A view can handle several MIME Types. Before diving into this subject, please consider to read how actions handle MIME Types.
It’s important to highlight the correlation between the format and template name. For a given MIME Type, Rack (and then Hanami) associate a format for it. XML is mapped from application/xml
to :xml
, HTML is text/html
and becomes :html
for us.
Format MUST be the first extension of the template file name. Eg dashboard/index.html.*
.
Default Rendering
If our action (Web::Controllers::Dashboard::Index
) is handling a JSON request, and we have defined a template for it (apps/web/templates/dashboard/index.json.erb
), our view will use it for rendering.
# apps/web/templates/dashboard/index.json.erb
{"foo":"bar"}
% curl -H "Accept: application/json" http://localhost:2300/dashboard
{"foo":"bar"}
We’re still able to request HTML format.
# apps/web/templates/dashboard/index.html.erb
<h1>Dashboard</h1>
% curl -H "Accept: text/html" http://localhost:2300/dashboard
<h1>Dashboard</h1>
In case we request an unsupported MIME Type, our application will raise an error.
% curl -H "Accept: application/xml" http://localhost:2300/dashboard
Hanami::View::MissingTemplateError: Can't find template "dashboard/index" for "xml" format.
View For Specific Format
This scenario works well if the presentational logic of a view can be applied for all the format templates that it handles. What if we want to have a custom rendering or different presentational logic?
We can inherit from our view and declare that our subclass only handles a specific format.
# apps/web/views/dashboard/json_index.rb
require_relative './index'
module Web
module Views
module Dashboard
class JsonIndex < Index
format :json
def render
raw JSON.generate({foo: 'bar'})
end
end
end
end
end
JSON requests for /dashboard
, will be handled by our JsonIndex
.
There is NO convention between the handled format and the class name. The important part is format :json
.
With the example above we took advantage of custom rendering to not use the template and let our serializer to return JSON for us.