diff --git a/Gemfile b/Gemfile index 9a90b211..fca8ca4d 100644 --- a/Gemfile +++ b/Gemfile @@ -3,7 +3,7 @@ source 'http://rubygems.org' 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 'mongoid', '2.0.0.beta.16' diff --git a/Gemfile.lock b/Gemfile.lock index 1650aa64..aad473d8 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -13,14 +13,14 @@ GIT GIT remote: git://github.com/locomotivecms/liquid.git - revision: dbcc0b1 - ref: dbcc0b1d9c189b3e3a13 + revision: f299f8b + ref: f299f8b7ff6ea102bfb3 specs: liquid (2.1.3) GIT remote: git://github.com/plataformatec/devise.git - revision: 219c05c + revision: c6002bb specs: devise (1.2.0) bcrypt-ruby (~> 2.1.2) diff --git a/app/models/extensions/page/editable_elements.rb b/app/models/extensions/page/editable_elements.rb index 5bbd2d1c..a1357bff 100644 --- a/app/models/extensions/page/editable_elements.rb +++ b/app/models/extensions/page/editable_elements.rb @@ -11,6 +11,10 @@ module Models module InstanceMethods + def editable_elements_grouped_by_blocks + self.editable_elements.group_by(&:block) + end + def find_editable_element(block, slug) self.editable_elements.detect { |el| el.block == block && el.slug == slug } end diff --git a/app/models/extensions/page/parse.rb b/app/models/extensions/page/parse.rb index fce8a80b..7da232ad 100644 --- a/app/models/extensions/page/parse.rb +++ b/app/models/extensions/page/parse.rb @@ -56,65 +56,58 @@ module Models 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.snippet_dependencies = context[:snippets] + # puts "*** [#{self.fullpath}] template_dependencies = #{self.template_dependencies.inspect}" + @template.root.context.clear - # - # dependencies = all_dependencies(@template.root, { :templates => [], :snippets => [] }) - # - # self.template_dependencies = dependencies[:templates] - # self.snippet_dependencies = dependencies[:snippets] end def template_must_be_valid @parsing_errors.try(:each) { |msg| self.errors.add :template, msg } 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 return unless @template_changed == true # 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 - 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 - descendants.map(&:save) + template_descendants.map(&:save) # puts "** first descendant = #{descendants.first.object_id} / #{descendants.first.template.inspect}" end - def _update_direct_template_descendants(descendants, cached) - direct_descendants = descendants.select do |page| - (page.template_dependencies - self.template_dependencies).size == 1 + def _update_direct_template_descendants(template_descendants, cached) + # puts "*** [#{self.fullpath}] _update_direct_template_descendants" + 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 + # puts "*** [#{self.fullpath}] direct = #{direct_descendants.inspect}" + direct_descendants.each do |page| 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 diff --git a/features/engine/editable_elements.feature b/features/engine/editable_elements.feature index a1e31f24..de3afd1f 100644 --- a/features/engine/editable_elements.feature +++ b/features/engine/editable_elements.feature @@ -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 %} """ - 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" 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: """ 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 """ \ No newline at end of file diff --git a/features/engine/inheritance.feature b/features/engine/inheritance.feature index 283a8cb4..36c5400a 100644 --- a/features/engine/inheritance.feature +++ b/features/engine/inheritance.feature @@ -16,13 +16,11 @@ Scenario: Liquid Inheritance with a single block
""" - And a page named "hello-world-with-layout" with the template: """ {% extends 'above-and-below' %} {% block body %}Hello World{% endblock %} """ - When I view the rendered page at "/hello-world-with-layout" Then the rendered output should look like: """ @@ -33,6 +31,26 @@ Scenario: Liquid Inheritance with a single block """ +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 Given a page named "layout-with-sidebar" with the template: """ diff --git a/features/step_definitions/editable_elements_steps.rb b/features/step_definitions/editable_elements_steps.rb index b87386d7..8395f161 100644 --- a/features/step_definitions/editable_elements_steps.rb +++ b/features/step_definitions/editable_elements_steps.rb @@ -3,8 +3,15 @@ Given /^a simple page named "([^"]*)" with the body:$/ do |page_slug, page_conte end # 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.find_editable_element(nil, slug).content = content 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 \ No newline at end of file diff --git a/features/step_definitions/page_steps.rb b/features/step_definitions/page_steps.rb index de166a7a..55accd42 100644 --- a/features/step_definitions/page_steps.rb +++ b/features/step_definitions/page_steps.rb @@ -36,6 +36,14 @@ end # page.save # 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 When /^I view the rendered page at "([^"]*)"$/ do |path| visit "http://#{@site.domains.first}#{path}" diff --git a/lib/locomotive/liquid/tags/editable_short_text.rb b/lib/locomotive/liquid/tags/editable_short_text.rb index 8271d3ae..7380d434 100644 --- a/lib/locomotive/liquid/tags/editable_short_text.rb +++ b/lib/locomotive/liquid/tags/editable_short_text.rb @@ -16,7 +16,7 @@ module Locomotive super - puts "@nodelist = #{@nodelist.inspect}" + # puts "@nodelist = #{@nodelist.inspect}" @context[:page].add_or_update_editable_element({ :block => @context[:current_block].try(:name), @@ -29,7 +29,7 @@ module Locomotive def render(context) 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) diff --git a/lib/locomotive/liquid/tags/extends.rb b/lib/locomotive/liquid/tags/extends.rb index 2f4e9ac3..b0a2da18 100644 --- a/lib/locomotive/liquid/tags/extends.rb +++ b/lib/locomotive/liquid/tags/extends.rb @@ -7,17 +7,21 @@ module Locomotive def initialize(tag_name, markup, tokens, context) if markup =~ Syntax - @template_name = $1 + @template_name = $1.gsub('\'', '').strip else raise SyntaxError.new("Error in tag 'extends' - Valid syntax: extends [template]") end + @context = context + retrieve_parent_page # before parsing the embedded tokens, get editable elements from parent page @context[:page].merge_editable_elements_from_page(@context[:parent_page]) super + + # puts "** after extends, @context[:templates] = #{@context[:templates].inspect}" end private @@ -36,7 +40,9 @@ module Locomotive end @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 end @@ -44,19 +50,20 @@ module Locomotive def retrieve_parent_page if @template_name == 'parent' if @context[:cached_parent] - @context[:parent] = @context[:cached_parent] + @context[:parent_page] = @context[:cached_parent] @context[:cached_parent] = nil else @context[:parent_page] = @context[:page].parent end else - path = @template_name.gsub("'", '') - @context[:parent_page] = @context[:cached_pages].try(:[], path) || - @context[:site].pages.where(:fullpath => path).first + @context[:parent_page] = @context[:cached_pages].try(:[], @template_name) || + @context[:site].pages.where(:fullpath => @template_name).first end 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 end