Rails templates
So now that Edge Rails got templates ( Thanks to Jeremy ) I just wanted to give a top level overview.
Templates are simple ruby files containing DSL for adding plugins/gems/initializers etc. to your freshly created Rails project. To apply the template, you need to provide rails generator with location of the template you wish to apply, using -m option :
|
|
rails blog -m ~/template.rb |
Thanks to the magic of open-uri, the template location can be a URL too :
|
|
rails blog -m http://gist.github.com/31208.txt |
You can even apply templates to your existing Rails application using rails:template rake task and supplying LOCATION environment variable :
|
|
rake rails:template LOCATION=~/template.rb |
A very simple template would look like :
1 2 3 4 5 6 7 8 9 |
# template.rb run "rm public/index.html" generate(:scaffold, "person name:string") route "map.root :controller => 'people'" rake("db:migrate") git :init git :add => "." git :commit => "-a -m 'Initial commit'" |
That’s very self explanatory. Here are the key methods for the template DSL :
gem(name, options = {})
Adds a config.gem entry for the supplied gem to generated application’s config/environment.rb
So if your application depends on bj and hpricot :
1 2 |
gem "bj" gem "hpricot", :version => '0.6', :source => "http://code.whytheluckystiff.net" |
Please note that this will NOT install the gems for you. So you may want to run rake gems:install:
|
|
rake "gems:install" |
And let Rails take care of installing the required gems if they’re not already installed.
plugin(name, options = {})
Installs a plugin to the generated application.
Plugin can be installed from Git :
|
|
plugin 'authentication', :git => 'git://github.com/foor/bar.git' |
You can even install plugins as git submodules :
|
|
plugin 'authentication', :git => 'git://github.com/foor/bar.git', :submodule => true |
Please note that you need to git :init before you can install a plugin as a submodule
Or use plain old SVN :
|
|
plugin 'wtfsvn' :svn => 'svn://crap.com/wtf/trunk' |
initializer(filename, data = nil, &block)
Adds an initializer to the generated application’s config/initializers directory.
So personally, I like using Object#not_nil? and Object#not_blank? :
1 2 3 4 5 6 7 8 9 10 11 |
initializer 'bloatlol.rb', <<-CODE-code class Object def not_nil? !nil? end def not_blank? !blank? end end CODE |
Similarly lib() creates a file in lib/ directory and vendor() creates a file in vendor/ directory. There is also file(), which accepts a relative path from RAILS_ROOT and creates all the directories/file needed :
1 2 3 4 |
file 'app/components/foo.rb', <<-CODE-code class Foo end CODE |
That’ll create app/components directory and put foo.rb in there.
rakefile(filename, data = nil, &block)
Creates a new rake file under lib/tasks with the supplied tasks :
1 2 3 4 5 6 7 8 9 |
rakefile("bootstrap.rake") do <<-TASK-task namespace :boot do task :strap do puts "i like boots!" end end TASK end |
And that creates lib/tasks/bootstrap.rake with a boot:strap rake task!
generate(what, args)
Runs the supplied rails generator with given arguments. For example, I love to scaffold some whenever I’m playing with Rails :
|
|
generate(:scaffold, "person", "name:string", "address:text", "age:number") |
run(command)
Executes an arbitrary command. Just like the backticks. My main use case is to remove public/index.html :
|
|
run "rm public/index.html" |
rake(command, options = {})
So you scaffolded, but who’s gonna run the db:migrate rake task !? Here’s who :
|
|
rake "db:migrate" |
Simple enough.
You can also run rake tasks in a different rails environment :
|
|
rake "db:migrate", :env => 'production' |
Or even use sudo :
|
|
rake "gems:install", :sudo => true |
route(routing_code)
This adds a routing entry to config/routes.rb file. In above steps, we generated a person scaffold and also removed public/index.html. Now to make PeopleController#index as the default page for the application :
|
|
route "map.root :controller => :person" |
Voila!
inside(dir)
I have my edge rails lying at ~/commit-rails/rails. So every time i have to manually symlink edge from my new app. But now :
1 2 3 |
inside('vendor') do run "ln -s ~/commit-rails/rails rails" end |
So inside() runs the command from the given directory.
ask(question)
ask gives you a chance to get some feedback from the user and use it in your templates. Lets say you want your user to name the new shiny library you’re adding :
1 2 3 4 5 6 7 |
lib_name = ask("What do you want to call the shiny library ?") lib_name << ".rb" unless lib_name.index(".rb") lib lib_name, <<-CODE-code class Shiny end CODE> |
yes?(question) or no?(question)
And you can even ask questions from templates and decide the flow based on user’s answer. Lets say you want to freeze rails only if the user want to :
|
|
rake("rails:freeze:gems") if yes?("Freeze rails gems ?") |
no?(question) acts just the opposite.
git(:must => “-a love”)
As we all love git/hub, Rails templates let you do the git stuff too !
1 2 3 |
git :init git :add => "." git :commit => "-a -m 'Initial commit'" |
And bort ?
Here’s what a bort template would look like :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# bort.rb inside('vendor') do run "ln -s ~/commit-rails/rails rails" end plugin 'rspec', :git => 'git://github.com/dchelimsky/rspec.git' plugin 'rspec-rails', :git => 'git://github.com/dchelimsky/rspec-rails.git' plugin 'exception_notifier', :git => 'git://github.com/rails/exception_notification.git' plugin 'open_id_authentication', :git => 'git://github.com/rails/open_id_authentication.git' plugin 'asset_packager', :git => 'http://synthesis.sbecker.net/pages/asset_packager' plugin 'role_requirement', :git => 'git://github.com/timcharper/role_requirement.git' plugin 'restful-authentication', :git => 'git://github.com/technoweenie/restful-authentication.git' gem 'mislav-will_paginate', :version => '~> 2.2.3', :lib => 'will_paginate', :source => 'http://gems.github.com' gem 'rubyist-aasm' gem 'ruby-openid' rake("gems:install", :sudo => true) generate("authenticated", "user session") generate("rspec") |
Shamelessly inspired/yanked from Jeremy’s templates repo
Save that code in bort.rb and :
|
|
[lifo@null Rails]$ ruby ~/commit-rails/rails/railties/bin/rails bortapp -m bort.rb |
Contribute
If you like this template stuff and want to share your templates with the rest of us, please contribute to Jeremy’s rails-templates project – which will be a collection of Rails templates.
And as usual, any bugs/feature requests can go to Rails lighthouse
UPDATE 1 Add an example of installing plugins as a git submodule. Thanks to Peter Cooper for the patch.
UPDATE 2 Add an example of rake rails:template LOCATION=foo task
- Person:
- Programming Language:
- Technology:


Recent comments
1 year 23 weeks ago
1 year 23 weeks ago
1 year 25 weeks ago
1 year 27 weeks ago
1 year 42 weeks ago
1 year 45 weeks ago
1 year 45 weeks ago
1 year 45 weeks ago
1 year 46 weeks ago
1 year 48 weeks ago