-
Notifications
You must be signed in to change notification settings - Fork 334
Using Layouts
It may be desirable to use a common layout file for all JSON responses to include a response code or other metadata. For example, the Google Geocoder API returns a status
field, and all response data under results
.
When returning JSON data, the rails application will merge controller output with a layout file via yield
, just as can be done with view layout files. Below is an example json layout file.
Note: We use the Yajl (
yajl-ruby
) binding in the examples below, but choose any JSON parser you like.
Filename:
app/views/layouts/application.json.erb
You can do this two (or even more) different ways:
{
"metadata": <%= @metadata.to_json.html_safe %>,
"error": <%= @error.to_json.html_safe %>,
"result": <%= yield %>
}
<%=
raw({
metadata: @metadata,
error: @error,
result: Yajl::Parser.parse(yield)
}.to_json)
%>
Filename:
app/views/layouts/application.json.haml
Add haml
to the Gemfile:
gem 'haml'
:plain
{
"status": #{response.status},
"error": #{@error.to_json.html_safe},
"result": #{yield}
}
Filename:
app/views/layouts/application.json.json_builder
Add json_builder
to the Gemfile:
gem 'json_builder'
status response.status
error @error.to_json.html_safe
result JSON.parse(yield)
Filename:
app/views/layouts/application.rabl
node(:status) { response.status }
node(:error) { @error.to_json.html_safe }
node(:result) do
case content_type
when :json
Yajl::Parser.parse(yield)
when :xml
Nori.new.parse(yield)
end
end
In this case, the rendered output of your .rabl
will appear under the result
field (or wherever the yield is placed in the layout file). The controller can pass metadata and error values via instance variables.
A yield by itself will only return the rendered template, which would be escaped HTML in the result
node. But if you convert the rendered content back into a Hash, RABL will treat the yielded content the way you'd expect. So for other content types, call a parser that can convert the yield
content into a Hash that can be understood by RABL.
This example may not work with Ruby 1.9 (1.9.2 and 1.9.3 in my case). So, if it raises No block given (yield)
, try to use Erb (the second one is the better one) or JsonBuilder layouts.
I haven't realize yet how to solve this problem.
Note that
html_safe
prevents Rails from auto-escaping the JSON output. Theraw
helper can also be used. This blog post explains the difference.