Archive for February, 2012

Multiple manifests for the asset pipeline

Tuesday, February 7th, 2012

One of the cool features introduced in Rails 3.1 was the asset pipeline (Asset Pipeline). The pipeline allows you to add js/css to manifest files and rails will precompile them into a single file, thus reducing load time.

The docs mention that you can have multiple manifest files:

You can have as many manifest files as you need. For example the admin.css and admin.js manifest could contain the JS and CSS files that are used for the admin section of an application.

This is handy for any number of reasons, allowing you to have as many specific css or js files as needed.

However, one thing missing from the docs is how to tell the precompiler that it needs to look for additional manifest files.

Just add this to your application.rb

config.assets.precompile += %w( admin.css )

will_paginate and acts_as_taggable_on and bootstrap

Tuesday, February 7th, 2012

In the process of updating my site to Rails 3.2 and decided to change up a few things. First, decided to use the bootstrap css framework from twitter (Bootstrap). There are a number of gems that allow you to use the less in rails, but the site actually has a very nice customization tool if you just want to tweak it how you’d like and then download the static css.

In order to get will_paginate to play nicely with bootstrap, you should follow this advice (will_paginate with bootstrap). Just create a will_paginate initializer to generate a new renderer for the link bar.

module WillPaginate
  module ActionView
    def will_paginate(collection = nil, options = {})
      options[:renderer] ||= BootstrapLinkRenderer
      super.try :html_safe
    end
 
    class BootstrapLinkRenderer < LinkRenderer
      protected
 
      def html_container(html)
        tag :div, tag(:ul, html), container_attributes
      end
 
      def page_number(page)
        tag :li, link(page, page, :rel => rel_value(page)), :class => ('active' if page == current_page)
      end
 
      def previous_or_next_page(page, text, classname)
        tag :li, link(text, page || '#'), :class => [classname[0..3], classname, ('disabled' unless page)].join(' ')
      end
 
      def gap
         tag :li, link(super, '#'), :class => 'disabled'
       end
    end
  end
end

I also decided to add tagging using the excellent acts_as_taggable_on gem (Acts As Taggable On). One of the things I wanted to do was not only display all tags available, but all tags available on subsets. And make it play nicely with pagination.

I tried this first:

@worlds = World.tagged_with(params[:tag]).order('title ASC').page(params[:page])
@tags = @worlds.tag_counts_on(:tags)

but the query turns out to be too complex

Mysql2::Error: This version of MySQL doesn’t yet support ‘LIMIT & IN/ALL/ANY/SOME subquery’

so I had to split out the actions on the relation:

@worlds = World.tagged_with(params[:tag]).order('title ASC')
@tags = @worlds.tag_counts_on(:tags)
@worlds = @worlds.page(params[:page])

and it works like a charm.