Skip to content

Instantly share code, notes, and snippets.

@baya
Forked from luikore/1-y_render.rb
Created July 4, 2013 02:49
Show Gist options
  • Save baya/5924556 to your computer and use it in GitHub Desktop.
Save baya/5924556 to your computer and use it in GitHub Desktop.
# 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[]

Render order of YRender is the same as output order, so it can be easily modified for stream rendering.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment