Terminology

All the Rails Engines docs apply to tools and mods.

Configuration

Mods may be enabled or disabled by editing config/mods_enabled.list. Likewise for tools with config/tools_enabled.list.

Additionally, your mod may need extra routes. An example might be:

codetitle. config/routes.rb

  map.from_plugin :gibberize

See the mod README to find out if a routes entry is required.

Tools can be made visible or hidden on a per site basis. See config/sites.yml.

Creating mod or tool

Every crabgrass mod/tool starts out life as a regular plugin. To create a skeleton:

./script/generate plugin your_plugin_name

This will create a new plugin in your vendor/plugins directory.

Move this directory to mods or tools directory:

mv vendor/plugin/your_plugin_name mods

The first thing to do is edit your new mod’s init.rb:

self.override_views = true
self.load_once = false

If override_views is set to true, then view files in your mod will override those in the main app. If load_once is set to false, then you can make changes to your mod in development mod and see those changes reflected in the application without needing to restart script/server.

As with every engine, mods and tools may contain an ‘app’ subfolder. This app folder mirrors the app in the rails root. Files in the mod’s app will append or overwrite the files in the main app folder.

For example:

app
|-- controllers
|   |-- account_controller.rb
|   '-- application.rb
'-- views
    '-- account
        |-- index.html.erb
        '-- login.html.erb
mods
|-- mymod1
|-- mymod2
'-- mymod3
    '-- app
        |-- controllers
        |   '-- account_controller.rb
        '-- views
            '-- account
                '-- login.html.erb

The file mods/mymod3/app/views/account/login.html.erb will override app/views/account/login.html.erb (but only if override_views is set to true). The file mods/mymod3/app/controllers/account_controller.rb will add new methods or change existing methods of app/controllers/account_controller.rb.

finalize

Another thing that mods can do is to run some code after everything else has been run. This is not so useful for plugins, but for mods it is often needed: Suppose, for example, you want to extend the Page class. Normally, plugins are not written to know anything about your particular rails application, but in the case of mods they are intended to modify a very specific rails application.

If we were to try to modify the Page class in the init.rb of our mod, we would create many errors trying to reference Page too early in rail’s startup process.

To get around this, mods can pass a block to self.finalize and this code will only get called once everything is loaded.

For example:

codetitle. mods/mymode/init.rb

self.finalize do
  Page.class_eval do
    acts_as_rateable
  end
end

mod migrations

If your plugin requires database migrations, you can generate new migrations and put them in a db/migrate folder in the plugin.

Then, to add these migrations to the main rails app, you run this:

./script/generate plugin_migration

That will generate a new app level migration that will run your plugin migrations.

mod assets

If you want to distribute stylesheets/javascripts/images with your plugin put them in a stylesheets/javascripts/images folder inside an assets folder in the plugin. Next time you run script/console or start the server the folders inside your plugin assets folder will be copied to public/plugin_assets/plugin_name.