RuHL on Rails
RuHL has some nice built in helpers, but lets discuss the out-of-the-box functionality.
First, add this to your environment.rb:
# In your config/environment.rb config.gem 'ruhl', :lib => 'ruhl/rails'
Now, everything else is as you would expect. Name your templates *.html.ruhl and Rails will automatically use the RuHL plugin.
Suppose you have the following in your layout:
<title data-ruhl="page_title">My Cool Site</title>
The page_title can be either a helper_method or an instance variable. The scope is the same as the other template languages. If the instance variable is in the controller action, it’s accessible. If it’s a helper method, it’s accessible.
If page_title is a method that returned “Posts | My Cool Site”, the the result would be:
<title>Posts | My Cool Site</title>
RuHL works best/fastest with methods but will look up instance variables. If you have a controller method like:
def show
@post = Post.find(params[:id])
end
And a view with:
<div data-ruhl="_use: post">
<h1 data-ruhl="title"/>
<textarea data-ruhl="content"/>
</div>
RuHL will find and use the @post instance variable as a local object within the scope of the div. When data-ruhl encounters :title, and :content it will first try @post.title and @post.content. If @post does not respond to a method, RuHL will then expect the method to be a helper (or instance variable).
You can turn off instance variable support by setting the following (in environment.rb). This will make processing faster because RuHL won’t use methods like instance_variable_defined? and instance_variable_get on the scope.
Ruhl.use_instance_variables = false
You could easily use the conventional setup of helpers within Rails, but RuHL likes using presenters and promotes their use, here’s how:
Let’s use the ol’ blog example and say you have a PostsController. In the show method of the post you can have something like:
def show
@post = Post.find(params[:id])
present
end
The present method is provided by RuHL and does the following:
1) Expects a PostPresenter to be defined (usually in app/presenters – don’t forget to add this path in config/environment.rb load_paths). The post presenter could be defined as simply as:
class PostPresenter < Ruhl::Rails::Presenter
end
2) Will create an instance of the PostPresenter using @post and @template for context. Here’s the initialize method (for reference):
def initialize(context, obj = nil)
@context = context
# May only want to use the form helper
if obj
@presentee = obj
define_paths(obj.class.name.underscore.downcase)
end
end
3) Renders ‘posts/show’ using the instance of PostPresenter as the local_object.
Here’s an example controller using RuHL’s present:
class PostsController < ApplicationController
def index
@posts = Post.all
end
def show
@post = Post.find(params[:id])
present
end
def new
@post = Post.new
present
end
def edit
@post = Post.find(params[:id])
present
end
def create
@post = Post.new(params[:post])
if @post.save
flash[:notice] = 'Post was successfully created.'
redirect_to(@post)
else
present :action => :new
end
end
def update
@post = Post.find(params[:id])
if @project.update_attributes(params[:post])
flash[:notice] = 'Post was successfully updated.'
redirect_to(@post)
else
present :action => :edit
end
end
def destroy
@post = Post.find(params[:id])
@post.destroy
redirect_to(posts_url)
end
end
So, to use the example from above:
<div data-ruhl="_use: post">
<h1 data-ruhl="title"/>
<textarea data-ruhl="content"/>
</div>
If you were using the presenter, you wouldn’t need the “_use: post”:
<div>
<h1 data-ruhl="title"/>
<textarea data-ruhl="content"/>
</div>
RuHL will look for :title and :content in the following order:
- Looks for a title method on the PostPresenter
- Looks for a title method on the @post instance variable
- Looks for a title method/instance variable on the scope.
