Merge pull request #189 from Shopify/cache_partials

Cache tokenized partial templates
This commit is contained in:
Tom Burns
2013-05-29 07:51:12 -07:00
3 changed files with 61 additions and 9 deletions
+16 -3
View File
@@ -24,8 +24,7 @@ module Liquid
end
def render(context)
source = _read_template_from_file_system(context)
partial = Liquid::Template.parse(source)
partial = load_cached_partial(context)
variable = context[@variable_name || @template_name[1..-2]]
context.stack do
@@ -46,7 +45,21 @@ module Liquid
end
private
def _read_template_from_file_system(context)
def load_cached_partial(context)
cached_partials = context.registers[:cached_partials] || {}
template_name = context[@template_name]
if cached = cached_partials[template_name]
return cached
end
source = read_template_from_file_system(context)
partial = Liquid::Template.parse(source)
cached_partials[template_name] = partial
context.registers[:cached_partials] = cached_partials
partial
end
def read_template_from_file_system(context)
file_system = context.registers[:file_system] || Liquid::Template.file_system
# make read_template_file call backwards-compatible.
+15 -3
View File
@@ -14,6 +14,17 @@ require File.dirname(__FILE__) + '/shopify/liquid'
require File.dirname(__FILE__) + '/shopify/database.rb'
class ThemeRunner
class FileSystem
def initialize(path)
@path = path
end
# Called by Liquid to retrieve a template file
def read_template_file(template_path, context)
File.read(@path + '/' + template_path + '.liquid')
end
end
# Load all templates into memory, do this now so that
# we don't profile IO.
@@ -47,7 +58,7 @@ class ThemeRunner
# Compute page_tempalte outside of profiler run, uninteresting to profiler
page_template = File.basename(template_name, File.extname(template_name))
compile_and_render(liquid, layout, assigns, page_template)
compile_and_render(liquid, layout, assigns, page_template, template_name)
end
end
@@ -74,7 +85,7 @@ class ThemeRunner
html = nil
RubyProf.resume
html = compile_and_render(liquid, layout, assigns, page_template)
html = compile_and_render(liquid, layout, assigns, page_template, template_name)
RubyProf.pause
@@ -88,10 +99,11 @@ class ThemeRunner
RubyProf.stop
end
def compile_and_render(template, layout, assigns, page_template)
def compile_and_render(template, layout, assigns, page_template, template_file)
tmpl = Liquid::Template.new
tmpl.assigns['page_title'] = 'Page title'
tmpl.assigns['template'] = page_template
tmpl.registers[:file_system] = ThemeRunner::FileSystem.new(File.dirname(template_file))
content_for_layout = tmpl.parse(template).render(assigns)
+27
View File
@@ -39,6 +39,15 @@ class OtherFileSystem
end
end
class CountingFileSystem
attr_reader :count
def read_template_file(template_path, context)
@count ||= 0
@count += 1
'from CountingFileSystem'
end
end
class IncludeTagTest < Test::Unit::TestCase
include Liquid
@@ -136,4 +145,22 @@ class IncludeTagTest < Test::Unit::TestCase
assert_equal "Product: Draft 151cm ", Template.parse("{% include template for product %}").render("template" => 'product', 'product' => { 'title' => 'Draft 151cm'})
end
def test_include_tag_caches_second_read_of_same_partial
file_system = CountingFileSystem.new
assert_equal 'from CountingFileSystemfrom CountingFileSystem',
Template.parse("{% include 'pick_a_source' %}{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
assert_equal 1, file_system.count
end
def test_include_tag_doesnt_cache_partials_across_renders
file_system = CountingFileSystem.new
assert_equal 'from CountingFileSystem',
Template.parse("{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
assert_equal 1, file_system.count
assert_equal 'from CountingFileSystem',
Template.parse("{% include 'pick_a_source' %}").render({}, :registers => {:file_system => file_system})
assert_equal 2, file_system.count
end
end # IncludeTagTest