12
votes

I'm trying to render a liquid template within a liquid layout (Liquid Template lang, not CSS liquid layout stuff). I can't seem to get the layout part to render. Currently using:

assigns = {'page_name' => 'test'}
@layout = Liquid::Template.parse(File.new(@theme.layout.path).read)
@template = Liquid::Template.parse(File.new(self.template.path).read)

@rend_temp = @template.render(assigns)
@rend_layout = @layout.render({'content_for_layout' => @rend_temp})

render :text => @rend_layout, :content_type => :html

The resulting HTML of the page shows that the 'template' rendered in liquid fine, but it isn't wrapped with the layout (replacing 'content_for_layout' in the layout with the rendered template)

2

2 Answers

9
votes

Just to let anyone else know who comes across this problem, the code posted above actually does work, the issue is with the variable named @template. I renamed @template, and @layout to @_tempalte, and @_layout and everything works as expected.

2
votes

For using liquid in ruby on rails (especially rails 3) - I believe the proper way to render your liquid templates (and also maintain all the work rails is doing for you) is as follows...

The liquid gem itself provides a liquid_view for rails so you can wire up the rails to look for "liquid" templates when you call #render. This liquid_view only works fully with rails 2.3 but can easily be updated to work with rails 3 by making the following update

if content_for_layout = @view.instance_variable_get("@content_for_layout")
  assigns['content_for_layout'] = content_for_layout
elsif @view.content_for?(:layout)
  assigns["content_for_layout"] = @view.content_for(:layout)
end
assigns.merge!(local_assigns.stringify_keys)

This can be seen here --> https://github.com/danshultz/liquid/commit/e27b5fcd174f4b3916a73b9866e44ac0a012b182

Then to properly render your liquid view just call

render :template => "index", :layout => "my_layout", :locals => { liquid_drop1 => drop, liquid_drop2 => drop }

In our application, since we have a handful of common liquid attributes we have overriden the "render" method in our base controller to automatically include the default locals by referencing #liquid_view_assigns which roll up additionally added liquid drops for the render call

def render(...)
  options[:locals] = options.fetch(:locals, {}).merge(liquid_view_assigns)
  super
end