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
|
||||
field :serialized_template, :type => Binary
|
||||
field :template_dependencies, :type => Array, :default => []
|
||||
|
||||
before_validation :serialize_template
|
||||
after_save :update_template_descendants
|
||||
|
||||
validate :template_must_be_valid
|
||||
|
||||
scope :pages, lambda { |domain| { :any_in => { :domains => [*domain] } } }
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
@ -21,26 +25,22 @@ module Models
|
||||
|
||||
protected
|
||||
|
||||
def parse
|
||||
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self })
|
||||
def parse(context = {})
|
||||
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self }.merge(context))
|
||||
@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
|
||||
|
||||
def serialize_template
|
||||
if self.new_record? || self.raw_template_changed?
|
||||
@template_changed = true
|
||||
|
||||
@parsing_errors = []
|
||||
|
||||
begin
|
||||
self.parse
|
||||
|
||||
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
|
||||
|
||||
self._serialize_template
|
||||
rescue ::Liquid::SyntaxError => error
|
||||
@parsing_errors << :liquid_syntax
|
||||
rescue ::Locomotive::Liquid::PageNotFound => error
|
||||
@ -49,10 +49,56 @@ module Models
|
||||
end
|
||||
end
|
||||
|
||||
def _serialize_template(context = {})
|
||||
self.parse(context)
|
||||
self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
|
||||
end
|
||||
|
||||
def template_must_be_valid
|
||||
@parsing_errors.try(:each) { |msg| self.errors.add :template, msg }
|
||||
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
|
||||
|
@ -3,17 +3,27 @@ module Locomotive
|
||||
module Tags
|
||||
class Extends < ::Liquid::Extends
|
||||
|
||||
attr_accessor :page_id
|
||||
|
||||
def parse_parent_template(context)
|
||||
page = nil
|
||||
|
||||
if @template_name == 'parent'
|
||||
page = context[:page].parent
|
||||
if context[:cached_parent]
|
||||
page = context[:cached_parent]
|
||||
context[:cached_parent] = nil
|
||||
else
|
||||
page = context[:page].parent
|
||||
end
|
||||
else
|
||||
page = context[:site].pages.where(:fullpath => @template_name.gsub("'", '')).first
|
||||
path = @template_name.gsub("'", '')
|
||||
page = context[:cached_pages].try(:[], path) || context[:site].pages.where(:fullpath => path).first
|
||||
end
|
||||
|
||||
raise PageNotFound.new("Page with fullpath '#{@template_name}' was not found") if page.nil?
|
||||
|
||||
@page_id = page.id
|
||||
|
||||
template = page.template
|
||||
|
||||
# merge blocks ?
|
||||
|
@ -1,7 +1,8 @@
|
||||
# require "rubygems"
|
||||
# require "ruby-prof"
|
||||
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|
|
||||
Mongoid.master.collection(collection).drop
|
||||
|
Loading…
Reference in New Issue
Block a user