1 minute read

I started a side project recently for hosting many sites from within one application. I decided to use Liquid to allow users to create their own site designs. Shopify designed Liquid to give users design freedom without compromising server integrity.

In the Rails app, I have a Theme and a Template model. A theme has many templates, and templates contain the Liquid markup in a content attribute. A theme has a primary template. To render a theme, we use liquid_template = Liquid::Template.parse(primary_template.content) to parse the Liquid content. This call is cacheable and so it is in the app.

After we parse the primary template, we render it with liquid_template.render(options, registers: {file_system: LiquidTemplateSystem.new(self)}). The LiquidTemplateSystem is a class I wrote to handle the nested template functionality. The goal is to call {{% include 'subtemplate' %}} inside one template to render another template’s content.

1
2
3
4
5
6
7
8
9
10
class LiquidTemplateSystem
  attr_reader :theme
  def initialize(theme)
    @theme = theme
  end

  def read_template_file(template_path, context)
    theme.templates.where(name: template_path).first.content
  end
end

The initializer just stores the theme that the we initialize the class with. Our file_system instance responds to the method read_template_file to handle the actual include call. read_template_file can accept one or two arguments (take two!). read_template_file must return a valid Liquid string that will render into the including template.

Tags:

Categories:

Updated: