Wolfmans Howlings

A programmers Blog about Ruby, Rails and a few other issues

Developing a social networking site part 3 - tag cloud

Posted by Jim Morris Sat, 23 Jun 2007 21:02:49 GMT

This is a simple one.

I use the excellent acts_as_taggable plugin, and I wanted to have a tag cloud like everyone does.

Of course I have different Models that can be tagged, and I want to keep everything DRY, so I created a helper and put the following in the application_helper.rb file

  # display a tag cloud for the given model
  def tag_cloud(model, title= nil)
    m= model.to_s.camelcase.constantize
    plural= model.to_s.capitalize.pluralize
    title ||= plural
    tags= m.tag_counts(:order => 'tags.name')
    gen= ""
    unless tags.empty?
      urlmeth= "tagged_#{model.to_s.pluralize}_path".to_sym
      gen= "<div class=\"tagcloud\">"
      gen += "<h3>#{title}</h3>"
      tags.each do |t|
        gen += "<span style=\"font-size:#{calc_size(t.count)}%\">"
        gen += link_to(h(t.name), self.send(urlmeth, :tag => t.name))
        gen += "</span> "
      end
      gen += "</div>"
      gen += "<hr/>"
    end
    gen
  end

This allows me to have multiple tag clouds for the different models, see snowdogsr.us on the left bar at the bottom.

The font is bigger for the more popular tags, and you can click on any tag to get a listing of all matching articles.

I use RESTful routing so I added this to routes.rb

  map.resources :places, :collection => { :tagged => :get }

which creates a named route tagged_places_path which returns an index with the places tagged with the tag that was clicked.

The places_controller method looks like this...

  def tagged
    @places= Place.find_tagged_with(params[:tag], :order => "updated_at DESC")
    @filter= "Tagged with #{params[:tag]}"
    respond_to do |format|
      format.html { render :action => 'index' }
      format.xml  { render :xml => @places.to_xml }
    end
  end

Posted in  | Tags , ,  | no comments | no trackbacks