module AssetTags include TrustyCms::Taggable include ActionView::Helpers::TagHelper include ActionView::Helpers::AssetTagHelper class TagError < StandardError; end %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| deprecated_tag "assets:#{name}", :substitute => "asset:#{name}", :deadline => '2.0' end desc %{ The namespace for referencing images and assets. *Usage:*
...
} tag 'asset' do |tag| tag.locals.asset = find_asset(tag, tag.attr) unless tag.attr.empty? tag.expand end desc %{ Cycles through all assets attached to the current page. This tag does not require the name atttribute, nor do any of its children. Use the @limit@ and @offset@ attribute to render a specific number of assets. Use @by@ and @order@ attributes to control the order of assets. Use @extensions@ attribute to specify which assets to be rendered. *Usage:*
...
} tag 'assets' do |tag| tag.expand end tag 'assets:each' do |tag| options = tag.attr.dup tag.locals.assets = tag.locals.page.assets.scoped(assets_find_options(tag)) tag.render('asset_list', tag.attr.dup, &tag.block) end # General purpose paginated asset lister. Very useful dryness. # Tag.locals.assets must be defined but can be empty. tag 'asset_list' do |tag| raise TagError, "r:asset_list: no assets to list" unless tag.locals.assets options = tag.attr.symbolize_keys result = "" paging = pagination_find_options(tag) assets = paging ? tag.locals.assets.paginate(paging) : tag.locals.assets.all assets.each do |asset| tag.locals.asset = asset result << tag.expand end if paging && assets.total_pages > 1 tag.locals.paginated_list = assets result << tag.render('pagination', tag.attr.dup) end result end desc %{ References the first asset attached to the current page. *Usage:*
...
} tag 'assets:first' do |tag| if tag.locals.asset = tag.locals.page.assets.first tag.expand end end desc %{ Renders the contained elements only if the current contextual page has one or more assets. The @min_count@ attribute specifies the minimum number of required assets. You can also filter by extensions with the @extensions@ attribute. *Usage:*
...
} tag 'if_assets' do |tag| count = tag.attr['min_count'] && tag.attr['min_count'].to_i || 1 assets = tag.locals.page.assets.count(:conditions => assets_find_options(tag)[:conditions]) tag.expand if assets >= count end desc %{ The opposite of @@. } tag 'unless_assets' do |tag| count = tag.attr['min_count'] && tag.attr['min_count'].to_i || 1 assets = tag.locals.page.assets.count(:conditions => assets_find_options(tag)[:conditions]) tag.expand unless assets >= count end # Resets the page Url and title within the asset tag [:title, :url].each do |method| tag "asset:page:#{method.to_s}" do |tag| tag.locals.page.send(method) end end desc %{ Renders the value for a top padding for a thumbnail. Put the thumbnail in a container with specified height and using this tag you can vertically align the image within its container. *Usage*:
*Working Example*:

      
  • <r:title />
} tag 'asset:top_padding' do |tag| asset, options = asset_and_options(tag) raise TagError, "'container' attribute required" unless options['container'] size = options['size'] ? options.delete('size') : 'icon' raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.style?(size) container = options.delete('container') ((container.to_i - asset.height(size).to_i)/2).to_s end ['height','width'].each do |dimension| desc %{ Renders the #{dimension} of the asset. } tag "asset:#{dimension}" do |tag| asset, options = asset_and_options(tag) unless asset.dimensions_known? raise TagError, "Can't determine #{dimension} for this Asset. It may not be a supported type." end size = options['size'] ? options.delete('size') : 'original' asset.send(dimension, size) end end desc %{ Returns a string representing the orientation of the asset, which must be imageable. (ie, it is an image or it has been processed to produce an image). Can be 'horizontal', 'vertical' or 'square'. } tag 'asset:orientation' do |tag| asset, options = asset_and_options(tag) size = options['size'] ? options.delete('size') : 'original' raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.style?(size) asset.orientation(size) end desc %{ Returns the aspect ratio of the asset, which must be an image. } tag 'asset:aspect' do |tag| asset, options = asset_and_options(tag) size = options['size'] ? options.delete('size') : 'original' raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.style?(size) asset.aspect(size) end desc %{ Renders the containing elements only if the asset's content type matches the regular expression given in the @matches@ attribute. If the @ignore_case@ attribute is set to false, the match is case sensitive. By default, @ignore_case@ is set to true. The @name@ or @id@ attribute is required on the parent tag unless this tag is used in @asset:each@. *Usage:*
...
} tag 'asset:if_content_type' do |tag| options = tag.attr.dup # XXX build_regexp_for comes from StandardTags regexp = build_regexp_for(tag,options) asset_content_type = tag.locals.asset.asset_content_type tag.expand unless asset_content_type.match(regexp).nil? end [:title, :caption, :asset_file_name, :extension, :asset_content_type, :asset_file_size, :id].each do |method| desc %{ Renders the @#{method.to_s}@ attribute of the asset } tag "asset:#{method.to_s}" do |tag| asset, options = asset_and_options(tag) asset.send(method) rescue nil end end tag 'asset:name' do |tag| tag.render('asset:title', tag.attr.dup) end tag 'asset:filename' do |tag| asset, options = asset_and_options(tag) asset.asset_file_name rescue nil end desc %{ Renders an image tag for the asset. Using the optional @size@ attribute, different sizes can be display. "thumbnail" and "icon" sizes are built in, but custom ones can be set by changing `assets.thumbnails.[type]` in the TrustyCms::Config settings. *Usage:*
} tag 'asset:image' do |tag| tag.locals.asset, options = image_asset_and_options(tag) return "Error: This image cannot be found" if tag.locals.asset == nil size = options.delete('size') || 'original' raise TagError, "asset #{tag.locals.asset.title} has no '#{size}' thumbnail" unless tag.locals.asset.style?(size) options['alt'] ||= tag.locals.asset.title url = tag.locals.asset.thumbnail(size) ActionController::Base.helpers.image_tag(url, options) end desc %{ Renders the url for the asset. If the asset is an image, the size attribute can be used to generate the url for that size. *Usage:*
} tag 'asset:url' do |tag| asset, options = asset_and_options(tag) size = options['size'] ? options.delete('size') : 'original' asset.thumbnail(size) rescue nil end desc %{ Renders a link to the asset. If the asset is an image, the size attribute can be used to generate a link to that size. *Usage:*
} tag 'asset:link' do |tag| asset, options = asset_and_options(tag) size = options['size'] ? options.delete('size') : 'original' text = options['text'] || asset.title anchor = options['anchor'] ? "##{options.delete('anchor')}" : '' attributes = options.inject('') { |s, (k, v)| s << %{#{k.downcase}="#{v}" } }.strip attributes = " #{attributes}" unless attributes.empty? text = tag.double? ? tag.expand : text url = asset.thumbnail(size) %{#{text}} rescue nil end private def asset_and_options(tag) options = tag.attr.dup [find_asset(tag, options), options] end def image_asset_and_options(tag) options = tag.attr.dup [find_image_asset(tag, options), options] end def find_asset(tag, options) tag.locals.asset ||= if title = (options.delete('name') || options.delete('title')) Asset.find_by_title(title) elsif id = options.delete('id') Asset.find_by_id(id) end tag.locals.asset || raise(TagError, "Asset not found.") end def find_image_asset(tag, options) tag.locals.asset ||= if title = (options.delete('name') || options.delete('title')) Asset.find_by_title(title) elsif id = options.delete('id') Asset.find_by_id(id) end tag.locals.asset || nil end def assets_find_options(tag) attr = tag.attr.symbolize_keys extensions = attr[:extensions] && attr[:extensions].split('|') || [] conditions = unless extensions.blank? # this is soon to be removed in favour of asset types [ extensions.map { |ext| "assets.asset_file_name LIKE ?"}.join(' OR '), *extensions.map { |ext| "%.#{ext}" } ] else nil end by = attr[:by] || 'page_attachments.position' order = attr[:order] || 'asc' options = { :order => "#{by} #{order}", :limit => attr[:limit] || nil, :offset => attr[:offset] || nil, :conditions => conditions } end end