when a template is modified, all pages inheriting from it are updated too (functional tests are coming)
This commit is contained in:
parent
4805d8813e
commit
75783ec881
@ -7,10 +7,14 @@ module Models
|
|||||||
|
|
||||||
included do
|
included do
|
||||||
field :serialized_template, :type => Binary
|
field :serialized_template, :type => Binary
|
||||||
|
field :template_dependencies, :type => Array, :default => []
|
||||||
|
|
||||||
before_validation :serialize_template
|
before_validation :serialize_template
|
||||||
|
after_save :update_template_descendants
|
||||||
|
|
||||||
validate :template_must_be_valid
|
validate :template_must_be_valid
|
||||||
|
|
||||||
|
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
@ -21,26 +25,22 @@ module Models
|
|||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def parse
|
def parse(context = {})
|
||||||
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self })
|
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self }.merge(context))
|
||||||
@template.root.context.clear
|
@template.root.context.clear
|
||||||
|
|
||||||
# TODO: walk thru the document tree to get parents as well as used snippets
|
self.template_dependencies = parent_templates(@template.root)
|
||||||
|
|
||||||
|
# TODO: snippets dependencies
|
||||||
end
|
end
|
||||||
|
|
||||||
def serialize_template
|
def serialize_template
|
||||||
if self.new_record? || self.raw_template_changed?
|
if self.new_record? || self.raw_template_changed?
|
||||||
|
@template_changed = true
|
||||||
|
|
||||||
@parsing_errors = []
|
@parsing_errors = []
|
||||||
|
|
||||||
begin
|
begin
|
||||||
self.parse
|
self._serialize_template
|
||||||
|
|
||||||
self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
|
|
||||||
|
|
||||||
# TODO: let other pages inheriting from that one and modify them in consequences
|
|
||||||
|
|
||||||
# TODO: build array of parent pages
|
|
||||||
|
|
||||||
rescue ::Liquid::SyntaxError => error
|
rescue ::Liquid::SyntaxError => error
|
||||||
@parsing_errors << :liquid_syntax
|
@parsing_errors << :liquid_syntax
|
||||||
rescue ::Locomotive::Liquid::PageNotFound => error
|
rescue ::Locomotive::Liquid::PageNotFound => error
|
||||||
@ -49,10 +49,56 @@ module Models
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def _serialize_template(context = {})
|
||||||
|
self.parse(context)
|
||||||
|
self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
|
||||||
|
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 parent_templates(node, templates = [])
|
||||||
|
templates << node.page_id if node.is_a?(Locomotive::Liquid::Tags::Extends)
|
||||||
|
|
||||||
|
if node.respond_to?(:nodelist)
|
||||||
|
node.nodelist.each do |child|
|
||||||
|
self.parent_templates(child, templates)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
templates
|
||||||
|
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
|
||||||
|
|
||||||
|
# group them by fullpath for better performance
|
||||||
|
cached = descendants.inject({}) { |memo, page| memo[page.fullpath] = page; memo }
|
||||||
|
|
||||||
|
self._update_direct_template_descendants(descendants, cached)
|
||||||
|
|
||||||
|
# finally save them all
|
||||||
|
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
|
||||||
|
end
|
||||||
|
|
||||||
|
direct_descendants.each do |page|
|
||||||
|
page.send(:_serialize_template, { :cached_parent => self, :cached_pages => cached })
|
||||||
|
|
||||||
|
page.send(:_update_direct_template_descendants, descendants, cached)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
@ -3,17 +3,27 @@ module Locomotive
|
|||||||
module Tags
|
module Tags
|
||||||
class Extends < ::Liquid::Extends
|
class Extends < ::Liquid::Extends
|
||||||
|
|
||||||
|
attr_accessor :page_id
|
||||||
|
|
||||||
def parse_parent_template(context)
|
def parse_parent_template(context)
|
||||||
page = nil
|
page = nil
|
||||||
|
|
||||||
if @template_name == 'parent'
|
if @template_name == 'parent'
|
||||||
page = context[:page].parent
|
if context[:cached_parent]
|
||||||
|
page = context[:cached_parent]
|
||||||
|
context[:cached_parent] = nil
|
||||||
else
|
else
|
||||||
page = context[:site].pages.where(:fullpath => @template_name.gsub("'", '')).first
|
page = context[:page].parent
|
||||||
|
end
|
||||||
|
else
|
||||||
|
path = @template_name.gsub("'", '')
|
||||||
|
page = context[:cached_pages].try(:[], path) || context[:site].pages.where(:fullpath => path).first
|
||||||
end
|
end
|
||||||
|
|
||||||
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if page.nil?
|
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if page.nil?
|
||||||
|
|
||||||
|
@page_id = page.id
|
||||||
|
|
||||||
template = page.template
|
template = page.template
|
||||||
|
|
||||||
# merge blocks ?
|
# merge blocks ?
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
# require "rubygems"
|
# require "rubygems"
|
||||||
# require "ruby-prof"
|
# require "ruby-prof"
|
||||||
ENV["RAILS_ENV"] ||= 'test'
|
ENV["RAILS_ENV"] ||= 'test'
|
||||||
require File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
|
||||||
|
require "./" + File.dirname(__FILE__) + "/../config/environment" unless defined?(RAILS_ROOT)
|
||||||
|
|
||||||
%w{sites pages layouts}.each do |collection|
|
%w{sites pages layouts}.each do |collection|
|
||||||
Mongoid.master.collection(collection).drop
|
Mongoid.master.collection(collection).drop
|
||||||
|
Loading…
Reference in New Issue
Block a user