add some tests for the editable_elements feature + fix bugs

This commit is contained in:
dinedine 2010-08-26 13:06:44 +02:00
parent be36c85e90
commit eea6d4f8ce
10 changed files with 100 additions and 47 deletions

View File

@ -3,7 +3,7 @@ source 'http://rubygems.org'
gem 'rails', '3.0.0.rc' gem 'rails', '3.0.0.rc'
gem 'liquid', :git => 'git://github.com/locomotivecms/liquid.git', :ref => 'dbcc0b1d9c189b3e3a13' gem 'liquid', :git => 'git://github.com/locomotivecms/liquid.git', :ref => 'f299f8b7ff6ea102bfb3'
gem 'bson_ext', '>= 1.0.1' gem 'bson_ext', '>= 1.0.1'
gem 'mongoid', '2.0.0.beta.16' gem 'mongoid', '2.0.0.beta.16'

View File

@ -13,14 +13,14 @@ GIT
GIT GIT
remote: git://github.com/locomotivecms/liquid.git remote: git://github.com/locomotivecms/liquid.git
revision: dbcc0b1 revision: f299f8b
ref: dbcc0b1d9c189b3e3a13 ref: f299f8b7ff6ea102bfb3
specs: specs:
liquid (2.1.3) liquid (2.1.3)
GIT GIT
remote: git://github.com/plataformatec/devise.git remote: git://github.com/plataformatec/devise.git
revision: 219c05c revision: c6002bb
specs: specs:
devise (1.2.0) devise (1.2.0)
bcrypt-ruby (~> 2.1.2) bcrypt-ruby (~> 2.1.2)

View File

@ -11,6 +11,10 @@ module Models
module InstanceMethods module InstanceMethods
def editable_elements_grouped_by_blocks
self.editable_elements.group_by(&:block)
end
def find_editable_element(block, slug) def find_editable_element(block, slug)
self.editable_elements.detect { |el| el.block == block && el.slug == slug } self.editable_elements.detect { |el| el.block == block && el.slug == slug }
end end

View File

@ -56,65 +56,58 @@ module Models
default_context = { :site => self.site, :page => self, :templates => [], :snippets => [] } default_context = { :site => self.site, :page => self, :templates => [], :snippets => [] }
@template = ::Liquid::Template.parse(self.raw_template, default_context.merge(context)) context = default_context.merge(context)
# puts "*** enter context = #{context.object_id}"
@template = ::Liquid::Template.parse(self.raw_template, context)
# puts "*** exit context = #{context.object_id}"
self.template_dependencies = context[:templates] self.template_dependencies = context[:templates]
self.snippet_dependencies = context[:snippets] self.snippet_dependencies = context[:snippets]
# puts "*** [#{self.fullpath}] template_dependencies = #{self.template_dependencies.inspect}"
@template.root.context.clear @template.root.context.clear
#
# dependencies = all_dependencies(@template.root, { :templates => [], :snippets => [] })
#
# self.template_dependencies = dependencies[:templates]
# self.snippet_dependencies = dependencies[:snippets]
end end
def template_must_be_valid def template_must_be_valid
@parsing_errors.try(:each) { |msg| self.errors.add :template, msg } @parsing_errors.try(:each) { |msg| self.errors.add :template, msg }
end end
# def all_dependencies(node, dependencies = {})
# case node
# when Locomotive::Liquid::Tags::Extends
# dependencies[:templates] << node.page_id
# when Locomotive::Liquid::Tags::Snippet
# dependencies[:snippets] << node.slug
# end
#
# if node.respond_to?(:nodelist) && node.nodelist
# node.nodelist.each do |child|
# self.all_dependencies(child, dependencies)
# end
# end
#
# dependencies
# end
def update_template_descendants def update_template_descendants
return unless @template_changed == true return unless @template_changed == true
# we admit at this point that the current template is up-to-date # we admit at this point that the current template is up-to-date
descendants = self.site.pages.any_in(:template_dependencies => [self.id]).to_a template_descendants = self.site.pages.any_in(:template_dependencies => [self.id]).to_a
# group them by fullpath for better performance # group them by fullpath for better performance
cached = descendants.inject({}) { |memo, page| memo[page.fullpath] = page; memo } cached = template_descendants.inject({}) { |memo, page| memo[page.fullpath] = page; memo }
self._update_direct_template_descendants(descendants, cached) # puts "*** [#{self.fullpath}] #{template_descendants.collect(&:fullpath).inspect}"
self._update_direct_template_descendants(template_descendants, cached)
# finally save them all # finally save them all
descendants.map(&:save) template_descendants.map(&:save)
# puts "** first descendant = #{descendants.first.object_id} / #{descendants.first.template.inspect}" # puts "** first descendant = #{descendants.first.object_id} / #{descendants.first.template.inspect}"
end end
def _update_direct_template_descendants(descendants, cached) def _update_direct_template_descendants(template_descendants, cached)
direct_descendants = descendants.select do |page| # puts "*** [#{self.fullpath}] _update_direct_template_descendants"
(page.template_dependencies - self.template_dependencies).size == 1 direct_descendants = template_descendants.select do |page|
# puts "*** \t\t[#{self.fullpath}] _update_direct_template_descendants (#{page.template_dependencies.inspect})"
((page.template_dependencies || [])- (self.template_dependencies || [])).size == 1
end end
# puts "*** [#{self.fullpath}] direct = #{direct_descendants.inspect}"
direct_descendants.each do |page| direct_descendants.each do |page|
page.send(:_parse_and_serialize_template, { :cached_parent => self, :cached_pages => cached }) page.send(:_parse_and_serialize_template, { :cached_parent => self, :cached_pages => cached })
page.send(:_update_direct_template_descendants, descendants, cached) page.send(:_update_direct_template_descendants, template_descendants, cached)
end end
end end

View File

@ -21,7 +21,7 @@ Scenario: Modified short text element
""" """
My application says {% editable_short_text 'a_sentence', hint: 'please enter a new sentence' %}Hello world{% endeditable_short_text %} My application says {% editable_short_text 'a_sentence', hint: 'please enter a new sentence' %}Hello world{% endeditable_short_text %}
""" """
And the editable element "a_sentence" with the content "Bonjour" in the "hello-world" page And the editable element "a_sentence" in the "hello-world" page with the content "Bonjour"
When I view the rendered page at "/hello-world" When I view the rendered page at "/hello-world"
Then the rendered output should look like: Then the rendered output should look like:
""" """
@ -52,4 +52,20 @@ Scenario: Not modified short text element inside a block and with page inheritan
Then the rendered output should look like: Then the rendered output should look like:
""" """
My application says Hello world My application says Hello world
"""
Scenario: Modified short text element inside a block and with page inheritance
Given a page named "hello-world" with the template:
"""
{% block main %}My application says {% editable_short_text 'a_sentence' %}Hello world{% endeditable_short_text %}{% endblock %}
"""
Given a page named "another-hello-world" with the template:
"""
{% extends hello-world %}
"""
And the editable element "a_sentence" for the "main" block in the "another-hello-world" page with the content "Bonjour"
When I view the rendered page at "/another-hello-world"
Then the rendered output should look like:
"""
My application says Bonjour
""" """

View File

@ -16,13 +16,11 @@ Scenario: Liquid Inheritance with a single block
</div> </div>
<div class="footer"></div> <div class="footer"></div>
""" """
And a page named "hello-world-with-layout" with the template: And a page named "hello-world-with-layout" with the template:
""" """
{% extends 'above-and-below' %} {% extends 'above-and-below' %}
{% block body %}Hello World{% endblock %} {% block body %}Hello World{% endblock %}
""" """
When I view the rendered page at "/hello-world-with-layout" When I view the rendered page at "/hello-world-with-layout"
Then the rendered output should look like: Then the rendered output should look like:
""" """
@ -33,6 +31,26 @@ Scenario: Liquid Inheritance with a single block
<div class="footer"></div> <div class="footer"></div>
""" """
Scenario: Update a parent page and see modifications in descendants
Given a page named "base" with the template:
"""
My application say: {% block something %}Lorem ipsum{% endblock %}
"""
And a page named "hello-world" with the template:
"""
{% extends 'base' %}
{% block something %}Hello World{% endblock %}
"""
When I update the "base" page with the template:
"""
My application says: {% block something %}Lorem ipsum{% endblock %}
"""
When I view the rendered page at "/hello-world"
Then the rendered output should look like:
"""
My application says: Hello World
"""
Scenario: Liquid Inheritance with multiple blocks Scenario: Liquid Inheritance with multiple blocks
Given a page named "layout-with-sidebar" with the template: Given a page named "layout-with-sidebar" with the template:
""" """

View File

@ -3,8 +3,15 @@ Given /^a simple page named "([^"]*)" with the body:$/ do |page_slug, page_conte
end end
# modify an editable element # modify an editable element
Given /^the editable element "([^"]*)" with the content "([^"]*)" in the "([^"]*)" page$/ do |slug, content, page_slug| Given /^the editable element "([^"]*)" in the "([^"]*)" page with the content "([^"]*)"$/ do |slug, page_slug, content|
page = @site.pages.where(:slug => page_slug).first page = @site.pages.where(:slug => page_slug).first
page.find_editable_element(nil, slug).content = content page.find_editable_element(nil, slug).content = content
page.save! page.save!
end
# modify an editable element
Given /^the editable element "([^"]*)" for the "([^"]*)" block in the "([^"]*)" page with the content "([^"]*)"$/ do |slug, block, page_slug, content|
page = @site.pages.where(:slug => page_slug).first
page.find_editable_element(block, slug).content = content
page.save!
end end

View File

@ -36,6 +36,14 @@ end
# page.save # page.save
# end # end
# update a page
When /^I update the "([^"]*)" page with the template:$/ do |page_slug, template|
puts "*************"
page = @site.pages.where(:slug => page_slug).first
page.update_attributes :raw_template => template
end
# try to render a page by slug # try to render a page by slug
When /^I view the rendered page at "([^"]*)"$/ do |path| When /^I view the rendered page at "([^"]*)"$/ do |path|
visit "http://#{@site.domains.first}#{path}" visit "http://#{@site.domains.first}#{path}"

View File

@ -16,7 +16,7 @@ module Locomotive
super super
puts "@nodelist = #{@nodelist.inspect}" # puts "@nodelist = #{@nodelist.inspect}"
@context[:page].add_or_update_editable_element({ @context[:page].add_or_update_editable_element({
:block => @context[:current_block].try(:name), :block => @context[:current_block].try(:name),
@ -29,7 +29,7 @@ module Locomotive
def render(context) def render(context)
current_page = context.registers[:page] current_page = context.registers[:page]
puts "[EditableShortText] rendering #{context['block'].inspect} / #{current_page.editable_elements.inspect}" # puts "[EditableShortText] rendering #{current_page.editable_elements.inspect}"
element = current_page.find_editable_element(context['block'].try(:name), @slug) element = current_page.find_editable_element(context['block'].try(:name), @slug)

View File

@ -7,17 +7,21 @@ module Locomotive
def initialize(tag_name, markup, tokens, context) def initialize(tag_name, markup, tokens, context)
if markup =~ Syntax if markup =~ Syntax
@template_name = $1 @template_name = $1.gsub('\'', '').strip
else else
raise SyntaxError.new("Error in tag 'extends' - Valid syntax: extends [template]") raise SyntaxError.new("Error in tag 'extends' - Valid syntax: extends [template]")
end end
@context = context
retrieve_parent_page retrieve_parent_page
# before parsing the embedded tokens, get editable elements from parent page # before parsing the embedded tokens, get editable elements from parent page
@context[:page].merge_editable_elements_from_page(@context[:parent_page]) @context[:page].merge_editable_elements_from_page(@context[:parent_page])
super super
# puts "** after extends, @context[:templates] = #{@context[:templates].inspect}"
end end
private private
@ -36,7 +40,9 @@ module Locomotive
end end
@context[:snippets] = page.snippet_dependencies @context[:snippets] = page.snippet_dependencies
@context[:templates] = [*page.template_dependencies] + [@page_id] @context[:templates] = ([*page.template_dependencies] + [@page_id]).compact
# puts "@context[:templates] = #{[*page.template_dependencies].inspect} + #{[@page_id].inspect} = #{@context[:templates].inspect}"
template template
end end
@ -44,19 +50,20 @@ module Locomotive
def retrieve_parent_page def retrieve_parent_page
if @template_name == 'parent' if @template_name == 'parent'
if @context[:cached_parent] if @context[:cached_parent]
@context[:parent] = @context[:cached_parent] @context[:parent_page] = @context[:cached_parent]
@context[:cached_parent] = nil @context[:cached_parent] = nil
else else
@context[:parent_page] = @context[:page].parent @context[:parent_page] = @context[:page].parent
end end
else else
path = @template_name.gsub("'", '') @context[:parent_page] = @context[:cached_pages].try(:[], @template_name) ||
@context[:parent_page] = @context[:cached_pages].try(:[], path) || @context[:site].pages.where(:fullpath => @template_name).first
@context[:site].pages.where(:fullpath => path).first
end end
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil? raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if @context[:parent_page].nil?
# puts "** @page_id = #{@context[:parent_page].id}"
@page_id = @context[:parent_page].id @page_id = @context[:parent_page].id
end end