[Radiant] Checking for an asset existence

Sean Cribbs seancribbs at gmail.com
Sat Dec 16 16:00:08 CST 2006


Brian Sam-Bodden wrote:
>     # <r:slug_image [prefix=""] [suffix=""] [default=""] [other 
> attributes...] /
>     #
>     # Renders a img tag to the page where part of the image name is 
> based on the
>     # slug for the current page. It allows you to add a prefix and a 
> suffix to
>     # build the name of the file. If the file exist (in the public 
> directory) it
>     # then renders the img tag for the file. If the file does not exist 
> it renders
>     # a img tag for a default image using the same prefix and suffix and 
> using the
>     # value of the default attribute. If not default attribute is 
> provided it uses
>     # the value 'default'. The slug_image tag passes all attributes over 
> to the HTML
>     # 'img' tag. This is very useful for passing attributes like the 
> 'class' attribute
>     # or 'id' attribute.
>     #
>     # For example in the page with slug 'home'
>     #   <r:slug_image prefix="images/highlights/" 
> suffix="-highlight.jpg" border="0" />
>     # will render
>     #   <img src="image/highlights/home-highlight.jpg" border="0" />
>     # if the image exists, if not it will render
>     #   <img src="image/highlights/default-highlight.jpg" border="0" />
>     define_tag 'slug_image' do |tag|
>       options = tag.attr.dup
>       prefix = tag.attr['prefix'] ? "#{options.delete('prefix')}" : ''
>       suffix = tag.attr['suffix'] ? "#{options.delete('suffix')}" : ''
>       default = tag.attr['default'] ? "#{options.delete('default')}" : 
> 'default'
>       attributes = options.inject('') { |s, (k, v)| s << 
> %{#{k.downcase}="#{v}" } }.strip
>       attributes = " #{attributes}" unless attributes.empty?
>       slugFile = prefix + tag.locals.page.slug + suffix
>       defaultFile = prefix + default + suffix
>       slugUrl = File.expand_path(File.join(RAILS_ROOT, "public", 
> slugFile))
>       defaultUrl = File.expand_path(File.join(RAILS_ROOT, "public", 
> defaultFile))
>       url = ""
>       if File.exists?(slugUrl)
>         url = slugFile
>       else #todo: should check that the default file exists
>         url = defaultFile
>       end
>
>       %{<img src="#{url}"#{attributes} />}
>     end
>
> Thanks,
>   Brian
>
>   

 It seems you studied some of the built-in tags too, for tricks. Here's 
are a few ways you can clarify the code:

tag 'slug_image' do |tag|
  options = tag.attr.dup
  # Well-known Ruby trick for conditional
  # assignment - nil evaluates the same as false
  prefix = options.delete('prefix') || ''
  suffix = options.delete('suffix') || ''
  default = options.delete('default') || ''
  attributes = options.inject([]) { |s, (k, v)| 
     s << %{#{k.downcase}="#{v}" } }.join(" ").strip
  attributes = " #{attributes}" unless attributes.empty?
  slugFile = prefix + tag.locals.page.slug + suffix
  defaultFile = prefix + default + suffix
  slugPath = File.expand_path(File.join(RAILS_ROOT, "public", slugFile))
  defaultPath = File.expand_path(File.join(RAILS_ROOT, "public", defaultFile))
  url = case
    when File.exists?(slugPath)
      slugFile
    when File.exists?(defaultPath)
      defaultFile
    else
      nil
   end
  %{<img src="#{url}"#{attributes} />} if url
end


I also completed your to-do.  There might be some other tricks you could 
employ, parallel assignment with an inject, but why bother?  Although 
it's fairly long, the tag definition is really clear - the key is to be 
pragmatic.  There is a point at which trying to be DRY becomes 
impractical and unclear and unnatural.

Cheers,

Sean



More information about the Radiant mailing list