Permalink
Browse files

Version 0.4 (exported from SVN)

  • Loading branch information...
1 parent d4351ff commit 6d2491fdf8906d4d83fcb49a87b07c959da3463f @chrisparrish chrisparrish committed Oct 18, 2008
View
@@ -1,3 +1,6 @@
+v0.4 File Uploading! You can now upload Javascripts or Stylesheets from the
+ corresponding index pages.
+
v0.3.1 Moved Templates to Haml -- now requires Radiant 0.6.7 (or 0.6.6 and
install Haml yourself -- untested).
@@ -46,6 +49,7 @@ v0.3 Big new features plus code refactoring and a bug fix. First, the new
v0.2.2 Bugfix - I added the UserActionObserver behavior and accompanying specs
to the Stylesheet and Javascript models
+
v0.2.1 Bugfix - I corrected the ActionController::InvalidAuthenticityToken that
comes from my not using the form helpers in my templates. I also weakly
spec-ed it.
View
@@ -19,36 +19,38 @@ In this README you'll find:
USAGE
=====
Using this extension is rather painless. If you can use the rest of Radiant,
-these additions will seem obvious. There are a couple of things to take note
-of, however.
+using these additions should feel obvious. There are a couple of things to take
+note of, however.
* The CSS and JS tabs are where you create, edit, and delete stylesheets and
javascripts. But you need Administrator or Developer permissions to see
these tabs.
-
+
* If you want to reference or otherwise use your script or stylesheet in one
of your pages, there are <r:stylesheet> and <r:javascript> tags. These tags
can be used to inject your CSS or JS code into the page or just render a
- link to the file itself. (See the 'available tags' link on the Page edit
- form to learn more about options for these tags).
-
- * If you want to cut down on server requests for CSS and JS files, you can
- also create a master CSS or JS file for each and use the appropriate
- <r:stylesheet> or <r:javascript> tags to incorporate other files of the same
- type. Viola, now Radiant offers asset packaging just like Rails!
+ link to the file itself. (Click the 'available tags' link when editing your
+ Page to learn more about these two tags and their options).
+ * If you really want to get fancy with your CSS and JS files, you can also use
+ the corresponding <r:stylesheet> or <r:javascript> to reference other files
+ of the same type. So now you can create a single CSS or JS file that is
+ made up of sub-files to cut down on server requests and speed up page load
+ time -- viola, now Radiant offers asset packaging just like Rails! (And the
+ caching mechanism is smart enough to keep track of your file's dependencies)
+
That's it. Everything else is either too obvious to bother with here or
-automagical and too top secret to disclose.
+automagical and/or too top secret to disclose ;-).
WHY CHANGE THINGS?
==================
-As John sees it, the pages tab is for storing the main content. (Think of the
-tree view as the list of available destinations for your users). Sure, they need
-stylesheets and javascripts but those are supporting files (much like images).
-They augment your pages.
+As John sees it, the pages tab is for storing your main content. (Think of the
+tree view as the list of available destinations for your users. Sure, they need
+stylesheets and javascripts, but those are supporting files -- much like images
+-- that augment your pages).
There are a number of interesting benefits gained by this approach:
@@ -62,21 +64,18 @@ There are a number of interesting benefits gained by this approach:
* This properly separates the concerns of Pages and Text Assets. (I mean, do
javascripts really need a layout or stylesheets a breadcrumb?). Easier to
understand for the user and easier to develop for.
-
- * Allows extensions to deal better interact with pages. For example, a search
- extension can now safely parse all the pages without terms like "background"
- yielding all your stylesheets.
- * Declutter the pages tree view so that it truly only shows what your clients
- see -- the things they'd aim their browser at (see John's point above).
+ * Allows extensions to better interact with pages. For example, a search
+ extension can now safely parse all the pages without search terms like:
+ "background" returning all your stylesheets.
- * This opens the door for validation, minification and obfuscation of scripts
- and stylesheets (I'm thinking that these belong in a separate extension but
- they're *much* easier to build now that CSS and JS are a distinct type of
- object).
+ * Declutter the pages tree view so that it only shows what your clients care
+ about -- the things they'd aim their browser at (see John's point above).
- * This lays a conceptual foundation for other, non-text assets like images,
- flash, and the like.
+ * This opens the door for validation, minification and obfuscation of scripts
+ and stylesheets (I'm thinking that these features belong in their own
+ extension(s) but they're *much* easier to build now that CSS and JS distinct
+ objects).
@@ -108,14 +107,16 @@ INSTALLATION
TO-DO
=====
-Create a way for users to upload stylesheets and javascripts (maybe even upload
-many via a zipped file) and unpack them into the db.
+Figure out what the core team needs to get this puppy baked into Radiant!
-Improve caching. I'd like to see a scenario where files are cached-on-save.
-Rails page caching might be a great choice. (Maintaining the cache -- sweepers,
-etc. -- wouldn't be all that hard for these items.).
+Improve caching by just clearing JS files on JS file update (and CSS on
+CSS file update) instead of clearing all. It also might be nice to cache files
+at save time too. (But really, unless you have a *ton* of CSS or JS files, the
+current mechanism is pretty darn slick.
-Add file minification to strip out comments and whitespace (and maybe obfuscate)
-javascripts and stylesheets. (I already have this started).
+Add a mechanism to eliminate (or at least reduce) the possibility of circular
+references with <r:stylesheet> or <r:javascript> tags.s
-Figure out what the core team needs to get this puppy baked into Radiant!
+Improve the file uploading: Do we need to confirm that it's a text file? Do we
+need to mess with handling different text encoding? Do we want to allow
+multiple file uploads?
@@ -48,14 +48,39 @@ def remove
def upload
- @uploaded_file = params[:text_asset][:file]
- puts
- puts @uploaded_file.content_type
- puts @uploaded_file.original_filename
- puts
- puts @uploaded_file.methods.sort.join("\n")
- puts params[:text_asset][:file].string
- redirect_to send("#{ model_symbol }_new_url")
+ if !request.post? # not a POST request
+ render :template => "site/not_found", :status => :method_not_allowed
+
+ elsif params[:upload].nil? # necessary params are missing
+ render :text => '', :status => :bad_request
+
+ else
+ @text_asset = model_class.create_from_file(params[:upload][:file])
+
+ if @text_asset.new_record? # wasn't saved -- there must be errors
+ responds_to_parent do
+ render :update do |page|
+ # populate errors in the errors popup and call method to show
+ page.replace_html "errors_for_#{model_name}",
+ '<ul class="uploadErrors">' +
+ @text_asset.errors.collect{|k,v|
+ %{<li class="warning">#{k.humanize.titlecase}: #{v}</li>}
+ }.to_s +
+ '</ul>'
+ page.call('showErrorsPopup')
+ end
+ end
+
+ else # success!
+ responds_to_parent do
+ render :update do |page|
+ page.redirect_to(:action => 'index')
+ end
+ end
+
+ end
+
+ end
end
@@ -68,5 +93,4 @@ def set_model
self.class.model_class params[:asset_type].camelize.constantize
end
-
end
@@ -10,7 +10,7 @@ class TextAsset < ActiveRecord::Base
validates_presence_of :filename, :message => 'required'
validates_length_of :filename, :maximum => 100, :message => '%d-character limit'
- validates_uniqueness_of :filename, :scope => :class_name, :message => 'filename already in use'
+ validates_uniqueness_of :filename, :scope => :class_name, :message => "filename already in use"
# the following regexp uses \A and \Z rather than ^ and $ to enforce no "\n" characters
validates_format_of :filename, :with => %r{\A[-_.A-Za-z0-9]*\Z}, :message => 'invalid format'
@@ -20,7 +20,7 @@ class TagError < StandardError; end
def after_initialize
self.dependencies = TextAssetDependencies.new(:list => []) if new_record?
- create_tag #adds the tag to the inherited class now that it has initialized
+ create_tags #adds radius tags to the inherited class now that it has initialized
end
@@ -51,13 +51,34 @@ def parse(text, show_errors = true)
end
+ def self.create_from_file(file)
+ @text_asset = self.new
+ if file.blank?
+ @text_asset.errors.add(:uploaded_file, 'no file submitted for upload')
+
+ elsif !file.kind_of?(ActionController::UploadedFile)
+ @text_asset.errors.add(:uploaded_file, 'unusable format')
+
+ elsif file.size > 262144 # 256k (that's a HUGE script or stylesheet)
+ @text_asset.errors.add(:uploaded_file, 'file size larger than 256kB')
+
+ else
+ @text_asset.filename = file.original_filename.gsub(/\s/, '-')
+ @text_asset.content = file.read
+ # everthing else passed so run through the std validations (save if valid)
+ @text_asset.save
+ end
+ @text_asset
+ end
+
+
private
# Adds a tag named after the inheriting class name (so <r:javascript> or
# <r:stylesheet>. This method is kind of funky since we wanted to define
# the tag in only one place yet we don't have the inheriting class' name
# until after initialization.
- def create_tag
+ def create_tags
self.class.class_eval do
tag(self.name.underscore) do |tag|
if name = tag.attr['name']
@@ -1,3 +1,25 @@
+- content_for('page_scripts') do
+ :plain
+ function toggle_upload_popup() {
+ var popup = $('upload-popup');
+ center(popup);
+ Element.toggle(popup);
+ }
+ function uploadInProgress() {
+ $('upload_button').disabled = true;
+ //$('upload_file').disabled = true;
+ $('busy').appear();
+ }
+ function showErrorsPopup() {
+ var popup = $('upload-errors-popup');
+ center(popup);
+ popup.show();
+ $('upload-popup').hide();
+ $('busy').hide();
+ $('upload_button').disabled = false;
+ $('upload_file').disabled = false;
+ }
+
- if model_name == 'stylesheet'
%h1 Stylesheets
%p Cascading Stylesheets (CSS files) can be used to alter the look &amp; feel of your pages, layouts, and/or snippets.
@@ -26,4 +48,24 @@
%td.note{:colspan => 2}== No #{proper_model_name.pluralize}
%p
- = link_to(image("new-#{model_name}", :alt => "New #{proper_model_name}"), send("#{model_name}_new_url"))
+ = link_to(image("new-#{model_name}", :alt => "New #{proper_model_name}"), send("#{model_name}_new_url"))
+ &nbsp;&nbsp;
+ = link_to image("upload-#{model_name}", :alt => "Upload #{proper_model_name}"), "#", :onclick => "toggle_upload_popup(); return false;"
+
+- content_for 'popups' do
+ .popup#upload-popup{:style => 'display:none;width:20em'}
+ #busy.busy{:style => "display: none"}= image 'spinner.gif'
+ %h3== Upload #{proper_model_name}
+ - form_for :upload, :url => send("#{model_name}_upload_url"),:html => { :multipart => true, :target => 'upload_frame', :onsubmit => 'uploadInProgress();' } do |f|
+ %p
+ %label{:for => 'upload_file'}== Select a #{model_name} file:
+ %p= f.file_field :file
+ %p= submit_tag 'Upload', :id => 'upload_button'
+ %p= link_to_function 'Close', "Element.hide('upload-popup')", :class => 'close-link'
+ %iframe{:id => 'upload_frame', :name => "upload_frame", :style => "width:1px;height:1px;border:0px", :src => "about:blank"}
+ .popup#upload-errors-popup{:style => 'display:none'}
+ %h3== Upload Errors
+ %p The file upload experinced the following errors:
+ %div{:id => "errors_for_#{model_name}"}
+ %p= link_to_function 'Close', "Element.hide('upload-errors-popup')", :class => 'close-link'
+
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
@@ -1,3 +1,5 @@
+require File.dirname(__FILE__) + '/../../spec_helper'
+
# These specs set the behavior of TextAssetController (which behaves as both a
# StylesheetController and JavascriptController).
#
@@ -9,8 +11,6 @@
# confirmed. That way, if the core team sees fit to change the behavior of
# AbstractController, we'll know our extension just broke.
-require File.dirname(__FILE__) + '/../../spec_helper'
-
[ { :class => Stylesheet,
:name => 'stylesheet',
:symbol => :stylesheet },
@@ -21,7 +21,7 @@
].each do |current_asset|
- describe Admin::TextAssetController, "(rendering #{current_asset[:name].pluralize}" do
+ describe "For #{current_asset[:name].pluralize},", Admin::TextAssetController do
integrate_views
@@ -48,36 +48,41 @@
- [:index, :new, :edit, :remove].each do |action|
+ [:index, :new, :edit, :remove, :upload].each do |action|
- # moved this test into the actions as the controller inits this before action
+ # moved this test into the actions as the controller inits this before each action
it "should have a model_class of #{current_asset[:name]}" do
controller.class.model_class.should == current_asset[:class]
end
- it "should require login to access the #{action} action" do
- logout
- lambda { get action }.should require_login
- end
+ describe "#{action} action" do
+ it "should require login to access the #{action} action" do
+ logout
+ lambda { get action }.should require_login
+ end
- it "should allow access to developers" do
- lambda { get action, :id => text_asset_id('main'),
- :asset_type => current_asset[:name]
- }.should restrict_access(:allow => [users(:developer)])
- end
+ it "should allow access to developers" do
+ lambda { get action, :id => text_asset_id('main'),
+ :asset_type => current_asset[:name] }.should
+ restrict_access(:allow => [users(:developer)])
+ end
+
+
+ it "should allow access to admins" do
+ lambda { get action, :id => text_asset_id('main'),
+ :asset_type => current_asset[:name]}.should
+ restrict_access(:allow => [users(:admin)])
+ end
- it "should allow access to admins" do
- lambda { get action, :id => text_asset_id('main'),
- :asset_type => current_asset[:name]
- }.should restrict_access(:allow => [users(:admin)])
- end
+ it "should deny non-developers and non-admins" do
+ lambda { get action,:asset_type => current_asset[:name] }.should
+ restrict_access(:deny => [users(:non_admin), users(:existing)])
+ end
- it "should deny non-developers and non-admins" do
- lambda { get action }.should restrict_access(:deny => [users(:non_admin), users(:existing)])
end
end
@@ -430,4 +435,4 @@
end
-end
+end
Oops, something went wrong. Retry.

0 comments on commit 6d2491f

Please sign in to comment.