radiant-clipped-extension-add-group 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (131) hide show
  1. data/LICENSE +22 -0
  2. data/README.md +184 -0
  3. data/Rakefile +109 -0
  4. data/app/controllers/admin/assets_controller.rb +66 -0
  5. data/app/controllers/admin/page_attachments_controller.rb +18 -0
  6. data/app/helpers/admin/assets_helper.rb +16 -0
  7. data/app/helpers/admin/page_attachments_helper.rb +2 -0
  8. data/app/models/asset.rb +237 -0
  9. data/app/models/asset_type.rb +241 -0
  10. data/app/models/old_page_attachment.rb +26 -0
  11. data/app/models/page_attachment.rb +20 -0
  12. data/app/views/admin/assets/_asset.html.haml +12 -0
  13. data/app/views/admin/assets/_asset_table.html.haml +33 -0
  14. data/app/views/admin/assets/_errors.html.haml +3 -0
  15. data/app/views/admin/assets/_form.html.haml +25 -0
  16. data/app/views/admin/assets/_page_assets.html.haml +12 -0
  17. data/app/views/admin/assets/_search.html.haml +17 -0
  18. data/app/views/admin/assets/_search_results.html.haml +17 -0
  19. data/app/views/admin/assets/edit.html.haml +41 -0
  20. data/app/views/admin/assets/index.html.haml +19 -0
  21. data/app/views/admin/assets/new.html.haml +24 -0
  22. data/app/views/admin/assets/refresh.html.haml +14 -0
  23. data/app/views/admin/assets/remove.html.haml +16 -0
  24. data/app/views/admin/configuration/_clipped_edit.html.haml +8 -0
  25. data/app/views/admin/configuration/_clipped_show.html.haml +12 -0
  26. data/app/views/admin/page_attachments/_attachment.html.haml +25 -0
  27. data/app/views/admin/page_parts/_page_part.html.haml +21 -0
  28. data/app/views/admin/pages/_asset_popups.html.haml +42 -0
  29. data/app/views/admin/pages/_assets.html.haml +11 -0
  30. data/app/views/admin/removed/_assets_bucket.html.haml +8 -0
  31. data/app/views/admin/removed/_assets_container.html.haml +58 -0
  32. data/app/views/admin/removed/_bucket.html.haml +11 -0
  33. data/app/views/admin/removed/_bucket_asset.html.haml +9 -0
  34. data/app/views/admin/removed/_show_bucket_link.html.haml +4 -0
  35. data/app/views/admin/removed/_upload_to_page.html.haml +12 -0
  36. data/app/views/admin/removed/bucket/_iframe.html.haml +1 -0
  37. data/artwork/icons.png +0 -0
  38. data/clipped_extension.rb +52 -0
  39. data/config/initializers/interpolation.rb +6 -0
  40. data/config/initializers/processors.rb +43 -0
  41. data/config/initializers/radiant_config.rb +65 -0
  42. data/config/locales/de.yml +109 -0
  43. data/config/locales/en.yml +110 -0
  44. data/config/locales/nl.yml +107 -0
  45. data/config/locales/ru.yml +110 -0
  46. data/config/routes.rb +8 -0
  47. data/cucumber.yml +1 -0
  48. data/db/migrate/001_create_assets.rb +12 -0
  49. data/db/migrate/002_create_paperclip_attributes.rb +13 -0
  50. data/db/migrate/003_create_user_observer.rb +13 -0
  51. data/db/migrate/004_create_page_attachments.rb +19 -0
  52. data/db/migrate/005_rename_users.rb +13 -0
  53. data/db/migrate/20110513205050_asset_uuid.rb +11 -0
  54. data/db/migrate/20110606111250_update_configuration.rb +34 -0
  55. data/db/migrate/20110609101438_dimensions.rb +13 -0
  56. data/db/migrate/20121024064452_add_group_to_assets.rb +9 -0
  57. data/features/support/env.rb +11 -0
  58. data/features/support/paths.rb +22 -0
  59. data/lib/asset_tags.rb +350 -0
  60. data/lib/clipped_admin_ui.rb +32 -0
  61. data/lib/cloud.rb +41 -0
  62. data/lib/generators/templates/clipped_config.rb +53 -0
  63. data/lib/page_asset_associations.rb +13 -0
  64. data/lib/paperclip/frame_grab.rb +73 -0
  65. data/lib/paperclip/geometry_transformation.rb +80 -0
  66. data/lib/radiant-clipped-extension.rb +8 -0
  67. data/lib/tasks/clipped_extension_tasks.rake +124 -0
  68. data/lib/tasks/paperclip_tasks.rake +79 -0
  69. data/public/flash/ZeroClipboard.swf +0 -0
  70. data/public/images/admin/assets/add.png +0 -0
  71. data/public/images/admin/assets/archive_icon.png +0 -0
  72. data/public/images/admin/assets/audio_icon.png +0 -0
  73. data/public/images/admin/assets/audio_thumbnail.png +0 -0
  74. data/public/images/admin/assets/c_icon.png +0 -0
  75. data/public/images/admin/assets/copy.png +0 -0
  76. data/public/images/admin/assets/css_icon.png +0 -0
  77. data/public/images/admin/assets/database_icon.png +0 -0
  78. data/public/images/admin/assets/delete.png +0 -0
  79. data/public/images/admin/assets/document_icon.png +0 -0
  80. data/public/images/admin/assets/document_thumbnail.png +0 -0
  81. data/public/images/admin/assets/flash_icon.png +0 -0
  82. data/public/images/admin/assets/flash_thumbnail.png +0 -0
  83. data/public/images/admin/assets/font_icon.png +0 -0
  84. data/public/images/admin/assets/gzip_icon.png +0 -0
  85. data/public/images/admin/assets/html_icon.png +0 -0
  86. data/public/images/admin/assets/image_icon.png +0 -0
  87. data/public/images/admin/assets/image_thumbnail.png +0 -0
  88. data/public/images/admin/assets/java_icon.png +0 -0
  89. data/public/images/admin/assets/page_edit.png +0 -0
  90. data/public/images/admin/assets/perl_icon.png +0 -0
  91. data/public/images/admin/assets/php_icon.png +0 -0
  92. data/public/images/admin/assets/presentation_icon.png +0 -0
  93. data/public/images/admin/assets/python_icon.png +0 -0
  94. data/public/images/admin/assets/reorder_assets.png +0 -0
  95. data/public/images/admin/assets/ruby_icon.png +0 -0
  96. data/public/images/admin/assets/script_icon.png +0 -0
  97. data/public/images/admin/assets/spreadsheet_icon.png +0 -0
  98. data/public/images/admin/assets/tar_icon.png +0 -0
  99. data/public/images/admin/assets/unknown_icon.png +0 -0
  100. data/public/images/admin/assets/unknown_thumbnail.png +0 -0
  101. data/public/images/admin/assets/video_icon.png +0 -0
  102. data/public/images/admin/assets/video_thumbnail.png +0 -0
  103. data/public/images/admin/assets/xml_icon.png +0 -0
  104. data/public/images/admin/assets/zip_icon.png +0 -0
  105. data/public/javascripts/admin/assets.js +297 -0
  106. data/public/stylesheets/sass/admin/assets.sass +224 -0
  107. data/radiant-clipped-extension.gemspec +29 -0
  108. data/spec/ci/before_script +23 -0
  109. data/spec/ci/script +2 -0
  110. data/spec/controllers/admin/assets_controller_spec.rb +50 -0
  111. data/spec/controllers/admin/page_attachments_controller_spec.rb +50 -0
  112. data/spec/datasets/assets_dataset.rb +36 -0
  113. data/spec/fixtures/5k.png +0 -0
  114. data/spec/fixtures/test.flv +0 -0
  115. data/spec/lib/asset_tags_spec.rb +107 -0
  116. data/spec/lib/frame_grab_spec.rb +17 -0
  117. data/spec/lib/geometry_transformation_spec.rb +63 -0
  118. data/spec/models/asset_spec.rb +72 -0
  119. data/spec/models/asset_type_spec.rb +70 -0
  120. data/spec/models/post_processing_spec.rb +62 -0
  121. data/spec/spec.opts +7 -0
  122. data/spec/spec_helper.rb +36 -0
  123. data/wireframes/edit-page-assets-2.bmml +453 -0
  124. data/wireframes/edit-page-assets-2.png +0 -0
  125. data/wireframes/edit-page-assets-3.bmml +454 -0
  126. data/wireframes/edit-page-assets-3.png +0 -0
  127. data/wireframes/edit-page-assets.bmml +433 -0
  128. data/wireframes/edit-page-assets.png +0 -0
  129. data/wireframes/edit-page.bmml +174 -0
  130. data/wireframes/edit-page.png +0 -0
  131. metadata +281 -0
data/cucumber.yml ADDED
@@ -0,0 +1 @@
1
+ default: --format progress features --tags ~@proposed,~@in_progress
@@ -0,0 +1,12 @@
1
+ class CreateAssets < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :assets do |t|
4
+ t.string :caption, :title
5
+ end
6
+
7
+ end
8
+
9
+ def self.down
10
+ drop_table :assets
11
+ end
12
+ end
@@ -0,0 +1,13 @@
1
+ class CreatePaperclipAttributes < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :assets, :asset_file_name, :string
4
+ add_column :assets, :asset_content_type, :string
5
+ add_column :assets, :asset_file_size, :integer
6
+ end
7
+
8
+ def self.down
9
+ remove_column :assets, :asset_file_name
10
+ remove_column :assets, :asset_content_type
11
+ remove_column :assets, :asset_file_size
12
+ end
13
+ end
@@ -0,0 +1,13 @@
1
+ class CreateUserObserver < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :assets, :created_by, :integer
4
+ add_column :assets, :updated_by, :integer
5
+ add_column :assets, :created_at, :datetime
6
+ add_column :assets, :updated_at, :datetime
7
+ end
8
+
9
+ def self.down
10
+ remove_column :assets, :created_by
11
+ remove_column :assets, :updated_by
12
+ end
13
+ end
@@ -0,0 +1,19 @@
1
+ class CreatePageAttachments < ActiveRecord::Migration
2
+ def self.up
3
+ # See if a page_attachments table from the original 'page_attachments' extension already exists
4
+ # If so, rename the table to old_page_attachments so they can be migrated later
5
+ if self.connection.tables.include?('page_attachments')
6
+ rename_table :page_attachments, :old_page_attachments
7
+ end
8
+ create_table :page_attachments do |t|
9
+ t.column :asset_id, :integer
10
+ t.column :page_id, :integer
11
+ t.column :position, :integer
12
+ end
13
+
14
+ end
15
+
16
+ def self.down
17
+ drop_table :page_attachments
18
+ end
19
+ end
@@ -0,0 +1,13 @@
1
+ class RenameUsers < ActiveRecord::Migration
2
+
3
+ def self.up
4
+ rename_column :assets, :created_by, :created_by_id
5
+ rename_column :assets, :updated_by, :updated_by_id
6
+ end
7
+
8
+ def self.down
9
+ rename_column :assets, :created_by_id, :created_by
10
+ rename_column :assets, :updated_by_id, :updated_by
11
+ end
12
+
13
+ end
@@ -0,0 +1,11 @@
1
+ class AssetUuid < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :assets, :uuid, :string
4
+ Asset.reset_column_information
5
+ Asset.all.each { |a| a.save! } # triggers assign_uuid
6
+ end
7
+
8
+ def self.down
9
+ remove_column :assets, :uuid
10
+ end
11
+ end
@@ -0,0 +1,34 @@
1
+ class UpdateConfiguration < ActiveRecord::Migration
2
+ def self.up
3
+ if Radiant.config.table_exists?
4
+
5
+ puts "Importing paperclip configuration"
6
+ %w{url path skip_filetype_validation storage}.select{|k| !!Radiant.config["assets.#{k}"] }.each do |k|
7
+ begin
8
+ Radiant.config["paperclip.#{k}"] = Radiant.config["assets.#{k}"]
9
+ rescue ActiveRecord::RecordInvalid => e
10
+ print "Oops! There was trouble setting #{k} to '#{Radiant.config["assets.#{k}"]}'"
11
+ print "\nSetting it to 'fog'. Please see the clipped extension README for more details."
12
+ Radiant.config["paperclip.#{k}"] = 'fog'
13
+ end
14
+ end
15
+
16
+ puts "Importing s3 storage configuration"
17
+ %w{bucket key secret host_alias}.select{|k| !!Radiant.config["assets.s3.#{k}"] }.each do |k|
18
+ Radiant.config["paperclip.s3.#{k}"] = Radiant.config["assets.s3.#{k}"]
19
+ end
20
+
21
+ puts "Importing thumbnail configuration"
22
+ if thumbnails = Radiant.config["assets.additional_thumbnails"]
23
+ old_styles = thumbnails.to_s.gsub(' ','').split(',').collect{|s| s.split('=')}.inject({}) {|ha, (k, v)| ha[k.to_sym] = v; ha}
24
+ new_styles = old_styles.map {|k,v| "#{k}:size=#{v}"}
25
+ Radiant.config["assets.thumbnails.image"] = new_styles.join("|")
26
+ Radiant.config["assets.thumbnails.video"] = new_styles.map{|s| "#{s},format=jpg"}.join("|")
27
+ Radiant.config["assets.thumbnails.pdf"] = new_styles.map{|s| "#{s},format=jpg"}.join("|")
28
+ end
29
+ end
30
+ end
31
+
32
+ def self.down
33
+ end
34
+ end
@@ -0,0 +1,13 @@
1
+ class Dimensions < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :assets, :original_width, :integer
4
+ add_column :assets, :original_height, :integer
5
+ add_column :assets, :original_extension, :string
6
+ end
7
+
8
+ def self.down
9
+ remove_column :assets, :original_width
10
+ remove_column :assets, :original_height
11
+ remove_column :assets, :original_extension
12
+ end
13
+ end
@@ -0,0 +1,9 @@
1
+ class AddGroupToAssets < ActiveRecord::Migration
2
+ def self.up
3
+ add_column :assets, :group, :string
4
+ end
5
+
6
+ def self.down
7
+ remove_column :assets, :group
8
+ end
9
+ end
@@ -0,0 +1,11 @@
1
+ # Sets up the Rails environment for Cucumber
2
+ ENV["RAILS_ENV"] = "test"
3
+ # Extension root
4
+ extension_env = File.expand_path(File.dirname(__FILE__) + '/../../../../../config/environment')
5
+ require extension_env+'.rb'
6
+
7
+ Dir.glob(File.join(RADIANT_ROOT, "features", "**", "*.rb")).each {|step| require step unless step =~ /datasets_loader\.rb$/}
8
+
9
+ Cucumber::Rails::World.class_eval do
10
+ dataset :assets
11
+ end
@@ -0,0 +1,22 @@
1
+ module NavigationHelpers
2
+
3
+ # Extend the standard PathMatchers with your own paths
4
+ # to be used in your features.
5
+ #
6
+ # The keys and values here may be used in your standard web steps
7
+ # Using:
8
+ #
9
+ # When I go to the "assets" admin page
10
+ #
11
+ # would direct the request to the path you provide in the value:
12
+ #
13
+ # admin_assets_path
14
+ #
15
+ PathMatchers = {} unless defined?(PathMatchers)
16
+ PathMatchers.merge!({
17
+ # /assets/i => 'admin_assets_path'
18
+ })
19
+
20
+ end
21
+
22
+ World(NavigationHelpers)
data/lib/asset_tags.rb ADDED
@@ -0,0 +1,350 @@
1
+ module AssetTags
2
+ include Radiant::Taggable
3
+
4
+ class TagError < StandardError; end
5
+
6
+ %w{top_padding width height caption asset_file_name asset_content_type asset_file_size id filename image flash thumbnail url link extension if_content_type page:title page:url}.each do |name|
7
+ deprecated_tag "assets:#{name}", :substitute => "asset:#{name}", :deadline => '2.0'
8
+ end
9
+
10
+ desc %{
11
+ The namespace for referencing images and assets.
12
+
13
+ *Usage:*
14
+ <pre><code><r:asset [name="asset name"]>...</r:asset></code></pre>
15
+ }
16
+ tag 'asset' do |tag|
17
+ tag.locals.asset = find_asset unless tag.attr.empty?
18
+ begin
19
+ tag.expand
20
+ rescue Paperclip::StyleError => e
21
+ Rails.logger.warn "style processing error with asset ##{tag.locals.asset.id}: #{e}"
22
+ raise TagError, e
23
+ end
24
+ end
25
+
26
+ desc %{
27
+ Cycles through all assets attached to the current page.
28
+ This tag does not require the name atttribute, nor do any of its children.
29
+ Use the @limit@ and @offset@ attribute to render a specific number of assets.
30
+ Use @by@ and @order@ attributes to control the order of assets.
31
+ Use @extensions@ attribute to specify which assets to be rendered.
32
+
33
+ *Usage:*
34
+ <pre><code><r:assets:each [limit=0] [offset=0] [order="asc|desc"] [by="position|title|..."] [extensions="png|pdf|doc"]>...</r:assets:each></code></pre>
35
+ }
36
+ tag 'assets' do |tag|
37
+ tag.expand
38
+ end
39
+ tag 'assets:each' do |tag|
40
+ options = tag.attr.dup
41
+ tag.locals.assets = tag.locals.page.assets.scoped(assets_find_options(tag))
42
+ tag.render('asset_list', tag.attr.dup, &tag.block)
43
+ end
44
+
45
+ # General purpose paginated asset lister. Very useful dryness.
46
+ # Tag.locals.assets must be defined but can be empty.
47
+
48
+ tag 'asset_list' do |tag|
49
+ raise TagError, "r:asset_list: no assets to list" unless tag.locals.assets
50
+ options = tag.attr.symbolize_keys
51
+ result = ""
52
+ paging = pagination_find_options(tag)
53
+ assets = paging ? tag.locals.assets.paginate(paging) : tag.locals.assets.all
54
+ assets.each do |asset|
55
+ tag.locals.asset = asset
56
+ result << tag.expand
57
+ end
58
+ if paging && assets.total_pages > 1
59
+ tag.locals.paginated_list = assets
60
+ result << tag.render('pagination', tag.attr.dup)
61
+ end
62
+ result
63
+ end
64
+
65
+ desc %{
66
+ References the first asset attached to the current page.
67
+
68
+ *Usage:*
69
+ <pre><code><r:assets:first>...</r:assets:first></code></pre>
70
+ }
71
+ tag 'assets:first' do |tag|
72
+ if tag.locals.asset = tag.locals.page.assets.first
73
+ tag.expand
74
+ end
75
+ end
76
+
77
+ desc %{
78
+ Renders the contained elements only if the current contextual page has one or
79
+ more assets. The @min_count@ attribute specifies the minimum number of required
80
+ assets. You can also filter by extensions with the @extensions@ attribute.
81
+
82
+ *Usage:*
83
+ <pre><code><r:if_assets [min_count="n"]>...</r:if_assets></code></pre>
84
+ }
85
+ tag 'if_assets' do |tag|
86
+ count = tag.attr['min_count'] && tag.attr['min_count'].to_i || 1
87
+ assets = tag.locals.page.assets.count(:conditions => assets_find_options(tag)[:conditions])
88
+ tag.expand if assets >= count
89
+ end
90
+
91
+ desc %{
92
+ The opposite of @<r:if_assets/>@.
93
+ }
94
+ tag 'unless_assets' do |tag|
95
+ count = tag.attr['min_count'] && tag.attr['min_count'].to_i || 1
96
+ assets = tag.locals.page.assets.count(:conditions => assets_find_options(tag)[:conditions])
97
+ tag.expand unless assets >= count
98
+ end
99
+
100
+ # Resets the page Url and title within the asset tag
101
+ [:title, :url].each do |method|
102
+ tag "asset:page:#{method.to_s}" do |tag|
103
+ tag.locals.page.send(method)
104
+ end
105
+ end
106
+
107
+
108
+
109
+
110
+
111
+
112
+
113
+ desc %{
114
+ Renders the value for a top padding for a thumbnail. Put the thumbnail in a
115
+ container with specified height and using this tag you can vertically
116
+ align the image within its container.
117
+
118
+ *Usage*:
119
+ <pre><code><r:asset:top_padding container = "140" [size="icon"]/></code></pre>
120
+
121
+ *Working Example*:
122
+ <pre><code>
123
+ <ul>
124
+ <r:asset:each>
125
+ <li style="height:140px">
126
+ <img style="padding-top:<r:top_padding size='category' container='140' />px"
127
+ src="<r:url />" alt="<r:title />" />
128
+ </li>
129
+ </r:asset:each>
130
+ </ul>
131
+ </code></pre>
132
+ }
133
+ tag 'asset:top_padding' do |tag|
134
+ asset, options = asset_and_options(tag)
135
+ raise TagError, "'container' attribute required" unless options['container']
136
+ size = options['size'] ? options.delete('size') : 'icon'
137
+ raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.has_style?(size)
138
+ container = options.delete('container')
139
+ ((container.to_i - asset.height(size).to_i)/2).to_s
140
+ end
141
+
142
+ ['height','width'].each do |dimension|
143
+ desc %{
144
+ Renders the #{dimension} of the asset.
145
+ }
146
+ tag "asset:#{dimension}" do |tag|
147
+ asset, options = asset_and_options(tag)
148
+ unless asset.dimensions_known?
149
+ raise TagError, "Can't determine #{dimension} for this Asset. It may not be a supported type."
150
+ end
151
+ size = options['size'] ? options.delete('size') : 'original'
152
+ asset.send(dimension, size)
153
+ end
154
+ end
155
+
156
+ desc %{
157
+ Returns a string representing the orientation of the asset, which must be imageable.
158
+ (ie, it is an image or it has been processed to produce an image).
159
+ Can be 'horizontal', 'vertical' or 'square'.
160
+ }
161
+ tag 'asset:orientation' do |tag|
162
+ asset, options = asset_and_options(tag)
163
+ size = options['size'] ? options.delete('size') : 'original'
164
+ raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.has_style?(size)
165
+ asset.orientation(size)
166
+ end
167
+
168
+ desc %{
169
+ Returns the aspect ratio of the asset, which must be an image.
170
+ }
171
+ tag 'asset:aspect' do |tag|
172
+ asset, options = asset_and_options(tag)
173
+ size = options['size'] ? options.delete('size') : 'original'
174
+ raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.has_style?(size)
175
+ asset.aspect(size)
176
+ end
177
+
178
+ desc %{
179
+ Renders the containing elements only if the asset's content type matches
180
+ the regular expression given in the @matches@ attribute. If the
181
+ @ignore_case@ attribute is set to false, the match is case sensitive. By
182
+ default, @ignore_case@ is set to true.
183
+
184
+ The @name@ or @id@ attribute is required on the parent tag unless this tag is used in @asset:each@.
185
+
186
+ *Usage:*
187
+ <pre><code><r:asset:each><r:if_content_type matches="regexp" [ignore_case=true|false"]>...</r:if_content_type></r:asset:each></code></pre>
188
+ }
189
+ tag 'asset:if_content_type' do |tag|
190
+ options = tag.attr.dup
191
+ # XXX build_regexp_for comes from StandardTags
192
+ regexp = build_regexp_for(tag,options)
193
+ asset_content_type = tag.locals.asset.asset_content_type
194
+ tag.expand unless asset_content_type.match(regexp).nil?
195
+ end
196
+
197
+ #TODO: could use better docs for Asset#other? case explaining what types it covers
198
+
199
+ [:title, :caption, :asset_file_name, :extension, :asset_content_type, :asset_file_size, :id].each do |method|
200
+ desc %{
201
+ Renders the @#{method.to_s}@ attribute of the asset
202
+ }
203
+ tag "asset:#{method.to_s}" do |tag|
204
+ asset, options = asset_and_options(tag)
205
+ asset.send(method) rescue nil
206
+ end
207
+ end
208
+
209
+ tag 'asset:name' do |tag|
210
+ tag.render('asset:title', tag.attr.dup)
211
+ end
212
+
213
+ tag 'asset:filename' do |tag|
214
+ asset, options = asset_and_options(tag)
215
+ asset.asset_file_name rescue nil
216
+ end
217
+
218
+ desc %{
219
+ Renders an image tag for the asset.
220
+
221
+ Using the optional @size@ attribute, different sizes can be display.
222
+ "thumbnail" and "icon" sizes are built in, but custom ones can be set
223
+ by changing `assets.thumbnails.[type]` in the Radiant::Config settings.
224
+
225
+ *Usage:*
226
+ <pre><code><r:asset:image [name="asset name" or id="asset id"] [size="icon|thumbnail|whatever"]></code></pre>
227
+ }
228
+ tag 'asset:image' do |tag|
229
+ tag.locals.asset, options = asset_and_options(tag)
230
+ size = options.delete('size') || 'original'
231
+ raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.has_style?(size)
232
+ options['alt'] ||= tag.locals.asset.title
233
+ attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
234
+ url = tag.locals.asset.thumbnail(size)
235
+ %{<img src="#{url}" #{attributes} />} rescue nil
236
+ end
237
+
238
+ desc %{
239
+ Embeds a flash-movie in a cross-browser-compatible fashion using only HTML
240
+ If no width and height attributes are given it will use the intrinsic
241
+ dimensions of the swf file
242
+
243
+ *Usage:*
244
+ <pre><code><r:asset:flash [name="asset name" or id="asset id"] [width="100"] [height="100"]>Fallback content</flash></code></pre>
245
+
246
+ *Example with text fallback:*
247
+ <pre><code><r:asset:flash name="flash_movie">
248
+ Sorry, you need to have flash installed, <a href="http://adobe.com/flash">get it here</a>
249
+ </flash></code></pre>
250
+
251
+ *Example with image fallback and explicit dimensions:*
252
+ <pre><code><r:asset:flash name="flash_movie" width="300" height="200">
253
+ <r:asset:image name="flash_screenshot" />
254
+ </flash></code></pre>
255
+ }
256
+ tag 'asset:flash' do |tag|
257
+ asset, options = asset_and_options(tag)
258
+ if tag.locals.asset.flash?
259
+ url = asset.thumbnail('original')
260
+ dimensions = [(tag.attr['width'] || asset.width),(tag.attr['height'] || asset.height)]
261
+ swf_embed_markup url, dimensions, tag.expand
262
+ end
263
+ end
264
+
265
+ desc %{
266
+ Renders the url for the asset. If the asset is an image, the <code>size</code> attribute can be used to
267
+ generate the url for that size.
268
+
269
+ *Usage:*
270
+ <pre><code><r:url [name="asset name" or id="asset id"] [size="icon|thumbnail"]></code></pre>
271
+ }
272
+ tag 'asset:url' do |tag|
273
+ asset, options = asset_and_options(tag)
274
+ size = options['size'] ? options.delete('size') : 'original'
275
+ asset.thumbnail(size) rescue nil
276
+ end
277
+
278
+ desc %{
279
+ Renders a link to the asset. If the asset is an image, the <code>size</code> attribute can be used to
280
+ generate a link to that size.
281
+
282
+ *Usage:*
283
+ <pre><code><r:asset:link [name="asset name" or id="asset id"] [size="icon|thumbnail"] /></code></pre>
284
+ }
285
+ tag 'asset:link' do |tag|
286
+ asset, options = asset_and_options(tag)
287
+ size = options['size'] ? options.delete('size') : 'original'
288
+ text = options['text'] || asset.title
289
+ anchor = options['anchor'] ? "##{options.delete('anchor')}" : ''
290
+ attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip
291
+ attributes = " #{attributes}" unless attributes.empty?
292
+ text = tag.double? ? tag.expand : text
293
+ url = asset.thumbnail(size)
294
+ %{<a href="#{url }#{anchor}"#{attributes}>#{text}</a>} rescue nil
295
+ end
296
+
297
+ private
298
+ def asset_and_options(tag)
299
+ options = tag.attr.dup
300
+ [find_asset(tag, options), options]
301
+ end
302
+
303
+ def find_asset(tag, options)
304
+ tag.locals.asset ||= if title = (options.delete('name') || options.delete('title'))
305
+ Asset.find_by_title(title)
306
+ elsif id = options.delete('id')
307
+ Asset.find_by_id(id)
308
+ end
309
+ tag.locals.asset || raise(TagError, "Asset not found.")
310
+ end
311
+
312
+ def assets_find_options(tag)
313
+ attr = tag.attr.symbolize_keys
314
+ extensions = attr[:extensions] && attr[:extensions].split('|') || []
315
+ conditions = unless extensions.blank?
316
+ # this is soon to be removed in favour of asset types
317
+ [ extensions.map { |ext| "assets.asset_file_name LIKE ?"}.join(' OR '),
318
+ *extensions.map { |ext| "%.#{ext}" } ]
319
+ else
320
+ nil
321
+ end
322
+
323
+ by = attr[:by] || 'page_attachments.position'
324
+ order = attr[:order] || 'asc'
325
+
326
+ options = {
327
+ :order => "#{by} #{order}",
328
+ :limit => attr[:limit] || nil,
329
+ :offset => attr[:offset] || nil,
330
+ :conditions => conditions
331
+ }
332
+ end
333
+
334
+ def swf_embed_markup(url, dimensions, fallback_content)
335
+ width, height = dimensions
336
+ %{<!--[if !IE]> -->
337
+ <object type="application/x-shockwave-flash" data="#{url}" width="#{width}" height="#{height}">
338
+ <!-- <![endif]-->
339
+ <!--[if IE]>
340
+ <object width="#{width}" height="#{height}"
341
+ classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"
342
+ codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,0,0">
343
+ <param name="movie" value="#{url}" />
344
+ <!-->
345
+ #{fallback_content}
346
+ </object>
347
+ <!-- <![endif]-->}
348
+ end
349
+ end
350
+