Mike Dershowitz wrote:
Hi:
Anyone know of anyone that's implemented AND made available a tag cloud implemented in rails?
Thanks!
Mike
Like Michael, I'm using acts_as_taggable and adding a method to the Tag model but implementing it slightly differently. I'm pasting the code as is (and just looking at it fresh, it could be improved in places), but not all of it is needed (e.g. I needed to be able to restrict the tag cloud to certain models, and those lines are commented as optional
def self.tag_cloud_count(options={}) except, only = options[:except].to_a, options[:only].to_a # optional raise ArgumentError, "You can only specify :except OR :only options" if !except.empty? && !only.empty? # optional conditions = "taggings.tag_id = tags.id" if except.empty? && only.empty? conditions = ["(taggings.tag_id = tags.id) AND (taggings.taggable_type IN (?))", only.collect {|m| m.to_s.classify }] if !only.empty? # optional conditions = ["(taggings.tag_id = tags.id) AND (taggings.taggable_type NOT IN (?))", except.collect {|m| m.to_s.classify }] if !except.empty? # optional find(:all, :select => "tags.*, COUNT(*) AS tag_count", :joins => "INNER JOIN taggings", :conditions => conditions, :group => "tags.name", :order => "tags.name ASC") end
Then in my app helper: def tag_cloud_for(tag_cloud) max_tag_count = tag_cloud.max {|a,b| a.tag_count.to_i <=> b.tag_count.to_i }.tag_count.to_f min_tag_count = tag_cloud.min {|a,b| a.tag_count.to_i <=> b.tag_count.to_i }.tag_count.to_f min_font_size = 1.0 max_font_size = 2.5 mult = (max_font_size - min_font_size)/(max_tag_count - min_tag_count) output = tag_cloud.collect { |tag| link_to( tag.name, {:controller => 'search', :tag => tag.name}, {:style => "font-size: #{(((tag.tag_count.to_f - min_tag_count) * mult) + min_font_size)}em"}) } output.join(" ") end
In the helper method above the argument of the method is simply the collection of tags returned by to tag_cloud_count method. The cloud is output as a set of links, which go to my search controller, which returns all items tagged with the given term.
Of course, YMMV, but hopefully between this and Michael's solution you should be able to find something that suits.
Cheers Chris