p. The blog now looks better and better, but it is still missing a key feature -- tags. p. Let's bust it out! Here is my plan: * Adding a tags attribute under each blog's meta data * Make a helper that reads each blog and count the occurance of each tag * Make a partial that links to each tags * Make a rake task that auto generates tags folder h3. Adding a tags attribute under each blog's meta data p. This is easy, just open up a post and add a **tags** attribute to the meta data: <%- uv( :lang => "yaml", :theme => 'blackboard', :line_numbers => false ) do -%> title : Adding Blog Tags using Webby created_at : 2009-04-06 19:12:00.343030 +08:00 blog_post : true filter: - erb - textile # Add some tags for this post tags: - ruby - webby <% end -%> h3. Make tags helper All I need to do is to make a tags helper module that does the counting for me, and register it with Webby. Here is the code: <% uv( :lang => "ruby", :theme => 'blackboard', :line_numbers => false ) do -%> # lib/tags_helper.rbS module TagsHelper # find all blog posts def posts(limit=:all, find_options=nil) options = { :in_directory => 'articles', :recursive => true, :blog_post => true, :sort_by => "created_at", :reverse => true} options.merge!(find_options) if find_options ::Webby::Resources.pages.find(limit, options) end def tags_hash return @tags_hash if @tags_hash @tags_hash = {} posts.each do |post| post.tags.each do |tag| @tags_hash[tag] ||=0 @tags_hash[tag] += 1 end if post.tags end @tags_hash end def posts_with_tag(tag, limit=:all, find_options=nil) posts(limit, find_options) do |post| post.tags && post.tags.include?(tag) end end end Webby::Helpers.register(TagsHelper) <% end -%> @posts@ is a handy little short cut for getting all blog posts, much shorter to type. You can also pass in the @limit@, and @find_options@ to customize your find. Example: <% uv( :lang => "ruby", :theme => 'blackboard', :line_numbers => false ) do -%> # finding first 10 posts in blogs dir, and sorted in descending chronological order posts(10, :in_directory => 'blogs', :sort_by => "created_at", :reverse => true) <% end -%> @tags_hash@ returns a hash with tag name and occurance as the key and value. @posts_with_tag@ finds all the blog posts related to a tag. h3. Make a partial Now that we have the helper, we can make a partial that displays the tags. I made it in HAML: <% uv( :lang => "haml", :theme => 'blackboard', :line_numbers => false ) do -%> %ul / sort tags in alphabetical order, and then generate links for each tag -tags_hash.keys.sort.each do |tag| %li %a{:href=>"/tags/#{tag}"}= tag ==(#{tags_hash[tag]}) <% end -%> You can see the partial in effect on the lower right side of the page in footer. This is basic and nothing fancy... h3. Make a Rake Task Now the tags are in place, we want actually display the tags pages. We make a new rake task to generate all the tags page for us. <% uv( :lang => "ruby", :theme => 'blackboard', :line_numbers => false ) do -%> #tags.rake require 'lib/tags.rb' include TagsHelper namespace :tags do desc "auto generate all tags page" task :generate do ::Webby.load_files tags_hash.keys.each do |tag| dir = Webby.site.tags_dir page = File.join(dir, File.basename(tag)) page = Webby::Builder.create(page, :from => "#{Webby.site.template_dir}/tags/generate.erb", :locals => {:tag => tag, :directory => dir}) end end desc "remove all tags page" task :remove do rm_r Webby.site.content_dir + "/" + Webby.site.tags_dir end desc "regenerate all tags page" task :regenerate => [:remove, :generate] end <% end -%> You will also need the corresponding @templates/tags/generate.erb@, which you can find in "my github account":http://github.com/aq1018/aaron-blog/