https://github.com/mislav/asbestos
Render JSON from your XML Builder templates
https://github.com/mislav/asbestos
Last synced: 2 months ago
JSON representation
Render JSON from your XML Builder templates
- Host: GitHub
- URL: https://github.com/mislav/asbestos
- Owner: mislav
- License: mit
- Created: 2009-06-23T18:37:40.000Z (almost 16 years ago)
- Default Branch: master
- Last Pushed: 2009-12-20T11:27:25.000Z (over 15 years ago)
- Last Synced: 2025-04-15T17:11:48.919Z (2 months ago)
- Language: Ruby
- Size: 85 KB
- Stars: 7
- Watchers: 4
- Forks: 1
- Open Issues: 0
-
Metadata Files:
- Readme: README.markdown
- License: LICENSE
Awesome Lists containing this project
README
Asbestos
========Template handler for Rails that allows you to use
a subset of XML Builder markup to produce JSON.Take, for instance, a common "show.xml.builder" template:
xml.instruct!
xml.category(:private => false) do
xml.name @category.name
xml.parent do
xml.id @category.parent_id
xml.name @category.parent.name
end
endIf you copied that to "show.json.asbestos", you would get:
{"category": {
"private": "false",
"name": "Science & Technology",
"parent": {
"id": 1,
"name": "Religion"
}
}}But of course, you don't want to duplicate your builder template
in another file, so we'll handle this in the controller:def show
respond_to do |wants|
wants.xml
wants.json {
# takes the "show.xml.builder" template and renders it to JSON
render_json_from_xml
}
end
endWith this method there's no need for a special template file for JSON.
Asbestos is designed to use existing XML Builder templates.How does it work?
-----------------The `xml` variable in your normal builder templates is the XML Builder object.
When you call methods on this object, it turns that into XML nodes and appends
everything to a string, which is later returned as the result of rendering.This plugin provides Asbestos::Builder, which tries to mimic the behavior
of the XML Builder while saving all the data to a big nested ruby hash.
In the end, `to_json` is called on it.Aggregates and ignores (important!)
-----------------------------------Problems start when you have Builder templates that render *collections*,
like in index actions:xml.instruct!
for category in @categories
xml.category do
# ...
end
endThere is a ruby loop in there, so if there are multiple categories the resulting
JSON would have just one. This is because the same "category" field in the JSON
hash would keep getting re-written by the next iteration. Asbestos::Builder is,
unfortunately, not aware about any loops in your template code.The solution is to indicate explicitly which keys you want aggregated:
render_json_from_xml :aggregate => ['category']
Now, what would previously create a "category" key will get aggregated
under a "categories" array, instead:{ "categories": [ ... ] }
Sometimes, most often with root elements, you want a key ignored.
You can specify which occurrences to ignore:render_json_from_xml :ignore => ['category']