First, we edit the corresponding template:
By visiting , we should see <h1>Dashboard</h1>
in our browser.
Again we should look at the naming convention. Our view is Web::Views::Dashboard::Index
, while the file name of the template is web/templates/dashboard/index
.
For a given view Web::Views::Dashboard::Index
, the corresponding template MUST be available at apps/web/templates/dashboard/index.html.erb
.
# apps/web/templates/dashboard/index.html.erb
<h1><%= title %></h1>
If we amend our template by adding an interpolated variable, the view is responsible for providing it.
The view now responds to #title
by implementing it as a concrete method. We still see <h1>Dashboard</h1>
when we visit /dashboard
.
There is another source for our context: exposures. They are a payload that comes from the action.
# apps/web/controllers/dashboard/index.rb
module Web
module Controllers
module Dashboard
expose :title
def call(params)
@title = 'Dashboard'
end
end
end
end
end
We can remove #title
from our view, to get the same output when accessing /dashboard
.
The objects exposed in the controller action are available in the corresponding view. So the values can also be modified, wrapped or reused in some other way. Assuming that the title
is exposed in the action, it can be accessed as follows:
# apps/web/views/dashboard/index.rb
module Dashboard
class Index
include Web::View
def full_title
"The title: " + title
end
end
end
end
end
Hanami performs rendering by calling #render
on a view and it expects a string in return. The benefit of an object-oriented approach is the ability to easily diverge from default behavior.
We can override that method to define a custom rendering policy.
Once again our output is still the same, but the template isn’t used at all.
If an action assigns the body of the response with , the rendering of the view is .