Renamed helpers to correspond to renamed Controller classes.
[merb_radiant.git] / radiant_specs / test / unit / .svn / text-base / standard_tags_test.rb.svn-base
blob7c14666ad9b377535388a2f2e495afbdece84761
1 require File.dirname(__FILE__) + '/../test_helper'
3 class StandardTagsTest < Test::Unit::TestCase
4   
5   fixtures :pages, :page_parts, :layouts, :snippets, :users
6   test_helper :render, :pages
7   
8   def setup
9     @page = pages(:radius)
10   end
11   
12   def test_tag_page
13     assert_renders 'Radius Test Page', '<r:title />'
14     assert_renders 'Ruby Home Page | Radius Test Page', %{<r:find url="/"><r:title /> | <r:page:title /></r:find>}
15   end
16   
17   def test_tags_page_attributes
18     [:breadcrumb, :slug, :title, :url].each do |attr|
19       value = @page.send(attr)
20       assert_renders value.to_s, "<r:#{attr} />"
21     end
22   end
23   
24   def test_tag_children
25     expected = 'Radius Test Child 1 Radius Test Child 2 Radius Test Child 3 '
26     input = '<r:children:each><r:title /> </r:children:each>'
27     assert_renders expected, input
28   end
29   def test_tag_children_each
30     assert_renders 'radius/child-1 radius/child-2 radius/child-3 ' , '<r:children:each><r:page><r:slug />/<r:child:slug /> </r:page></r:children:each>'
31   end
32   def test_tag_children_each_attributes
33     @page = pages(:assorted)
34     assert_renders 'a b c d e f g h i j ', page_children_each_tags
35     assert_renders 'a b c d e ',           page_children_each_tags(%{limit="5"})
36     assert_renders 'd e f g h ',           page_children_each_tags(%{offset="3" limit="5"})
37     assert_renders 'j i h g f e d c b a ', page_children_each_tags(%{order="desc"})
38     assert_renders 'f e d c b a j i h g ', page_children_each_tags(%{by="breadcrumb"})
39     assert_renders 'g h i j a b c d e f ', page_children_each_tags(%{by="breadcrumb" order="desc"})
40   end
41   def test_tag_children_each_with_status_attribute
42     @page = pages(:assorted)
43     assert_render_match /^(draft |)a b c d e f g h i j( draft|) $/, page_children_each_tags(%{status="all"})
44     assert_renders 'draft ', page_children_each_tags(%{status="draft"})
45     assert_renders 'a b c d e f g h i j ', page_children_each_tags(%{status="published"})
46     assert_render_error "`status' attribute of `each' tag must be set to a valid status", page_children_each_tags(%{status="askdf"})
47   end
48   def test_tag_children_each_attributes_with_invalid_limit
49     message = "`limit' attribute of `each' tag must be a positive number between 1 and 4 digits"
50     assert_render_error message, page_children_each_tags(%{limit="a"})
51     assert_render_error message, page_children_each_tags(%{limit="-10"})
52     assert_render_error message, page_children_each_tags(%{limit="50000"})
53   end
54   def test_tag_children_each_attributes_with_invalid_offset
55     message = "`offset' attribute of `each' tag must be a positive number between 1 and 4 digits"
56     assert_render_error message, page_children_each_tags(%{offset="a"})
57     assert_render_error message, page_children_each_tags(%{offset="-10"})
58     assert_render_error message, page_children_each_tags(%{offset="50000"})
59   end
60   def test_tag_children_each_attributes_with_invalid_by_field_name
61     message = "`by' attribute of `each' tag must be set to a valid field name"
62     assert_render_error message, page_children_each_tags(%{by="non-existant-field"})
63   end
64   def test_tag_children_each_attributes_with_invalid_limit
65     message = %{`order' attribute of `each' tag must be set to either "asc" or "desc"}
66     assert_render_error message, page_children_each_tags(%{order="asdf"})
67   end
68   def test_tag_children_each_does_not_list_virtual_pages
69     @page = pages(:assorted)
70     assert_renders 'a b c d e f g h i j ', '<r:children:each><r:slug /> </r:children:each>'
71     assert_render_match /^(draft |)a b c d e f g h i j( draft|) $/, '<r:children:each status="all"><r:slug /> </r:children:each>'
72   end
73   
74   def test_tag_children_each_header
75     @page = pages(:news)
76     assert_renders '[Jan/06] a-great-day-for-ruby [Feb/06] another-great-day-for-ruby later-that-day [Jan/07] next-year-in-ruby ', '<r:children:each><r:header>[<r:date format="%b/%y" />] </r:header><r:slug /> </r:children:each>'
77   end
78   def test_tag_children_each_header_with_name_attribute
79     @page = pages(:news)
80     assert_renders '[2006] (Jan) a-great-day-for-ruby (Feb) another-great-day-for-ruby later-that-day [2007] (Jan) next-year-in-ruby ', %{<r:children:each><r:header name="year">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:children:each>}  
81   end
82   def test_tag_children_each_header_with_restart_attribute
83     @page = pages(:news)
84     assert_renders(
85       '[2006] (Jan) a-great-day-for-ruby (Feb) another-great-day-for-ruby later-that-day [2007] (Jan) next-year-in-ruby ',
86       %{<r:children:each><r:header name="year" restart="month">[<r:date format='%Y' />] </r:header><r:header name="month">(<r:date format="%b" />) </r:header><r:slug /> </r:children:each>}
87     )
88     assert_renders(
89       '[2006] (Jan) <30> a-great-day-for-ruby (Feb) <05> another-great-day-for-ruby <06> later-that-day [2007] (Jan) <30> next-year-in-ruby ',
90       %{<r:children:each><r:header name="year" restart="month;day">[<r:date format='%Y' />] </r:header><r:header name="month" restart="day">(<r:date format="%b" />) </r:header><r:header name="day"><<r:date format='%d' />> </r:header><r:slug /> </r:children:each>}
91     )
92   end
93   
94   def test_tag_children_count
95     assert_renders '3', '<r:children:count />'
96   end
97   
98   def test_tag_children_first
99     assert_renders 'Radius Test Child 1', '<r:children:first:title />'
100   end
101   def test_tag_children_first_parameters
102     @page = pages(:assorted)
103     assert_renders 'a', page_children_first_tags
104     assert_renders 'a', page_children_first_tags(%{limit="5"})
105     assert_renders 'd', page_children_first_tags(%{offset="3" limit="5"})
106     assert_renders 'j', page_children_first_tags(%{order="desc"})
107     assert_renders 'f', page_children_first_tags(%{by="breadcrumb"})
108     assert_renders 'g', page_children_first_tags(%{by="breadcrumb" order="desc"})
109   end
110   def test_tag_children_first_is_nil
111     @page = pages(:textile)
112     assert_renders '', '<r:children:first:title />'
113   end
114   
115   def test_tag_children_last
116     assert_renders 'Radius Test Child 3', '<r:children:last:title />'
117   end
118   def test_tag_children_last_parameters
119     @page = pages(:assorted)
120     assert_renders 'j', page_children_last_tags
121     assert_renders 'e', page_children_last_tags(%{limit="5"})
122     assert_renders 'h', page_children_last_tags(%{offset="3" limit="5"})
123     assert_renders 'a', page_children_last_tags(%{order="desc"})
124     assert_renders 'g', page_children_last_tags(%{by="breadcrumb"})
125     assert_renders 'f', page_children_last_tags(%{by="breadcrumb" order="desc"})
126   end
127   def test_tag_children_last_nil
128     @page = pages(:textile)
129     assert_renders '', '<r:children:last:title />'
130   end
131   
132   def test_tag_content
133     expected = "<h1>Radius Test Page</h1>\n\n\n\t<ul>\n\t<li>Radius Test Child 1</li>\n\t\t<li>Radius Test Child 2</li>\n\t\t<li>Radius Test Child 3</li>\n\t</ul>"
134     assert_renders expected, '<r:content />'
135   end
136   def test_tag_content_with_part_attribute
137     assert_renders "Just a test.\n", '<r:content part="extended" />'
138   end
139   def test_tag_content_with_inherit_attribute
140     assert_renders '', '<r:content part="sidebar" />'
141     assert_renders '', '<r:content part="sidebar" inherit="false" />'
142     assert_renders 'Radius Test Page sidebar.', '<r:content part="sidebar" inherit="true" />'
143     assert_render_error %{`inherit' attribute of `content' tag must be set to either "true" or "false"}, '<r:content part="sidebar" inherit="weird value" />'
144     
145     assert_renders '', '<r:content part="part_that_doesnt_exist" inherit="true" />'
146   end
147   def test_tag_content_with_inherit_and_contextual_attributes
148     assert_renders 'Radius Test Page sidebar.', '<r:content part="sidebar" inherit="true" contextual="true" />'
149     assert_renders 'Ruby Home Page sidebar.', '<r:content part="sidebar" inherit="true" contextual="false" />'
150     
151     @page = pages(:inheritance_test_page_grandchild)
152     assert_renders 'Inheritance Test Page Grandchild inherited body.', '<r:content part="body" inherit="true" contextual="true" />'
153   end
154   def test_tag_content_with_inherit_attribute_grandparent
155     @page = pages(:child)
156     assert_renders '', '<r:content part="sidebar" />'
157     assert_renders 'Child sidebar.', '<r:content part="sidebar" inherit="true" />'
158     @page = pages(:parent)
159     assert_renders '', '<r:content part="sidebar" />'
160     assert_renders 'Parent sidebar.', '<r:content part="sidebar" inherit="true" />'
161   end
162   def test_tag_content_with_global_page_propagation
163     @page = pages(:global_child)
164     assert_renders 'Global Child Global Child', '<r:content part="titles" inherit="true" contextual="true"/>'
165     assert_renders 'Global Global Child', '<r:content part="titles" inherit="true" contextual="false"/>'
166   end
167   
168   def test_tag_child_content
169     expected = "Radius test child 1 body.\nRadius test child 2 body.\nRadius test child 3 body.\n"
170     assert_renders expected, '<r:children:each><r:content /></r:children:each>'
171   end
172   
173   def test_tag_if_content_without_body_attribute
174     assert_renders 'true', '<r:if_content>true</r:if_content>'
175   end
176   def test_tag_if_content_with_body_attribute
177     assert_renders 'true', '<r:if_content part="body">true</r:if_content>'
178   end
179   def test_tag_if_content_with_nonexistant_body_attribute
180     assert_renders '', '<r:if_content part="asdf">true</r:if_content>'
181   end
182   
183   def test_tag_unless_content_without_body_attribute
184     assert_renders '', '<r:unless_content>false</r:unless_content>'
185   end
186   def test_tag_unless_content_with_body_attribute
187     assert_renders '', '<r:unless_content part="body">false</r:unless_content>'
188   end
189   def test_tag_unless_content_with_nonexistant_body_attribute
190     assert_renders 'false', '<r:unless_content part="asdf">false</r:unless_content>'
191   end
192   
193   def test_tag_author
194     assert_renders 'Admin User', '<r:author />'
195   end
196   def test_tag_author_nil
197     @page = pages(:textile)
198     assert_renders '', '<r:author />'
199   end
200   
201   def test_tag_date
202     assert_renders 'Monday, January 30, 2006', '<r:date />'
203   end
204   def test_tag_date_with_format_attribute
205     assert_renders '30 Jan 2006', '<r:date format="%d %b %Y" />'
206   end
207   def test_tag_date_now
208     assert_renders Time.now.strftime("%A, %B %d, %Y"), '<r:date for="now" />'
209   end
210   def test_tag_date_other_attributes
211     assert_renders 'Monday, January 30, 2006', '<r:date for="created_at" />'
212     assert_renders 'Tuesday, January 31, 2006', '<r:date for="updated_at" />'
213     assert_renders 'Monday, January 30, 2006', '<r:date for="published_at" />'
214     assert_render_error "Invalid value for 'for' attribute.", '<r:date for="blah" />'
215   end
216   def test_tag_date_uses_local_timezone 
217     Radiant::Config["local.timezone"] = "Tokyo"
218     format = "%H:%m"
219     expected = TimeZone["Tokyo"].adjust(@page.published_at).strftime format 
220     assert_renders expected, %Q(<r:date format="#{format}" />) 
221   end
223   def test_tag_link
224     assert_renders '<a href="/radius/">Radius Test Page</a>', '<r:link />'
225   end
226   def test_tag_link__attributes
227     expected = '<a href="/radius/" class="test" id="radius">Radius Test Page</a>'
228     assert_renders expected, '<r:link class="test" id="radius" />'
229   end
230   def test_tag_link__block_form
231     assert_renders '<a href="/radius/">Test</a>', '<r:link>Test</r:link>'
232   end
233   def test_tag_link__anchor
234     assert_renders '<a href="/radius/#test">Test</a>', '<r:link anchor="test">Test</r:link>'
235   end
236   def test_tag_child_link
237     expected = "<a href=\"/radius/child-1/\">Radius Test Child 1</a> <a href=\"/radius/child-2/\">Radius Test Child 2</a> <a href=\"/radius/child-3/\">Radius Test Child 3</a> "
238     assert_renders expected, '<r:children:each><r:link /> </r:children:each>' 
239   end
240   
241   def test_tag_snippet
242     assert_renders 'test', '<r:snippet name="first" />'
243   end
244   def test_tag_snippet_not_found
245     assert_render_error 'snippet not found', '<r:snippet name="non-existant" />'
246   end
247   def test_tag_snippet_without_name
248     assert_render_error "`snippet' tag must contain `name' attribute", '<r:snippet />'
249   end
250   def test_tag_snippet_with_markdown
251     assert_renders '<p><strong>markdown</strong></p>', '<r:page><r:snippet name="markdown" /></r:page>'
252   end
253   def test_tag_snippet_with_global_page_propagation
254     assert_renders "#{@page.title} " * @page.children.count, '<r:snippet name="global_page_cascade" />'
255   end
256   def test_tag_snippet_with_recursion_global_page_propagation
257     @page = Page.find(6)
258     assert_renders "#{@page.title}" * 2, '<r:snippet name="recursive" />'
259   end
260   
261   def test_tag_random
262     assert_render_match /^(1|2|3)$/, "<r:random> <r:option>1</r:option> <r:option>2</r:option> <r:option>3</r:option> </r:random>"
263   end
264   
265   def test_tag_comment
266     assert_renders 'just a test', 'just a <r:comment>small </r:comment>test'
267   end
268   
269   def test_tag_navigation_1
270     tags = %{<r:navigation urls="Home: Boy: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/">
271                <r:normal><a href="<r:url />"><r:title /></a></r:normal>
272                <r:here><strong><r:title /></strong></r:here>
273                <r:selected><strong><a href="<r:url />"><r:title /></a></strong></r:selected>
274                <r:between> | </r:between>
275              </r:navigation>}
276     expected = %{<strong><a href="/">Home: Boy</a></strong> | <a href="/archive/">Archives</a> | <strong>Radius</strong> | <a href="/documentation/">Docs</a>}
277     assert_renders expected, tags
278   end
279   def test_tag_navigation_2
280     tags = %{<r:navigation urls="Home: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/">
281                <r:normal><r:title /></r:normal>
282              </r:navigation>}
283     expected = %{Home Archives Radius Docs}
284     assert_renders expected, tags
285   end
286   def test_tag_navigation_3
287     tags = %{<r:navigation urls="Home: / | Archives: /archive/ | Radius: /radius/ | Docs: /documentation/">
288                <r:normal><r:title /></r:normal>
289                <r:selected><strong><r:title/></strong></r:selected>
290              </r:navigation>}
291     expected = %{<strong>Home</strong> Archives <strong>Radius</strong> Docs}
292     assert_renders expected, tags
293   end
294   def test_tag_navigation_without_urls
295     assert_renders '', %{<r:navigation><r:normal /></r:navigation>}
296   end
297   def test_tag_navigation_without_normal_tag
298     assert_render_error  "`navigation' tag must include a `normal' tag", %{<r:navigation urls="something:here"></r:navigation>}
299   end
300   def test_tag_navigation_with_urls_without_slashes
301     tags = %{<r:navigation urls="Home: | Archives: /archive | Radius: /radius | Docs: /documentation">
302                <r:normal><r:title /></r:normal>
303                <r:here><strong><r:title /></strong></r:here>
304              </r:navigation>}
305     expected = %{Home Archives <strong>Radius</strong> Docs}
306     assert_renders expected, tags
307   end
308   
309   def test_tag_find
310     assert_renders 'Ruby Home Page', %{<r:find url="/"><r:title /></r:find>}
311   end
312   def test_tag_find_without_url
313     assert_render_error "`find' tag must contain `url' attribute", %{<r:find />}
314   end
315   def test_tag_find_with_nonexistant_url
316     assert_renders '', %{<r:find url="/asdfsdf/"><r:title /></r:find>}
317   end
318   def test_tag_find_with_nonexistant_url_and_file_not_found
319     assert_renders '', %{<r:find url="/gallery/asdfsdf/"><r:title /></r:find>}
320   end
321   
322   def test_tag_find_and_children
323     assert_renders 'a-great-day-for-ruby another-great-day-for-ruby later-that-day next-year-in-ruby ', %{<r:find url="/news/"><r:children:each><r:slug /> </r:children:each></r:find>}
324   end
325   
326   def test_tag_escape_html
327     assert_renders '&lt;strong&gt;a bold move&lt;/strong&gt;', '<r:escape_html><strong>a bold move</strong></r:escape_html>'
328   end
329   
330   def test_tag_rfc1123_date
331     @page.published_at = Time.utc(2004, 5, 2)
332     assert_renders 'Sun, 02 May 2004 00:00:00 GMT', '<r:rfc1123_date />'
333   end
334   
335   def test_tag_breadcrumbs
336     @page = pages(:deep_nested_child_for_breadcrumbs)
337     assert_renders '<a href="/">Home</a> &gt; <a href="/radius/">Radius Test Page</a> &gt; <a href="/radius/child-1/">Radius Test Child 1</a> &gt; Deeply nested child',
338       '<r:breadcrumbs />'
339   end
340   def test_tag_breadcrumbs_with_separator_attribute
341     @page = pages(:deep_nested_child_for_breadcrumbs)
342     assert_renders '<a href="/">Home</a> :: <a href="/radius/">Radius Test Page</a> :: <a href="/radius/child-1/">Radius Test Child 1</a> :: Deeply nested child',
343       '<r:breadcrumbs separator=" :: " />'
344   end
345   
346   def test_tag_if_url_does_not_match
347     assert_renders '', '<r:if_url matches="fancypants">true</r:if_url>'
348   end
349   def test_tag_if_url_matches
350      assert_renders 'true', '<r:if_url matches="r.dius/$">true</r:if_url>'
351   end
352   def test_tag_if_url_without_ignore_case
353     assert_renders 'true', '<r:if_url matches="rAdius/$">true</r:if_url>'
354   end
355   def test_tag_if_url_with_ignore_case_true
356     assert_renders 'true', '<r:if_url matches="rAdius/$" ignore_case="true">true</r:if_url>'
357   end
358   def test_tag_if_url_with_ignore_case_false
359     assert_renders '', '<r:if_url matches="rAdius/$" ignore_case="false">true</r:if_url>'
360   end
361   def test_tag_if_url_with_malformatted_regexp
362     assert_render_error "Malformed regular expression in `matches' argument of `if_url' tag: unmatched (: /r(dius\\/$/", '<r:if_url matches="r(dius/$">true</r:if_url>'
363   end
364   def test_tag_if_url_empty
365     assert_render_error "`if_url' tag must contain a `matches' attribute.", '<r:if_url>test</r:if_url>'
366   end
367   
368   def test_tag_unless_url_does_not_match
369     assert_renders 'true', '<r:unless_url matches="fancypants">true</r:unless_url>'
370   end
371   def test_tag_unless_url_matches
372     assert_renders '', '<r:unless_url matches="r.dius/$">true</r:unless_url>'
373   end
374   def test_tag_unless_url_without_ignore_case
375     assert_renders '', '<r:unless_url matches="rAdius/$">true</r:unless_url>'
376   end
377   def test_tag_unless_url_with_ignore_case_true
378     assert_renders '', '<r:unless_url matches="rAdius/$" ignore_case="true">true</r:unless_url>'
379   end
380   def test_tag_unless_url_with_ignore_case_false
381     assert_renders 'true', '<r:unless_url matches="rAdius/$" ignore_case="false">true</r:unless_url>'
382   end
383   def test_tag_unless_url_with_malformatted_regexp
384     assert_render_error "Malformed regular expression in `matches' argument of `unless_url' tag: unmatched (: /r(dius\\/$/", '<r:unless_url matches="r(dius/$">true</r:unless_url>'
385   end
386   def test_tag_unless_url_empty
387     assert_render_error "`unless_url' tag must contain a `matches' attribute.", '<r:unless_url>test</r:unless_url>'
388   end
389   
390   def test_tag_cycle
391     assert_renders 'first second', '<r:cycle values="first, second" /> <r:cycle values="first, second" />'
392   end
393   def test_tag_cycle_returns_to_beginning
394     assert_renders 'first second first', '<r:cycle values="first, second" /> <r:cycle values="first, second" /> <r:cycle values="first, second" />'
395   end
396   def test_tag_cycle_default_name
397     assert_renders 'first second', '<r:cycle values="first, second" /> <r:cycle values="first, second" name="cycle" />'
398   end
399   def test_tag_cycle_keeps_separate_counters
400     assert_renders 'first one second two', '<r:cycle values="first, second" /> <r:cycle values="one, two" name="numbers" /> <r:cycle values="first, second" /> <r:cycle values="one, two" name="numbers" />'
401   end
402   def test_tag_cycle_resets_counter
403     assert_renders 'first first', '<r:cycle values="first, second" /> <r:cycle values="first, second" reset="true"/>'    
404   end
405   def test_tag_cycle_names_empty
406     assert_render_error "`cycle' tag must contain a `values' attribute.", '<r:cycle />'
407   end
408   
409   def test_tag_parent
410     assert_renders pages(:homepage).title, '<r:parent><r:title /></r:parent>'
411     assert_renders page_eachable_children(pages(:homepage)).collect(&:title).join(""), '<r:parent><r:children:each by="title"><r:title /></r:children:each></r:parent>'
412     assert_renders @page.title * @page.children.count, '<r:children:each><r:parent:title /></r:children:each>'
413   end
414   def test_tag_if_parent
415     assert_renders 'true', '<r:if_parent>true</r:if_parent>'
416     @page = pages(:homepage)
417     assert_renders '', '<r:if_parent>true</r:if_parent>'
418   end
419   def test_tag_unless_parent
420     assert_renders '', '<r:unless_parent>true</r:unless_parent>'
421     @page = pages(:homepage)
422     assert_renders 'true', '<r:unless_parent>true</r:unless_parent>'
423   end
424   
425   def test_tag_if_children
426     @page = pages(:homepage)
427     assert_renders 'true', '<r:if_children>true</r:if_children>'
428     @page = pages(:childless)
429     assert_renders '', '<r:if_children>true</r:if_children>'
430   end
431   def test_tag_unless_children
432     @page = pages(:homepage)
433     assert_renders '', '<r:unless_children>true</r:unless_children>'
434     @page = pages(:childless)
435     assert_renders 'true', '<r:unless_children>true</r:unless_children>'
436   end
437   
438   def test_if_dev
439     assert_renders '-dev-', '-<r:if_dev>dev</r:if_dev>-', nil , 'dev.site.com'
440     assert_renders '--', '-<r:if_dev>dev</r:if_dev>-'
441   end
442   def test_if_dev_on_included_page
443     assert_renders '-dev-', '-<r:find url="/devtags/"><r:content part="if_dev" /></r:find>-', nil, 'dev.site.com'
444     assert_renders '--', '-<r:find url="/devtags/"><r:content part="if_dev" /></r:find>-'
445   end
446   
447   def test_unless_dev
448     assert_renders '--', '-<r:unless_dev>not dev</r:unless_dev>-', nil, 'dev.site.com'
449     assert_renders '-not dev-', '-<r:unless_dev>not dev</r:unless_dev>-'
450   end
451   def test_unless_dev_on_included_page
452     assert_renders '--', '-<r:find url="/devtags/"><r:content part="unless_dev" /></r:find>-', nil, 'dev.site.com'
453     assert_renders '-not dev-', '-<r:find url="/devtags/"><r:content part="unless_dev" /></r:find>-'
454   end
455   
456   private
457   
458     def page_children_first_tags(attr = nil)
459       attr = ' ' + attr unless attr.nil?
460       "<r:children:first#{attr}><r:slug /></r:children:first>"
461     end
462     
463     def page_children_last_tags(attr = nil)
464       attr = ' ' + attr unless attr.nil?
465       "<r:children:last#{attr}><r:slug /></r:children:last>"
466     end
467     
468     def page_children_each_tags(attr = nil)
469       attr = ' ' + attr unless attr.nil?
470       "<r:children:each#{attr}><r:slug /> </r:children:each>"
471     end
472     
473     def page_eachable_children(page)
474       page.children.select(&:published?).reject(&:virtual)
475     end
476