Adding Blog Tags using Webby
The blog now looks better and better, but it is still missing a key feature — tags.
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
Adding a tags attribute under each blog’s meta data
This is easy, just open up a post and add a tags attribute to the meta data:
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
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:
# 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)
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:
# finding first 10 posts in blogs dir, and sorted in descending chronological order posts(10, :in_directory => 'blogs', :sort_by => "created_at", :reverse => true)
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.
Make a partial
Now that we have the helper, we can make a partial that displays the tags. I made it in HAML:
%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]})
You can see the partial in effect on the lower right side of the page in footer. This is basic and nothing fancy…
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.
#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
You will also need the corresponding templates/tags/generate.erb, which you can find in my github account