also update page templates if a snippet was modified

This commit is contained in:
dinedine 2010-08-24 15:04:53 +02:00
parent 75783ec881
commit e580021eda
3 changed files with 69 additions and 22 deletions

View File

@ -8,6 +8,7 @@ module Models
included do included do
field :serialized_template, :type => Binary field :serialized_template, :type => Binary
field :template_dependencies, :type => Array, :default => [] field :template_dependencies, :type => Array, :default => []
field :snippet_dependencies, :type => Array, :default => []
before_validation :serialize_template before_validation :serialize_template
after_save :update_template_descendants after_save :update_template_descendants
@ -25,22 +26,13 @@ module Models
protected protected
def parse(context = {})
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self }.merge(context))
@template.root.context.clear
self.template_dependencies = parent_templates(@template.root)
# TODO: snippets dependencies
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 @template_changed = true
@parsing_errors = [] @parsing_errors = []
begin begin
self._serialize_template self._parse_and_serialize_template
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,25 +41,44 @@ module Models
end end
end end
def _serialize_template(context = {}) def _parse_and_serialize_template(context = {})
self.parse(context) self.parse(context)
self._serialize_template
end
def _serialize_template
self.serialized_template = BSON::Binary.new(Marshal.dump(@template)) self.serialized_template = BSON::Binary.new(Marshal.dump(@template))
end end
def parse(context = {})
@template = ::Liquid::Template.parse(self.raw_template, { :site => self.site, :page => self }.merge(context))
@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 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 = []) def all_dependencies(node, dependencies = {})
templates << node.page_id if node.is_a?(Locomotive::Liquid::Tags::Extends) 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) if node.respond_to?(:nodelist) && node.nodelist
node.nodelist.each do |child| node.nodelist.each do |child|
self.parent_templates(child, templates) self.all_dependencies(child, dependencies)
end end
end end
templates dependencies
end end
def update_template_descendants def update_template_descendants
@ -93,7 +104,7 @@ module Models
end end
direct_descendants.each do |page| direct_descendants.each do |page|
page.send(:_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, descendants, cached)
end end

View File

@ -12,6 +12,8 @@ class Snippet
## callbacks ## ## callbacks ##
before_validation :normalize_slug before_validation :normalize_slug
after_save :update_templates
after_destroy :update_templates
# TODO: after_save callback to let pages embedding this snippet know about the changes the user has just made. # TODO: after_save callback to let pages embedding this snippet know about the changes the user has just made.
@ -28,5 +30,27 @@ class Snippet
self.slug.slugify!(:without_extension => true, :downcase => true) if self.slug.present? self.slug.slugify!(:without_extension => true, :downcase => true) if self.slug.present?
end end
def update_templates
pages = self.site.pages.any_in(:snippet_dependencies => [self.slug]).to_a
pages.each do |page|
self._change_snippet_inside_template(page.template.root)
page.send(:_serialize_template) && page.save
end
end
def _change_snippet_inside_template(node)
if node.is_a?(Locomotive::Liquid::Tags::Snippet)
node.refresh(self)
else
if node.respond_to?(:nodelist)
node.nodelist.each do |child|
self._change_snippet_inside_template(child)
end
end
end
end
end end

View File

@ -4,17 +4,17 @@ module Locomotive
class Snippet < ::Liquid::Include class Snippet < ::Liquid::Include
attr_accessor :slug
attr_accessor :partial attr_accessor :partial
def initialize(tag_name, markup, tokens, context) def initialize(tag_name, markup, tokens, context)
super super
snippet = context[:site].snippets.where(:slug => @template_name.gsub('\'', '')).first @slug = @template_name.gsub('\'', '')
if snippet snippet = context[:site].snippets.where(:slug => @slug).first
@partial = ::Liquid::Template.parse(snippet.template, context)
@partial.root.context.clear self.refresh(snippet, context) if snippet
end
end end
def render(context) def render(context)
@ -40,6 +40,18 @@ module Locomotive
output output
end end
end end
def refresh(snippet, context = {})
if snippet.destroyed?
@snippet_id = nil
@partial = nil
else
@snippet_id = snippet.id
@partial = ::Liquid::Template.parse(snippet.template, context)
@partial.root.context.clear
end
end
end end
::Liquid::Template.register_tag('include', Snippet) ::Liquid::Template.register_tag('include', Snippet)