1 | # This module contains helper methods for displaying and uploading files |
---|
2 | # for attributes created by +FileColumn+'s +file_column+ method. It will be |
---|
3 | # automatically included into ActionView::Base, thereby making this module's |
---|
4 | # methods available in all your views. |
---|
5 | module FileColumnHelper |
---|
6 | |
---|
7 | # Use this helper to create an upload field for a file_column attribute. This will generate |
---|
8 | # an additional hidden field to keep uploaded files during form-redisplays. For example, |
---|
9 | # when called with |
---|
10 | # |
---|
11 | # <%= file_column_field("entry", "image") %> |
---|
12 | # |
---|
13 | # the following HTML will be generated (assuming the form is redisplayed and something has |
---|
14 | # already been uploaded): |
---|
15 | # |
---|
16 | # <input type="hidden" name="entry[image_temp]" value="..." /> |
---|
17 | # <input type="file" name="entry[image]" /> |
---|
18 | # |
---|
19 | # You can use the +option+ argument to pass additional options to the file-field tag. |
---|
20 | # |
---|
21 | # Be sure to set the enclosing form's encoding to 'multipart/form-data', by |
---|
22 | # using something like this: |
---|
23 | # |
---|
24 | # <%= form_tag {:action => "create", ...}, :multipart => true %> |
---|
25 | def file_column_field(object, method, options={}) |
---|
26 | result = ActionView::Helpers::InstanceTag.new(object.dup, method.to_s+"_temp", self).to_input_field_tag("hidden", {}) |
---|
27 | result << ActionView::Helpers::InstanceTag.new(object.dup, method, self).to_input_field_tag("file", options) |
---|
28 | end |
---|
29 | |
---|
30 | # Creates an URL where an uploaded file can be accessed. When called for an Entry object with |
---|
31 | # id 42 (stored in <tt>@entry</tt>) like this |
---|
32 | # |
---|
33 | # <%= url_for_file_column(@entry, "image") |
---|
34 | # |
---|
35 | # the following URL will be produced, assuming the file "test.png" has been stored in |
---|
36 | # the "image"-column of an Entry object stored in <tt>@entry</tt>: |
---|
37 | # |
---|
38 | # /entry/image/42/test.png |
---|
39 | # |
---|
40 | # This will produce a valid URL even for temporary uploaded files, e.g. files where the object |
---|
41 | # they are belonging to has not been saved in the database yet. |
---|
42 | # |
---|
43 | # The URL produces, although starting with a slash, will be relative |
---|
44 | # to your app's root. If you pass it to one rails' +image_tag+ |
---|
45 | # helper, rails will properly convert it to an absolute |
---|
46 | # URL. However, this will not be the case, if you create a link with |
---|
47 | # the +link_to+ helper. In this case, you can pass <tt>:absolute => |
---|
48 | # true</tt> to +options+, which will make sure, the generated URL is |
---|
49 | # absolute on your server. Examples: |
---|
50 | # |
---|
51 | # <%= image_tag url_for_file_column(@entry, "image") %> |
---|
52 | # <%= link_to "Download", url_for_file_column(@entry, "image", :absolute => true) %> |
---|
53 | # |
---|
54 | # If there is currently no uploaded file stored in the object's column this method will |
---|
55 | # return +nil+. |
---|
56 | def url_for_file_column(object, method, options=nil) |
---|
57 | case object |
---|
58 | when String, Symbol |
---|
59 | object = instance_variable_get("@#{object.to_s}") |
---|
60 | end |
---|
61 | |
---|
62 | # parse options |
---|
63 | subdir = nil |
---|
64 | absolute = false |
---|
65 | if options |
---|
66 | case options |
---|
67 | when Hash |
---|
68 | subdir = options[:subdir] |
---|
69 | absolute = options[:absolute] |
---|
70 | when String, Symbol |
---|
71 | subdir = options |
---|
72 | end |
---|
73 | end |
---|
74 | |
---|
75 | relative_path = object.send("#{method}_relative_path", subdir) |
---|
76 | return nil unless relative_path |
---|
77 | |
---|
78 | url = "" |
---|
79 | url << request.relative_url_root.to_s if absolute |
---|
80 | url << "/" |
---|
81 | url << object.send("#{method}_options")[:base_url] << "/" |
---|
82 | url << relative_path |
---|
83 | end |
---|
84 | |
---|
85 | # Same as +url_for_file_colum+ but allows you to access different versions |
---|
86 | # of the image that have been processed by RMagick. |
---|
87 | # |
---|
88 | # If your +options+ parameter is non-nil this will |
---|
89 | # access a different version of an image that will be produced by |
---|
90 | # RMagick. You can use the following types for +options+: |
---|
91 | # |
---|
92 | # * a <tt>:symbol</tt> will select a version defined in the model |
---|
93 | # via FileColumn::Magick's <tt>:versions</tt> feature. |
---|
94 | # * a <tt>geometry_string</tt> will dynamically create an |
---|
95 | # image resized as specified by <tt>geometry_string</tt>. The image will |
---|
96 | # be stored so that it does not have to be recomputed the next time the |
---|
97 | # same version string is used. |
---|
98 | # * <tt>some_hash</tt> will dynamically create an image |
---|
99 | # that is created according to the options in <tt>some_hash</tt>. This |
---|
100 | # accepts exactly the same options as Magick's version feature. |
---|
101 | # |
---|
102 | # The version produced by RMagick will be stored in a special sub-directory. |
---|
103 | # The directory's name will be derived from the options you specified |
---|
104 | # (via a hash function) but if you want |
---|
105 | # to set it yourself, you can use the <tt>:name => name</tt> option. |
---|
106 | # |
---|
107 | # Examples: |
---|
108 | # |
---|
109 | # <%= url_for_image_column @entry, "image", "640x480" %> |
---|
110 | # |
---|
111 | # will produce an URL like this |
---|
112 | # |
---|
113 | # /entry/image/42/bdn19n/filename.jpg |
---|
114 | # # "640x480".hash.abs.to_s(36) == "bdn19n" |
---|
115 | # |
---|
116 | # and |
---|
117 | # |
---|
118 | # <%= url_for_image_column @entry, "image", |
---|
119 | # :size => "50x50", :crop => "1:1", :name => "thumb" %> |
---|
120 | # |
---|
121 | # will produce something like this: |
---|
122 | # |
---|
123 | # /entry/image/42/thumb/filename.jpg |
---|
124 | # |
---|
125 | # Hint: If you are using the same geometry string / options hash multiple times, you should |
---|
126 | # define it in a helper to stay with DRY. Another option is to define it in the model via |
---|
127 | # FileColumn::Magick's <tt>:versions</tt> feature and then refer to it via a symbol. |
---|
128 | # |
---|
129 | # The URL produced by this method is relative to your application's root URL, |
---|
130 | # although it will start with a slash. |
---|
131 | # If you pass this URL to rails' +image_tag+ helper, it will be converted to an |
---|
132 | # absolute URL automatically. |
---|
133 | # If there is currently no image uploaded, or there is a problem while loading |
---|
134 | # the image this method will return +nil+. |
---|
135 | def url_for_image_column(object, method, options=nil) |
---|
136 | case object |
---|
137 | when String, Symbol |
---|
138 | object = instance_variable_get("@#{object.to_s}") |
---|
139 | end |
---|
140 | subdir = nil |
---|
141 | if options |
---|
142 | subdir = object.send("#{method}_state").create_magick_version_if_needed(options) |
---|
143 | end |
---|
144 | if subdir.nil? |
---|
145 | nil |
---|
146 | else |
---|
147 | url_for_file_column(object, method, subdir) |
---|
148 | end |
---|
149 | end |
---|
150 | end |
---|