Skip to content
Newer
Older
100644 87 lines (65 sloc) 2.48 KB
b7a0372 @mislav initial import
authored Jun 23, 2009
1 Asbestos
2 ========
3
4 Template handler for Rails that allows you to use
5 a subset of XML Builder markup to produce JSON.
6
7 Take, for instance, a common "show.xml.builder" template:
8
9 xml.instruct!
10 xml.category(:private => false) do
11 xml.name @category.name
12 xml.parent do
13 xml.id @category.parent_id
14 xml.name @category.parent.name
15 end
16 end
17
18 If you copied that to "show.json.asbestos", you would get:
19
20 {"category": {
21 "private": "false",
22 "name": "Science & Technology",
23 "parent": {
24 "id": 1,
25 "name": "Religion"
26 }
27 }}
28
29 But of course, you don't want to duplicate your builder template
30 in another file, so we'll handle this in the controller:
31
32 def show
33 respond_to do |wants|
34 wants.xml
35 wants.json {
36 # takes the "show.xml.builder" template and renders it to JSON
37 render_json_from_xml
38 }
39 end
40 end
41
42 With this method there's no need for a special template file for JSON.
43 Asbestos is designed to use existing XML Builder templates.
44
45 How does it work?
46 -----------------
47
48 The `xml` variable in your normal builder templates is the XML Builder object.
49 When you call methods on this object, it turns that into XML nodes and appends
50 everything to a string, which is later returned as the result of rendering.
51
52 This plugin provides Asbestos::Builder, which tries to mimic the behavior
53 of the XML Builder while saving all the data to a big nested ruby hash.
54 In the end, `to_json` is called on it.
55
56 Aggregates and ignores (important!)
57 -----------------------------------
58
59 Problems start when you have Builder templates that render *collections*,
60 like in index actions:
61
62 xml.instruct!
63 for category in @categories
64 xml.category do
65 # ...
66 end
67 end
68
69 There is a ruby loop in there, so if there are multiple categories the resulting
70 JSON would have just one. This is because the same "category" field in the JSON
71 hash would keep getting re-written by the next iteration. Asbestos::Builder is,
72 unfortunately, not aware about any loops in your template code.
73
74 The solution is to indicate explicitly which keys you want aggregated:
75
76 render_json_from_xml :aggregate => ['category']
77
78 Now, what would previously create a "category" key will get aggregated
79 under a "categories" array, instead:
80
81 { "categories": [ ... ] }
82
83 Sometimes, most often with root elements, you want a key ignored.
84 You can specify which occurrences to ignore:
85
86 render_json_from_xml :ignore => ['category']
Something went wrong with that request. Please try again.