Chili
The spicy extension framework
Roadmap
Core features
Unobtrusively(!)...
- add new models
done
- add new tables/migrations
done
- add new controllers and show/hide conditionally
done
- add new views and show/hide conditionally
done
- conditionally add to/edit existing views
done
- add methods to existing models
done
- add new stylesheets and javascripts
done
- modify existing controller actions
Obstacles
- Deface caches overrides in production. Monkey patch?
Minor niggles
- Have to add gemspec to main app
- Can only have one override per engine per partial due to the way I'm grabbing the class from the override
- Need to use DSL branch from deface
- Have to restart server when adding overrides
- Request specs don't have access to path helpers
Docs...
Creating a new chili extension
Assuming you want to add a new extension that adds "like" capabilities to a subset of users, run:
chili likes
This is basically a shortcut for running the rails plugin new
engine generator with a custom template.
The script will prompt you for the location of your main app repository to which you are adding the chili extension. The repo will be added as a submodule in the main_app directory.
Prepare main app
- make sure that shared views (f.ex layouts) uses
main_app.
prefix for routes - add
gem 'deface', git: 'git://github.com/railsdog/deface.git', branch: 'dsl'
to Gemfile - add
gemspec path: '../'
to Gemfile - bundle
- set up database
Setting up activation conditions
Use the active_if block to control whether new controllers/overrides are visible or not. The context of the active_if block is the application controller so you can use any methods available to that.
# lib/chili_likes.rb
module ChiliLikes
extend Chili::Activatable
active_if { logged_in? && current_user.admin? } # Extension is only visible to logged in admin users
end
Modifying view templates in main app
See deface docs for details.
As an example, assuming the main app has a partial at app/views/posts/_post.html.erb
:
<% # app/overrides/posts/_post/chili_likes.html.erb.deface (folder should mimic main app view path) %>
<!-- insert_bottom 'li' -->
<%= link_to 'Show likes', chili_likes.likes_path %>
Adding new resources
Use rails g scaffold Like
as usual when using engines. The new resource will be namespaced to ChiliLikes::Like
and automounted in the main app at /chili_likes/likes
, but only accessible when active_if is true.
All the rules for using engine-based models apply.
Modifying existing models
Create a model with the same name as the one you want to modify: rails g model User --migration=false
and inherit from the original:
# app/model/chili_likes/user.rb
module ChiliLikes
class User < ::User
has_many :likes
end
end
Access through the namespaced model:
<%= ChiliLikes::User.first.likes %>
<%= current_user.becomes(ChiliLikes::User).likes %>
Adding new stylesheets/javascripts
Add files as usual in app/assets/chili_likes/javascripts|stylesheets
and inject them into the layout using an override:
<% # app/overrides/layouts/application/chili_likes.html.erb.deface %>
<!-- insert_bottom 'head' -->
<%= stylesheet_link_tag 'chili_likes/application' %>
<%= javascript_include_tag 'chili_likes/application' %>
Gotchas
- Chili will not be able to automount if you use a catch-all route in your main app (ie
match '*a', to: 'errors#routing'
), you will have to remove the catch-all or manually add the engine to the main app's routes file. - Just like normal engines, Chili requires you to prepend path helpers with
main_app
(iemain_app.root_path
etc) in view templates that are shared with the main app (such as the main app's application layout file).