first draft of the new template inheritance mechanism based on our fork of Liquid
This commit is contained in:
parent
eaf03be8d5
commit
53500bda9e
19
Gemfile
19
Gemfile
@ -3,17 +3,14 @@ source 'http://rubygems.org'
|
||||
|
||||
gem 'rails', '3.0.0.rc'
|
||||
|
||||
# gem 'liquid', '2.0.0'
|
||||
gem 'liquid', '2.1.2'
|
||||
# i think we'll need to fork our templating language
|
||||
# gem 'locomotive-liquid'
|
||||
gem 'liquid', :git => 'git://github.com/locomotivecms/liquid.git', :ref => 'a41213c77cbc81dab87d'
|
||||
|
||||
gem 'bson_ext', '>= 1.0.1'
|
||||
gem 'mongoid', :git => "git://github.com/durran/mongoid.git", :ref => "e387a0d1dc74da057472"
|
||||
gem 'mongoid', :git => 'git://github.com/durran/mongoid.git', :ref => 'e387a0d1dc74da057472'
|
||||
gem 'mongoid_acts_as_tree', '0.1.5'
|
||||
gem 'mongo_session_store', '2.0.0.pre'
|
||||
gem 'warden'
|
||||
gem 'devise', :git => "git://github.com/plataformatec/devise.git"
|
||||
gem 'devise', :git => 'git://github.com/plataformatec/devise.git'
|
||||
gem 'haml', '3.0.15'
|
||||
gem 'rmagick', '2.12.2'
|
||||
gem 'aws'
|
||||
@ -40,16 +37,16 @@ group :test, :development do
|
||||
end
|
||||
|
||||
group :test do
|
||||
gem "autotest"
|
||||
gem "growl-glue"
|
||||
gem 'autotest'
|
||||
gem 'growl-glue'
|
||||
gem 'rspec-rails', '2.0.0.beta.19'
|
||||
gem 'factory_girl_rails'
|
||||
gem "pickle", :git => "http://github.com/codegram/pickle.git"
|
||||
gem "pickle-mongoid"
|
||||
gem 'pickle', :git => 'http://github.com/codegram/pickle.git'
|
||||
gem 'pickle-mongoid'
|
||||
gem 'capybara'
|
||||
|
||||
# would be nice..
|
||||
# gem "capybara-envjs"
|
||||
# gem 'capybara-envjs'
|
||||
|
||||
gem 'database_cleaner'
|
||||
gem 'cucumber'
|
||||
|
22
Gemfile.lock
22
Gemfile.lock
@ -3,6 +3,12 @@ GIT
|
||||
revision: e387a0d
|
||||
ref: e387a0d1dc74da057472
|
||||
specs:
|
||||
mongoid (2.0.0.beta.15)
|
||||
activemodel (= 3.0.0.rc)
|
||||
bson (= 1.0.4)
|
||||
mongo (= 1.0.6)
|
||||
tzinfo (= 0.3.22)
|
||||
will_paginate (~> 3.0.pre)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/floehopper/mocha.git
|
||||
@ -11,6 +17,13 @@ GIT
|
||||
mocha (0.9.8.20090918115329)
|
||||
rake
|
||||
|
||||
GIT
|
||||
remote: git://github.com/locomotivecms/liquid.git
|
||||
revision: a41213c
|
||||
ref: a41213c77cbc81dab87d
|
||||
specs:
|
||||
liquid (2.1.3)
|
||||
|
||||
GIT
|
||||
remote: git://github.com/plataformatec/devise.git
|
||||
revision: 01c272c
|
||||
@ -133,7 +146,6 @@ GEM
|
||||
configuration (>= 0.0.5)
|
||||
rake (>= 0.8.1)
|
||||
linecache (0.43)
|
||||
liquid (2.1.2)
|
||||
mail (2.2.5)
|
||||
activesupport (>= 2.3.6)
|
||||
mime-types
|
||||
@ -144,12 +156,6 @@ GEM
|
||||
bson (>= 1.0.4)
|
||||
mongo_session_store (2.0.0.pre)
|
||||
actionpack (~> 3.0)
|
||||
mongoid (2.0.0.beta.15)
|
||||
activemodel (= 3.0.0.rc)
|
||||
bson (= 1.0.4)
|
||||
mongo (= 1.0.6)
|
||||
tzinfo (= 0.3.22)
|
||||
will_paginate (~> 3.0.pre)
|
||||
mongoid_acts_as_tree (0.1.5)
|
||||
bson (>= 0.20.1)
|
||||
mongoid (<= 2.0.0)
|
||||
@ -252,7 +258,7 @@ DEPENDENCIES
|
||||
inherited_resources (= 1.1.2)
|
||||
jeweler
|
||||
launchy
|
||||
liquid (= 2.1.2)
|
||||
liquid!
|
||||
mimetype-fu
|
||||
mocha!
|
||||
mongo_session_store (= 2.0.0.pre)
|
||||
|
@ -1,5 +1,8 @@
|
||||
# @deprecated
|
||||
class Layout < LiquidTemplate
|
||||
|
||||
# acts_as_tree
|
||||
|
||||
protected
|
||||
|
||||
# TODO: move that in the liquify_template module
|
||||
|
@ -67,7 +67,7 @@ class Page
|
||||
self.slug
|
||||
else
|
||||
slugs = self.self_and_ancestors.map(&:slug)
|
||||
slugs.shift
|
||||
slugs.shift unless slugs.size == 1
|
||||
File.join slugs
|
||||
end
|
||||
end
|
||||
|
@ -1,6 +1,6 @@
|
||||
%ul
|
||||
= admin_submenu_item 'site', edit_admin_current_site_url
|
||||
= admin_submenu_item 'layouts', admin_layouts_url
|
||||
/ = admin_submenu_item 'layouts', admin_layouts_url
|
||||
= admin_submenu_item 'snippets', admin_snippets_url
|
||||
= admin_submenu_item 'theme_assets', admin_theme_assets_url
|
||||
= admin_submenu_item 'account', edit_admin_my_account_url
|
@ -8,7 +8,7 @@ Background:
|
||||
Given I have the site: "test site" set up
|
||||
|
||||
Scenario: Liquid Inheritance with a single block
|
||||
Given a layout named "above_and_below" with the source:
|
||||
Given a page named "above-and-below" with the template:
|
||||
"""
|
||||
<div class="header"></div>
|
||||
<div class="body">
|
||||
@ -19,7 +19,7 @@ Scenario: Liquid Inheritance with a single block
|
||||
|
||||
And a page named "hello-world-with-layout" with the template:
|
||||
"""
|
||||
{% extends 'above_and_below' %}
|
||||
{% extends 'above-and-below' %}
|
||||
{% block body %}Hello World{% endblock %}
|
||||
"""
|
||||
|
||||
@ -34,7 +34,7 @@ Scenario: Liquid Inheritance with a single block
|
||||
"""
|
||||
|
||||
Scenario: Liquid Inheritance with multiple blocks
|
||||
Given a layout named "layout_with_sidebar" with the source:
|
||||
Given a page named "layout-with-sidebar" with the template:
|
||||
"""
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
@ -49,7 +49,7 @@ Scenario: Liquid Inheritance with multiple blocks
|
||||
"""
|
||||
And a page named "hello-world-multiblocks" with the template:
|
||||
"""
|
||||
{% extends 'layout_with_sidebar' %}
|
||||
{% extends 'layout-with-sidebar' %}
|
||||
{% block body %}Hello world{% endblock %}
|
||||
"""
|
||||
When I view the rendered page at "/hello-world-multiblocks"
|
||||
@ -68,7 +68,7 @@ Scenario: Liquid Inheritance with multiple blocks
|
||||
"""
|
||||
|
||||
Scenario: Multiple inheritance (layout extending another layout)
|
||||
Given a layout named "layout_with_sidebar" with the source:
|
||||
Given a page named "layout-with-sidebar" with the template:
|
||||
"""
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
@ -79,15 +79,15 @@ Scenario: Multiple inheritance (layout extending another layout)
|
||||
</div>
|
||||
<div class="footer"></div>
|
||||
"""
|
||||
And a layout named "custom_layout_with_sidebar" with the source:
|
||||
And a page named "custom-layout-with-sidebar" with the template:
|
||||
"""
|
||||
{% extends 'layout_with_sidebar' %}
|
||||
{% extends 'layout-with-sidebar' %}
|
||||
{% block sidebar %}Custom sidebar{% endblock %}
|
||||
{% block body %}Hello{% endblock %}
|
||||
"""
|
||||
And a page named "hello-world-multiblocks" with the template:
|
||||
"""
|
||||
{% extends 'custom_layout_with_sidebar' %}
|
||||
{% extends 'custom-layout-with-sidebar' %}
|
||||
{% block body %}{{ block.super }} world{% endblock %}
|
||||
"""
|
||||
When I view the rendered page at "/hello-world-multiblocks"
|
||||
@ -103,9 +103,8 @@ Scenario: Multiple inheritance (layout extending another layout)
|
||||
<div class="footer"></div>
|
||||
"""
|
||||
|
||||
|
||||
Scenario: Page extending a layout with multiple embedded blocks which extends another template
|
||||
Given a layout named "layout_with_sidebar" with the source:
|
||||
Given a page named "layout-with-sidebar" with the template:
|
||||
"""
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
@ -116,14 +115,14 @@ Scenario: Page extending a layout with multiple embedded blocks which extends an
|
||||
</div>
|
||||
<div class="footer"></div>
|
||||
"""
|
||||
And a layout named "custom_layout_with_sidebar" with the source:
|
||||
And a page named "custom-layout-with-sidebar" with the template:
|
||||
"""
|
||||
{% extends 'layout_with_sidebar' %}
|
||||
{% extends 'layout-with-sidebar' %}
|
||||
{% block body %}{{ block.super }} {% block main %}mister{% endblock %}{% endblock %}
|
||||
"""
|
||||
And a page named "hello-world-multiblocks" with the template:
|
||||
"""
|
||||
{% extends 'custom_layout_with_sidebar' %}
|
||||
{% extends 'custom-layout-with-sidebar' %}
|
||||
{% block main %}{{ block.super }} Jacques{% endblock %}
|
||||
"""
|
||||
When I view the rendered page at "/hello-world-multiblocks"
|
||||
|
@ -1,16 +0,0 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Drops
|
||||
class Block < ::Liquid::Drop
|
||||
|
||||
def initialize(block)
|
||||
@block = block
|
||||
end
|
||||
|
||||
def super
|
||||
@block.call_super(@context)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
@ -44,7 +44,11 @@ module Locomotive
|
||||
|
||||
def store_template
|
||||
begin
|
||||
@template = ::Liquid::Template.parse(self.liquify_template_source)
|
||||
# puts "self.liquify_template_source = #{self.liquify_template_source.inspect}"
|
||||
@template = ::Liquid::Template.parse(self.liquify_template_source, { :site => self.site })
|
||||
@template.root.context.clear
|
||||
# puts "@template = #{@template.inspect}"
|
||||
# @template = Locomotive::Liquid::Template.parse(self)
|
||||
|
||||
if self.respond_to?(:after_parse_template) # kind of callback
|
||||
self.send(:after_parse_template)
|
||||
|
@ -1,50 +0,0 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Tags
|
||||
class Block < ::Liquid::Block
|
||||
Syntax = /(\w+)/
|
||||
|
||||
attr_accessor :parent
|
||||
attr_reader :name
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
if markup =~ Syntax
|
||||
@name = $1
|
||||
else
|
||||
raise ::Liquid::SyntaxError.new("Syntax Error in 'block' - Valid syntax: block [name]")
|
||||
end
|
||||
|
||||
super if tokens
|
||||
end
|
||||
|
||||
def render(context)
|
||||
context.stack do
|
||||
context['block'] = Locomotive::Liquid::Drops::Block.new(self)
|
||||
|
||||
render_all(@nodelist, context)
|
||||
end
|
||||
end
|
||||
|
||||
def add_parent(nodelist)
|
||||
if parent
|
||||
parent.add_parent(nodelist)
|
||||
else
|
||||
self.parent = self.class.new(@tag_name, @name, nil)
|
||||
parent.nodelist = nodelist
|
||||
end
|
||||
end
|
||||
|
||||
def call_super(context)
|
||||
if parent
|
||||
parent.render(context)
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
::Liquid::Template.register_tag('block', Block)
|
||||
end
|
||||
end
|
||||
end
|
@ -15,7 +15,7 @@ module Locomotive
|
||||
|
||||
Syntax = /(#{::Liquid::VariableSignature}+)\s*from\s*(#{::Liquid::QuotedString}+)/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
def initialize(tag_name, markup, tokens, context)
|
||||
if markup =~ Syntax
|
||||
@target = $1
|
||||
@url = $2.gsub(/['"]/, '')
|
||||
|
@ -1,83 +1,26 @@
|
||||
module Locomotive
|
||||
module Liquid
|
||||
module Tags
|
||||
class Extends < ::Liquid::Block
|
||||
Syntax = /(#{::Liquid::QuotedFragment})/
|
||||
class Extends < ::Liquid::Extends
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
if markup =~ Syntax
|
||||
@template_name = $1
|
||||
else
|
||||
raise ::Liquid::SyntaxError.new("Syntax Error in 'extends' - Valid syntax: extends [template]")
|
||||
class PageNotFound < ::Liquid::Error; end
|
||||
|
||||
def parse_parent_template(context)
|
||||
page = context[:site].pages.where(:fullpath => @template_name.gsub("'", '')).first
|
||||
|
||||
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if page.nil?
|
||||
|
||||
template = page.template
|
||||
|
||||
# merge blocks ?
|
||||
blocks = find_blocks(template.root.nodelist)
|
||||
|
||||
blocks.each_value do |block|
|
||||
block.send(:instance_variable_set, :"@context", context)
|
||||
block.end_tag
|
||||
end
|
||||
|
||||
super
|
||||
|
||||
@blocks = @nodelist.inject({}) do |m, node|
|
||||
m[node.name] = node if node.is_a?(Locomotive::Liquid::Tags::Block); m
|
||||
end
|
||||
end
|
||||
|
||||
def parse(tokens)
|
||||
parse_all(tokens)
|
||||
end
|
||||
|
||||
def render(context)
|
||||
template, parent_blocks = load_template(context)
|
||||
|
||||
@blocks.each do |name, block|
|
||||
if pb = parent_blocks[name]
|
||||
pb.parent = block.parent
|
||||
pb.add_parent(pb.nodelist)
|
||||
pb.nodelist = block.nodelist
|
||||
else
|
||||
if is_extending?(template)
|
||||
template.root.nodelist << block
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
template.render(context)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def parse_all(tokens)
|
||||
@nodelist ||= []
|
||||
@nodelist.clear
|
||||
|
||||
while token = tokens.shift
|
||||
case token
|
||||
when /^#{::Liquid::TagStart}/
|
||||
if token =~ /^#{::Liquid::TagStart}\s*(\w+)\s*(.*)?#{::Liquid::TagEnd}$/
|
||||
# fetch the tag from registered blocks
|
||||
if tag = ::Liquid::Template.tags[$1]
|
||||
@nodelist << tag.new($1, $2, tokens)
|
||||
else
|
||||
# this tag is not registered with the system
|
||||
# pass it to the current block for special handling or error reporting
|
||||
unknown_tag($1, $2, tokens)
|
||||
end
|
||||
else
|
||||
raise ::Liquid::SyntaxError, "Tag '#{token}' was not properly terminated with regexp: #{TagEnd.inspect} "
|
||||
end
|
||||
when /^#{::Liquid::VariableStart}/
|
||||
@nodelist << create_variable(token)
|
||||
when ''
|
||||
# pass
|
||||
else
|
||||
@nodelist << token
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def load_template(context)
|
||||
layout = context.registers[:site].layouts.where(:slug => context[@template_name]).first
|
||||
[layout.template, layout.template.send(:instance_variable_get, :"@parent_blocks")]
|
||||
end
|
||||
|
||||
def is_extending?(template)
|
||||
template.root.nodelist.any? { |node| node.is_a?(Extends) }
|
||||
template
|
||||
end
|
||||
|
||||
end
|
||||
|
@ -12,7 +12,7 @@ module Locomotive
|
||||
|
||||
Syntax = /(#{::Liquid::Expression}+)?/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
def initialize(tag_name, markup, tokens, context)
|
||||
if markup =~ Syntax
|
||||
@site_or_page = $1 || 'page'
|
||||
@options = {}
|
||||
|
@ -19,7 +19,7 @@ module Locomotive
|
||||
|
||||
Syntax = /(#{::Liquid::Expression}+)\s+by\s+([0-9]+)/
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
def initialize(tag_name, markup, tokens, context)
|
||||
if markup =~ Syntax
|
||||
@collection_name = $1
|
||||
@per_page = $2.to_i
|
||||
|
@ -3,7 +3,7 @@ module Locomotive
|
||||
module Tags
|
||||
class WithScope < ::Liquid::Block
|
||||
|
||||
def initialize(tag_name, markup, tokens)
|
||||
def initialize(tag_name, markup, tokens, context)
|
||||
@attributes = {}
|
||||
markup.scan(::Liquid::TagAttributes) do |key, value|
|
||||
@attributes[key] = value
|
||||
|
@ -7,21 +7,21 @@ require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_
|
||||
Mongoid.master.collection(collection).drop
|
||||
end
|
||||
|
||||
puts "Starting benchmark..."
|
||||
puts "Starting test..."
|
||||
|
||||
site = Site.create :name => 'Benchmark Website', :subdomain => 'benchmark'
|
||||
|
||||
layout_with_sidebar = site.layouts.create :name => 'with_sidebar', :value => %{
|
||||
simple = site.pages.create :title => 'Simple', :slug => 'simple', :layout_template => %{
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
<div class="sidebar">
|
||||
{% block sidebar %}DEFAULT SIDEBAR CONTENT{% endblock %}
|
||||
A sidebar here / INDEX sidebar
|
||||
</div>
|
||||
<div class="body">
|
||||
{% block body %}DEFAULT BODY CONTENT{% endblock %}
|
||||
<div class="wrapper">Lorem ipsum</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer"></div>
|
||||
@ -29,24 +29,48 @@ layout_with_sidebar = site.layouts.create :name => 'with_sidebar', :value => %{
|
||||
</html>
|
||||
}
|
||||
|
||||
custom_layout_with_sidebar = site.layouts.create :name => 'custom_with_sidebar', :value => %{
|
||||
\{% extends 'with_sidebar' %\}
|
||||
\{% block sidebar %\}A sidebar here\{% endblock %\}
|
||||
\{% block body %\}<div class="wrapper">\{% block main %\}DEFAULT MAIN CONTENT\{% endblock %\}</div>\{% endblock %\}
|
||||
base = site.pages.create :title => 'Base page', :slug => 'base', :layout_template => %{
|
||||
<html>
|
||||
<head></head>
|
||||
<body>
|
||||
<div class="header"></div>
|
||||
<div class="content">
|
||||
<div class="sidebar">
|
||||
{% block sidebar %}My simple sidebar{% endblock %}
|
||||
</div>
|
||||
<div class="body">
|
||||
{% block body %}Just to say hi{% endblock %}
|
||||
</div>
|
||||
</div>
|
||||
<div class="footer"></div>
|
||||
</body>
|
||||
</html>
|
||||
}
|
||||
|
||||
page = site.pages.create :title => 'Benchmark', :slug => 'benchmark', :layout_template => %{
|
||||
\{% extends 'custom_with_sidebar' %\}
|
||||
\{% block sidebar %\}\{\{ block.super \}\} / INDEX sidebar\{% endblock %\}
|
||||
\{% block main %\}Lorem ipsum\{% endblock %\}
|
||||
page_1 = site.pages.create :title => 'Page 1', :slug => 'page_1', :layout_template => %{
|
||||
{% extends base %}
|
||||
{% block sidebar %}A sidebar here{% endblock %}
|
||||
{% block body %}<div class="wrapper">{% block main %}DEFAULT MAIN CONTENT{% endblock %}</div>{% endblock %}
|
||||
}
|
||||
|
||||
page_2 = site.pages.create :title => 'Page 2', :slug => 'page_2', :layout_template => %{
|
||||
{% extends page_1 %}
|
||||
{% block sidebar %}{{ block.super }} / INDEX sidebar{% endblock %}
|
||||
{% block main %}Lorem ipsum{% endblock %}
|
||||
}
|
||||
|
||||
puts "OUTPUT = #{page_2.render(Liquid::Context.new)}"
|
||||
|
||||
context = Liquid::Context.new({}, { 'site' => site }, { :site => site })
|
||||
|
||||
puts "====> OUTPUT \n#{page.render(context)}"
|
||||
|
||||
Benchmark.bm do |bm|
|
||||
bm.report("Rendering page 10k times") do
|
||||
bm.report("Rendering a simple page 10k times") do
|
||||
10000.times do
|
||||
Page.where(:title => 'Simple').first.render(context)
|
||||
end
|
||||
end
|
||||
|
||||
bm.report("Rendering a complex page 10k times") do
|
||||
10000.times do
|
||||
Page.last.render(context)
|
||||
end
|
||||
@ -54,10 +78,13 @@ Benchmark.bm do |bm|
|
||||
end
|
||||
|
||||
# # empty page (imac 27'): User System Total Real
|
||||
# # Rendering page 10k times 13.390000 1.700000 15.090000 ( 15.654966)
|
||||
# Rendering page 10k times 21.390000 1.820000 23.210000 ( 24.120529)
|
||||
|
||||
# # page with inherited template (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 85.840000 7.600000 93.440000 ( 97.841248)
|
||||
|
||||
# # with optimization (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 84.240000 7.280000 91.520000 ( 95.475565)
|
||||
# Rendering page 10k times 84.240000 7.280000 91.520000 ( 95.475565)
|
||||
|
||||
# # with locomotive liquid (imac 27'): User System Total Real
|
||||
# Rendering page 10k times 38.750000 3.050000 41.800000 ( 42.880022)
|
||||
|
Loading…
Reference in New Issue
Block a user