Create a Generator for a Ruby Gem

Today I decided to create a pull request on bootstrap-sass-rails. This gem include Twitter Bootstrap in your Rails application using SASS preprocessor but there is (in my opinion) one thing missing in this gem, the possibility to generate all the files required to modify your theme.

When I use Twitter Bootstrap it is because you can quickly customize all your design just by changing some variables but I don’t know all the variables used by it so I need to copy the variable file to be able to modify each one. I like also to remove all useless css because the bootstrap is good but reeaaaly big so I would like to just include the parts I want.

In this gem there is one file with all the variables and one file which include all the other files so it’s exactly what I need so this generator will just copy those files into my stylesheets directory.

Let’s create this generator !

First you need to create your generator, I decided to have the generator bootstrap:advanced so I need to add the file lib/generators/bootstrap/advanced_generator.rb.

advanced_generator.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
require 'rails/generators'

module Bootstrap
  class AdvancedGenerator < Rails::Generators::Base
    source_root File.expand_path('..', __FILE__)

    # Copy all needed stylesheets in the asset directory of the application
    def copy_stylesheets
      FileUtils.mkdir_p "app/assets/stylesheets/bootstrap_overrides"

      copy_file "../../../app/assets/stylesheets/twitter/bootstrap.css.scss",        "app/assets/stylesheets/bootstrap_overrides/base.css.scss"
      copy_file "../../../app/assets/stylesheets/twitter/bootstrap/_variables.scss", "app/assets/stylesheets/bootstrap_overrides/variables.css.scss"
      copy_file "templates/bootstrap_overrides.css.scss",                            "app/assets/stylesheets/bootstrap_overrides/bootstrap_overrides.css.scss"
    end
  end
end

Let’s have a look on this file. First I load the rails/generator file to be able to use all generators obejects then I create my class extended by the base generator and wrapped by a module. Here don’t forget, convention over configuration the module is the same name of your folder but classify and the same with the class name.

source_root instruction is needed to configure from where the generator have to execute the commands.

Then you just have do define the functions you want, all the functions defined in this class will be called automatically so nothing to do more for this. Good !

So now you generator is done but you still cannot run it when you try to run it. This is because you need to create an Engine class to execute this generator. This part is also pretty simple, just go in your gem lib directory and create the class Engine wraped by the module of your gem.

lib/bootstrap/sass/rails/engine.rb
1
2
3
4
5
6
7
8
module Bootstrap
  module Sass
    module Rails
      class Engine < ::Rails::Engine
      end
    end
  end
end

Tadaaa the generator is now ready to use :)

cool

You can see the full code on the pull request

Comments

Copyright © 2014 - Anthony Estebe -