Tag Cloud on rails?


#1

Hi:

Anyone know of anyone that’s implemented AND made available a tag cloud
implemented in rails?

Thanks!

Mike


#2

Mike D. 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


#3

On Wednesday 14 February 2007, Mike D. wrote:

Hi:

Anyone know of anyone that’s implemented AND made available a tag
cloud implemented in rails?

Here’s what I’m using with Acts As Taggable (On Steroids).

I’ve added a method to the Tag model class for retrieving the N most
popular tags

def self.find_most_popular(max_count = 0)
count_col = Tag.connection.quote_column_name(‘count’)
sql = “SELECT tags.id AS id, tags.name AS name, COUNT(*) AS
#{count_col}”
sql << " FROM taggings JOIN tags ON taggings.tag_id = tags.id"
sql << " GROUP BY tag_id ORDER BY #{count_col} DESC"
sql << " LIMIT #{max_count.to_i}" if max_count.to_i > 0
tags = Tag.find_by_sql(sql)
tag_count = tags.size
tags.each do |tag|
tag.send(:write_attribute, :percentage, (tag.count * 100) /
tag_count)
end
tags
end

Acts As Taggable On Steroids has some other functionality for this, see
its REAME.

In the PopularTagsHelper I have a method like this

def popular_tag(t, options = {})
wrap = options[:wrap] || ‘span’
font_size = t.percentage * (options[:size_scale] || 12)
font_weight = t.percentage * (options[:weight_scale] || 10)
font_size = [font_size, options[:min_size]].max if
options[:min_size]
font_size = [font_size, options[:max_size]].min if
options[:max_size]
content_tag(wrap,
link_to(t.name, ‘’),
:title => “#{t.count} times”,
:class => options[:class],
:style => “font-size:#{font_size}%;font-weight:#{font_weight}%”
)
end

In the view

    <% @popular_tags.sort_by(&:name).each do |t| -%> <%= popular_tag(t, :wrap => 'li', :min_size => 30, :max_size => 400) %> <% end -%>

Finally some CSS

.tagcloud {
text-align: center;
width: 70%;
}
.tagcloud li {
display: inline-block;
display: -moz-inline-box;
white-space: nowrap;
vertical-align: middle;
line-height: 1.2em;
padding: 0 0.2em;
}

On a self-serving note, let me point you to
http://schuerig.de/michael/blog/index.php/2007/02/14/popular-requests/

HTH,
Michael


Michael S.
mailto:removed_email_address@domain.invalid
http://www.schuerig.de/michael/