# This module contains helper methods for displaying and uploading files # for attributes created by +FileColumn+'s +file_column+ method. It will be # automatically included into ActionView::Base, thereby making this module's # methods available in all your views. module FileColumnHelper # Use this helper to create an upload field for a file_column attribute. This will generate # an additional hidden field to keep uploaded files during form-redisplays. For example, # when called with # # <%= file_column_field("entry", "image") %> # # the following HTML will be generated (assuming the form is redisplayed and something has # already been uploaded): # # # # # You can use the +option+ argument to pass additional options to the file-field tag. # # Be sure to set the enclosing form's encoding to 'multipart/form-data', by # using something like this: # # <%= form_tag {:action => "create", ...}, :multipart => true %> def file_column_field(object, method, options={}) result = ActionView::Helpers::InstanceTag.new(object.dup, method.to_s+"_temp", self).to_input_field_tag("hidden", {}) result << ActionView::Helpers::InstanceTag.new(object.dup, method, self).to_input_field_tag("file", options) end # Creates an URL where an uploaded file can be accessed. When called for an Entry object with # id 42 (stored in @entry) like this # # <%= url_for_file_column(@entry, "image") # # the following URL will be produced, assuming the file "test.png" has been stored in # the "image"-column of an Entry object stored in @entry: # # /entry/image/42/test.png # # This will produce a valid URL even for temporary uploaded files, e.g. files where the object # they are belonging to has not been saved in the database yet. # # The URL produces, although starting with a slash, will be relative # to your app's root. If you pass it to one rails' +image_tag+ # helper, rails will properly convert it to an absolute # URL. However, this will not be the case, if you create a link with # the +link_to+ helper. In this case, you can pass :absolute => # true to +options+, which will make sure, the generated URL is # absolute on your server. Examples: # # <%= image_tag url_for_file_column(@entry, "image") %> # <%= link_to "Download", url_for_file_column(@entry, "image", :absolute => true) %> # # If there is currently no uploaded file stored in the object's column this method will # return +nil+. def url_for_file_column(object, method, options=nil) case object when String, Symbol object = instance_variable_get("@#{object.to_s}") end # parse options subdir = nil absolute = false if options case options when Hash subdir = options[:subdir] absolute = options[:absolute] when String, Symbol subdir = options end end relative_path = object.send("#{method}_relative_path", subdir) return nil unless relative_path url = "" url << ActionController::Base.relative_url_root.to_s if absolute url << "/" url << object.send("#{method}_options")[:base_url] << "/" url << relative_path end # Same as +url_for_file_colum+ but allows you to access different versions # of the image that have been processed by RMagick. # # If your +options+ parameter is non-nil this will # access a different version of an image that will be produced by # RMagick. You can use the following types for +options+: # # * a :symbol will select a version defined in the model # via FileColumn::Magick's :versions feature. # * a geometry_string will dynamically create an # image resized as specified by geometry_string. The image will # be stored so that it does not have to be recomputed the next time the # same version string is used. # * some_hash will dynamically create an image # that is created according to the options in some_hash. This # accepts exactly the same options as Magick's version feature. # # The version produced by RMagick will be stored in a special sub-directory. # The directory's name will be derived from the options you specified # (via a hash function) but if you want # to set it yourself, you can use the :name => name option. # # Examples: # # <%= url_for_image_column @entry, "image", "640x480" %> # # will produce an URL like this # # /entry/image/42/bdn19n/filename.jpg # # "640x480".hash.abs.to_s(36) == "bdn19n" # # and # # <%= url_for_image_column @entry, "image", # :size => "50x50", :crop => "1:1", :name => "thumb" %> # # will produce something like this: # # /entry/image/42/thumb/filename.jpg # # Hint: If you are using the same geometry string / options hash multiple times, you should # define it in a helper to stay with DRY. Another option is to define it in the model via # FileColumn::Magick's :versions feature and then refer to it via a symbol. # # The URL produced by this method is relative to your application's root URL, # although it will start with a slash. # If you pass this URL to rails' +image_tag+ helper, it will be converted to an # absolute URL automatically. # If there is currently no image uploaded, or there is a problem while loading # the image this method will return +nil+. def url_for_image_column(object, method, options=nil) case object when String, Symbol object = instance_variable_get("@#{object.to_s}") end subdir = nil if options subdir = object.send("#{method}_state").create_magick_version_if_needed(options) end if subdir.nil? nil else url_for_file_column(object, method, subdir) end end end