app/liquid/liquid_file_system.rb
# frozen_string_literal: true
# The <tt>LiquidFileSystem</tt> class is used by +Liquid+ for
# retrieving partial content.
#
# Partials are rendered within template content using the +include+ tag:
#
# {% include 'post' %}
#
# The above tag is equivalent to calling:
#
# LiquidFileSystem.read_template_file('post')
#
# <tt>LiquidFileSystem</tt> will query the <tt>LiquidPartial</tt> model
# for a record with a matching +title+. If this returns nil, the
# filesystem is checked for a file with a matching name.
# Partial filenames, like Rails partials, are preceeded with a +_+,
# and end with +.liquid'.
#
# _post.liquid
#
# When developing a new partial, you can set <tt>Settings.liquid_templating_source</tt>
# to 'file'. This will force the class to always read content from file.
class LiquidFileSystem
class << self
# Returns an array of matching files.
#
# ==== Options
#
# * +title+
#
def partials(title)
filename = title.to_s.parameterize.underscore
Dir.glob([
"#{Rails.root}/app/views/plugins/**/_#{filename}.liquid",
"#{Rails.root}/app/liquid/views/partials/_#{filename}.liquid",
"#{Rails.root}/vendor/theme/templates/partials/_#{filename}.liquid"
])
end
def read_template_file(title)
return read(title) unless Settings.liquid_templating_source == 'file'
read_from_file(title)
end
private
def read(title)
read_from_store(title) || read_from_file(title) || "Partial #{title} was not found"
end
def read_from_store(title)
LiquidPartial.find_by(title: title).try(:content)
end
def read_from_file(title)
return nil if partials(title).empty?
File.read(partials(title).first)
end
end
end