ref: master
app/helpers/tags_helper.rb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 |
# encoding: UTF-8 module TagsHelper module Cloud MAX_SIZE = 32 MIN_SIZE = 12 end # <tt>tags</tt> must be a hash where the keys are tag names and the values # the count of elements tagged with the tag, as returned by # Profile#tagged_with. If not tags were returned, just returns # _('No tags yet.') # # <tagname_option> must be a symbol representing the key to be inserted in # <tt>url</tt> with the tag name as value, if <tt>url</tt> is a Hash. If # <tt>url_options</tt> is a String, then the tag name is just appended to it. # # Example: # # tag_cloud({ 'first-tag' => 10, 'second-tag' => 2, 'third-tag' => 1 }, :id, { :action => 'show_tag' }) # # <tt>options</tt> can include one or more of the following: # # * <tt>:max_size</tt>: font size for the tag with largest count # * <tt>:min_size</tt>: font size for the tag with smallest count # * <tt>:show_count</tt>: whether to show the count of contents for each tag. Defauls to <tt>false</tt>. # # The algorithm for generating the different sizes and positions is a # courtesy of Aurelio: http://www.colivre.coop.br/Aurium/Nuvem # (pt_BR only). def tag_cloud(tags, tagname_option, url, options = {}) return content_tag('em', _('No tags yet.') + ' ') + link_to(content_tag(:span, _('What are tags?')),_('http://en.wikipedia.org/wiki/Tag_%28metadata%29')) if tags.empty? max_size = options[:max_size] || Cloud::MAX_SIZE min_size = options[:min_size] || Cloud::MIN_SIZE delta = max_size - min_size max = tags.values.max.to_f min = tags.values.min.to_f # Sorts first based on translated strings and then, if they are equal, based on the original form. # This way variant characters falls on the same level as their base characters and don't end up # at the end of the tag list. # Example: AA ÁA AB Z instead of AA AB Z ÁA tags.collect{ |k,v| [ActiveSupport::Inflector.transliterate(k).downcase, [k,v]] }.sort.collect { |ascii, t| t }.map do |tag,count| if ( max == min ) v = 0.5 else v = (count.to_f - min) / (max - min) end style = ""+ "font-size: #{ (v * delta).round + min_size }px;"+ "top: #{ -(delta/2) - (v * (delta/2)).round }px;" destination = url.merge(tagname_option => tag) if options[:show_count] display_count = options[:show_count] ? "<small><sup>(#{count})</sup></small>" : "" link_to (tag + display_count).html_safe, destination, :style => style else link_to h(tag) , destination, :style => style, :title => n_( 'one item', '%d items', count ) % count end end.join("\n").html_safe end def linked_article_tags(article) if @profile # We are rendering a page inside a profile, so link to the profile tag search. url = { :controller => 'profile', :profile => @profile.identifier, :action => 'tags' } tagname_option = :id else # We are rendering a page outside a profile, so link to the global tag search. url = { :action => 'tag' } tagname_option = :tag end article.tags.map { |t| link_to(t, url.merge(tagname_option=>t.name) ) }.join("\n") end end |