Render order of YRender is the same as output order, so it can be easily modified for stream rendering.
-
-
Save baya/5924556 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# simulate template rendering | |
class Template < Struct.new(:name) | |
def render | |
puts "#{name}_begin" | |
r = "#{name}_begin\n" | |
r << yield if block_given? | |
puts "#{name}_end\n" | |
r << "#{name}_end\n" | |
end | |
end | |
def Y f | |
g = -> h, *x { f[h[h], *x] }.curry 2 | |
g[g] | |
end | |
YRender = Y -> f, n, layouts { | |
if n == 0 | |
layouts[0].render | |
else | |
layouts[n].render { f.call n - 1, layouts } | |
end | |
} | |
def render_all_y layouts | |
YRender.call (layouts.size - 1), layouts | |
end | |
def render_all_inside_out layouts | |
layouts.inject '' do |r, e| | |
e.render { r } | |
end | |
end | |
def render_all_outside_in layouts | |
outside, *inside = layouts.reverse.map do |e| | |
e.render { '<render:yield/>' } | |
end | |
inside.each do |r| | |
outside.gsub! '<render:yield/>', r | |
end | |
outside | |
end | |
def render_all_in_order layouts | |
top = layouts.pop | |
if layouts.empty? | |
top.render | |
else | |
top.render { render_all_in_order layouts } | |
end | |
end | |
layouts = -> { %w'page layout2 layout1'.map{|name| Template.new name } } | |
puts "\n== Y ==" | |
render_all_y layouts[] | |
puts "\n== inside -> outside ==" | |
render_all_inside_out layouts[] | |
puts "\n== ouside -> inside ==" | |
render_all_outside_in layouts[] | |
puts "\n== recursive in order ==" | |
render_all_in_order layouts[] |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment