74 lines
2.7 KiB
Ruby
74 lines
2.7 KiB
Ruby
module Liquid
|
|
# A Liquid file system is a way to let your templates retrieve other templates for use with the include tag.
|
|
#
|
|
# You can implement subclasses that retrieve templates from the database, from the file system using a different
|
|
# path structure, you can provide them as hard-coded inline strings, or any manner that you see fit.
|
|
#
|
|
# You can add additional instance variables, arguments, or methods as needed.
|
|
#
|
|
# Example:
|
|
#
|
|
# Liquid::Template.file_system = Liquid::LocalFileSystem.new(template_path)
|
|
# liquid = Liquid::Template.parse(template)
|
|
#
|
|
# This will parse the template with a LocalFileSystem implementation rooted at 'template_path'.
|
|
class BlankFileSystem
|
|
# Called by Liquid to retrieve a template file
|
|
def read_template_file(_template_path)
|
|
raise FileSystemError, "This liquid context does not allow includes."
|
|
end
|
|
end
|
|
|
|
# This implements an abstract file system which retrieves template files named in a manner similar to Rails partials,
|
|
# ie. with the template name prefixed with an underscore. The extension ".liquid" is also added.
|
|
#
|
|
# For security reasons, template paths are only allowed to contain letters, numbers, and underscore.
|
|
#
|
|
# Example:
|
|
#
|
|
# file_system = Liquid::LocalFileSystem.new("/some/path")
|
|
#
|
|
# file_system.full_path("mypartial") # => "/some/path/_mypartial.liquid"
|
|
# file_system.full_path("dir/mypartial") # => "/some/path/dir/_mypartial.liquid"
|
|
#
|
|
# Optionally in the second argument you can specify a custom pattern for template filenames.
|
|
# The Kernel::sprintf format specification is used.
|
|
# Default pattern is "_%s.liquid".
|
|
#
|
|
# Example:
|
|
#
|
|
# file_system = Liquid::LocalFileSystem.new("/some/path", "%s.html")
|
|
#
|
|
# file_system.full_path("index") # => "/some/path/index.html"
|
|
#
|
|
class LocalFileSystem
|
|
attr_accessor :root
|
|
|
|
def initialize(root, pattern = "_%s.liquid".freeze)
|
|
@root = root
|
|
@pattern = pattern
|
|
end
|
|
|
|
def read_template_file(template_path)
|
|
full_path = full_path(template_path)
|
|
raise FileSystemError, "No such template '#{template_path}'" unless File.exist?(full_path)
|
|
|
|
File.read(full_path)
|
|
end
|
|
|
|
def full_path(template_path)
|
|
raise FileSystemError, "Illegal template name '#{template_path}'" unless template_path =~ /\A[^.\/][a-zA-Z0-9_\/]+\z/
|
|
|
|
full_path = if template_path.include?('/'.freeze)
|
|
File.join(root, File.dirname(template_path), @pattern % File.basename(template_path))
|
|
else
|
|
File.join(root, @pattern % template_path)
|
|
end
|
|
|
|
raise FileSystemError, "Illegal template path '#{File.expand_path(full_path)}'" unless File.expand_path(full_path).start_with?(File.expand_path(root))
|
|
|
|
full_path
|
|
end
|
|
end
|
|
end
|