diff --git a/lib/puffer_pages/backends/models/layout.rb b/lib/puffer_pages/backends/models/layout.rb index b3f97e6..8688598 100644 --- a/lib/puffer_pages/backends/models/layout.rb +++ b/lib/puffer_pages/backends/models/layout.rb @@ -12,7 +12,9 @@ class PufferPages::Backends::Layout < ActiveRecord::Base validates_uniqueness_of :name def self.find_layout(name) - where(:name => name).first + layout = where(:name => name).first + layout.cache_translations if PufferPages.localize + layout end def render *args diff --git a/lib/puffer_pages/backends/models/mixins/renderable.rb b/lib/puffer_pages/backends/models/mixins/renderable.rb index 993e7ff..cc7416b 100644 --- a/lib/puffer_pages/backends/models/mixins/renderable.rb +++ b/lib/puffer_pages/backends/models/mixins/renderable.rb @@ -3,12 +3,13 @@ module Backends module Mixins module Renderable extend ActiveSupport::Concern + extend ::NewRelic::Agent::MethodTracer if defined? ::NewRelic def template @template ||= ::Liquid::Template.parse(self) end - private + private # Method gets some arguments and returns source, context and additional @@ -104,24 +105,27 @@ def normalize_context_options options end def render_template source, context = {}, additional = {} - template = source.respond_to?(:template) ? source.template : ::Liquid::Template.parse(source) - context = merge_context(context, additional) + self.class.trace_execution_scoped(["Custom/render_template/#{self.name.try(:underscore) || 'other'}"]) do - if context.is_a?(::Liquid::Context) - instrument_render! context do - template.send(render_method, context) - end - else - tracker = PufferPages::Liquid::Tracker.new - context = merge_context(context, registers: { - :file_system => PufferPages::Liquid::FileSystem.new, - :tracker => tracker - }) - - instrument_render! context do - tracker.cleanup template.send(render_method, - context[:drops].merge!(context[:environment]), - registers: context[:registers]) + template = source.respond_to?(:template) ? source.template : ::Liquid::Template.parse(source) + context = merge_context(context, additional) + + if context.is_a?(::Liquid::Context) + instrument_render! context do + template.send(render_method, context) + end + else + tracker = PufferPages::Liquid::Tracker.new + context = merge_context(context, registers: { + :file_system => PufferPages::Liquid::FileSystem.new, + :tracker => tracker + }) + + instrument_render! context do + tracker.cleanup template.send(render_method, + context[:drops].merge!(context[:environment]), + registers: context[:registers]) + end end end end @@ -150,4 +154,4 @@ def render_method end end end -end \ No newline at end of file +end diff --git a/lib/puffer_pages/backends/models/mixins/translatable.rb b/lib/puffer_pages/backends/models/mixins/translatable.rb index 0a3faba..ffcf954 100644 --- a/lib/puffer_pages/backends/models/mixins/translatable.rb +++ b/lib/puffer_pages/backends/models/mixins/translatable.rb @@ -14,6 +14,12 @@ def self.globalize_migrator @globalize_migrator ||= PufferPages::Globalize::Migrator.new(self) end + define_method :cache_translations do + translations.with_locale(Globalize.fallbacks).each do |translation| + translation_caches[translation.locale.to_sym] = translation + end + end + fields.each do |field| define_method "#{field}_translations" do result = translations.each_with_object(HashWithIndifferentAccess.new) do |translation, result| diff --git a/lib/puffer_pages/backends/models/origin.rb b/lib/puffer_pages/backends/models/origin.rb index 032966c..9a30cbf 100644 --- a/lib/puffer_pages/backends/models/origin.rb +++ b/lib/puffer_pages/backends/models/origin.rb @@ -36,10 +36,11 @@ def import_json json end def self.export_json - %w(layouts snippets pages).each_with_object({}) do |table, result| + res = %w(layouts snippets pages).each_with_object({}) do |table, result| klass = "puffer_pages/#{table}".classify.constantize result[table] = klass.export_json - end.as_json.to_json + end + MultiJson.dump(res) end private diff --git a/lib/puffer_pages/backends/models/page.rb b/lib/puffer_pages/backends/models/page.rb index 4f9b834..a635cf1 100644 --- a/lib/puffer_pages/backends/models/page.rb +++ b/lib/puffer_pages/backends/models/page.rb @@ -138,11 +138,22 @@ def self_and_ancestors_page_parts end def inherited_page_parts - @inherited_page_parts ||= self_and_ancestors_page_parts.group_by(&:name).map { |(_, group)| group.first } + @inherited_page_parts ||= begin + page_parts = self_and_ancestors_page_parts.group_by(&:name) + if PufferPages.localize + translation_cached = page_parts.values.map { |group| group.first.handler == 'yaml' ? group : group.first }. + flatten.index_by(&:id) + PufferPages::PagePart::Translation.where(page_part_id: translation_cached.keys). + with_locale(Globalize.fallbacks).each do |translation| + translation_cached[translation.page_part_id].translation_caches[translation.locale.to_sym] = translation + end + end + page_parts + end end def inherited_page_part name - inherited_page_parts.detect { |part| part.name == name } + inherited_page_parts[name].first end def render *args @@ -161,9 +172,11 @@ def render *args end else instrument_render! context do - inherited_page_parts.map do |part| - result = part.render context - part.main? ? result : "<% content_for :'#{part.name}' do %>#{result}<% end %>" + inherited_page_parts.values.map(&:first).map do |part| + if part.main? || part.name.in?(%w(keywords title description)) + result = part.render context + part.main? ? result : "<% content_for :'#{part.name}' do %>#{result}<% end %>" + end end.join end end diff --git a/lib/puffer_pages/backends/models/page_part.rb b/lib/puffer_pages/backends/models/page_part.rb index c980227..955e97b 100644 --- a/lib/puffer_pages/backends/models/page_part.rb +++ b/lib/puffer_pages/backends/models/page_part.rb @@ -8,8 +8,6 @@ class PufferPages::Backends::PagePart < ActiveRecord::Base attr_protected - default_scope ->{ includes :translations } if PufferPages.localize - validates_presence_of :name validates_uniqueness_of :name, :scope => :page_id @@ -50,17 +48,17 @@ def additional_render_options { environment: { processed: self } } end + def page_segments + @page_segments ||= page.segments + end + def i18n_scope - i18n_scope_for page.segments, :page_parts, name + i18n_scope_for page_segments end def i18n_defaults - page.segments.inject([]) do |memo, element| - memo.push (memo.last || []).dup.push(element) - end.unshift([]).inject([]) do |memo, segments| - memo.unshift i18n_scope_for(segments) - memo.unshift i18n_scope_for(segments, :page_parts, name) - end + page_segments[0..-2].each_with_object([[]]) { |segment, result| result.push result.last + [segment] }.reverse. + map { |segments| i18n_scope_for(segments) } end private diff --git a/lib/puffer_pages/backends/models/snippet.rb b/lib/puffer_pages/backends/models/snippet.rb index 995d51f..3fdb935 100644 --- a/lib/puffer_pages/backends/models/snippet.rb +++ b/lib/puffer_pages/backends/models/snippet.rb @@ -12,7 +12,9 @@ class PufferPages::Backends::Snippet < ActiveRecord::Base validates_uniqueness_of :name def self.find_snippet(name) - where(:name => name).first + snippet = where(:name => name).first + snippet.cache_translations if PufferPages.localize + snippet end def render *args diff --git a/lib/puffer_pages/handlers/yaml.rb b/lib/puffer_pages/handlers/yaml.rb index 42670ff..0e22a95 100644 --- a/lib/puffer_pages/handlers/yaml.rb +++ b/lib/puffer_pages/handlers/yaml.rb @@ -2,7 +2,10 @@ module PufferPages module Handlers class Yaml < Base def process renderable, context = nil - renderable.self_and_ancestors.where(handler: 'yaml').reverse.each_with_object({}) do |renderable, result| + page_parts = context ? context.registers[:page].inherited_page_parts[renderable.name] : + renderable.self_and_ancestors + page_parts.select { |renderable| renderable.handler == 'yaml' }.reverse. + each_with_object({}) do |renderable, result| load_arguments = [renderable.render(context)] load_arguments.push renderable.name if YAML.method(:load).arity == -2 hash = YAML.load *load_arguments diff --git a/lib/puffer_pages/liquid/tags/array.rb b/lib/puffer_pages/liquid/tags/array.rb index f1f5ce5..3b03410 100644 --- a/lib/puffer_pages/liquid/tags/array.rb +++ b/lib/puffer_pages/liquid/tags/array.rb @@ -21,6 +21,10 @@ def render(context) '' end + def blank? + false + end + private def variables_from_string(markup) diff --git a/lib/puffer_pages/liquid/tags/assets.rb b/lib/puffer_pages/liquid/tags/assets.rb index d686e05..3fb795c 100644 --- a/lib/puffer_pages/liquid/tags/assets.rb +++ b/lib/puffer_pages/liquid/tags/assets.rb @@ -28,6 +28,10 @@ def render(context) context.registers[:tracker].register(erb) end + def blank? + false + end + private def variables_from_string(markup) diff --git a/lib/puffer_pages/liquid/tags/cache.rb b/lib/puffer_pages/liquid/tags/cache.rb index b09cea4..5f50184 100644 --- a/lib/puffer_pages/liquid/tags/cache.rb +++ b/lib/puffer_pages/liquid/tags/cache.rb @@ -61,7 +61,7 @@ def expires_in expiration end def cache_key key - ActiveSupport::Cache.expand_cache_key key.unshift('puffer_pages_cache') + Digest::MD5.hexdigest ActiveSupport::Cache.expand_cache_key(key.unshift('puffer_pages_cache')) end def cache_store @@ -71,6 +71,10 @@ def cache_store def cache? PufferPages.config.perform_caching && cache_store end + + def blank? + false + end end end diff --git a/lib/puffer_pages/liquid/tags/image.rb b/lib/puffer_pages/liquid/tags/image.rb index c980949..0e38e8c 100644 --- a/lib/puffer_pages/liquid/tags/image.rb +++ b/lib/puffer_pages/liquid/tags/image.rb @@ -28,6 +28,10 @@ def render(context) context.registers[:tracker].register("<%= image_tag #{@path}, #{attributes} %>") end + + def blank? + false + end end end diff --git a/lib/puffer_pages/liquid/tags/include.rb b/lib/puffer_pages/liquid/tags/include.rb index a6638a6..d1de98d 100644 --- a/lib/puffer_pages/liquid/tags/include.rb +++ b/lib/puffer_pages/liquid/tags/include.rb @@ -4,7 +4,7 @@ module Tags class Include < ::Liquid::Include def render(context) - source = _read_template_from_file_system(context) + source = read_template_from_file_system(context) variable = context[@variable_name || @template_name[1..-2]] context.stack do diff --git a/lib/puffer_pages/liquid/tags/javascript.rb b/lib/puffer_pages/liquid/tags/javascript.rb index 482ea4d..6116f71 100644 --- a/lib/puffer_pages/liquid/tags/javascript.rb +++ b/lib/puffer_pages/liquid/tags/javascript.rb @@ -6,6 +6,10 @@ class Javascript < ::Liquid::Block def render(context) context.registers[:tracker].register("<%= javascript_tag do %>#{super}<% end %>") end + + def blank? + false + end end end diff --git a/lib/puffer_pages/liquid/tags/partials.rb b/lib/puffer_pages/liquid/tags/partials.rb index 6e7e386..99946ee 100644 --- a/lib/puffer_pages/liquid/tags/partials.rb +++ b/lib/puffer_pages/liquid/tags/partials.rb @@ -6,7 +6,7 @@ class Partials < Include private - def _read_template_from_file_system(context) + def read_template_from_file_system(context) file_system = context.registers[:file_system] || Liquid::Template.file_system template_name = "#{@tag_name.pluralize}/#{context[@template_name]}" diff --git a/lib/puffer_pages/liquid/tags/render.rb b/lib/puffer_pages/liquid/tags/render.rb index 4a5dc58..9d4e668 100644 --- a/lib/puffer_pages/liquid/tags/render.rb +++ b/lib/puffer_pages/liquid/tags/render.rb @@ -27,6 +27,10 @@ def render(context) end %>") end + + def blank? + false + end end end diff --git a/lib/puffer_pages/liquid/tags/scope.rb b/lib/puffer_pages/liquid/tags/scope.rb index 5675e06..ddf1bec 100644 --- a/lib/puffer_pages/liquid/tags/scope.rb +++ b/lib/puffer_pages/liquid/tags/scope.rb @@ -21,6 +21,10 @@ def render(context) super end end + + def blank? + false + end end end diff --git a/lib/puffer_pages/liquid/tags/translate.rb b/lib/puffer_pages/liquid/tags/translate.rb index f9d712c..104b15f 100644 --- a/lib/puffer_pages/liquid/tags/translate.rb +++ b/lib/puffer_pages/liquid/tags/translate.rb @@ -34,12 +34,13 @@ def render(context) end end - if processed && key.first == '.' - I18n.translate i18n_key(processed, key.last(-1)), - options.merge!(:default => i18n_defaults(processed, key.last(-1))) - else - I18n.translate key, options - end + if processed && key.first == '.' + default = i18n_defaults(processed, key.last(-1)) + options.merge!(:default => default) if default.any? + I18n.translate i18n_key(processed, key.last(-1)), options + else + I18n.translate key, options + end end def i18n_key(processed, key) @@ -51,7 +52,11 @@ def i18n_defaults(processed, key) end def array_to_key *array - array.flatten.map { |segment| segment.to_s.gsub(?., ?/) }.join(?.).to_sym + array.flatten.map { |segment| segment.to_s.tr(?., ?/) }.join(?.).to_sym + end + + def blank? + false end end diff --git a/lib/puffer_pages/liquid/tags/url.rb b/lib/puffer_pages/liquid/tags/url.rb index 8ac6647..cb34a0b 100644 --- a/lib/puffer_pages/liquid/tags/url.rb +++ b/lib/puffer_pages/liquid/tags/url.rb @@ -43,6 +43,10 @@ def render(context) context.registers[:controller].send("#{@helper_name}_#{@tag_name}", *arguments, attributes) end + def blank? + false + end + end end diff --git a/lib/puffer_pages/liquid/tags/yield.rb b/lib/puffer_pages/liquid/tags/yield.rb index fd2feec..45d307d 100644 --- a/lib/puffer_pages/liquid/tags/yield.rb +++ b/lib/puffer_pages/liquid/tags/yield.rb @@ -22,6 +22,10 @@ def render(context) "<%= yield :'#{@name}' %>" : "<%= yield %>") end + + def blank? + false + end end end diff --git a/lib/puffer_pages/log_subscriber.rb b/lib/puffer_pages/log_subscriber.rb index 3de1e06..8cee54c 100644 --- a/lib/puffer_pages/log_subscriber.rb +++ b/lib/puffer_pages/log_subscriber.rb @@ -2,24 +2,35 @@ module PufferPages class LogSubscriber < ActiveSupport::LogSubscriber def render_page event message = " PufferPages: rendered page /#{event.payload[:subject].location} #{duration(event)}" - info message + persistent_log event.payload[:subject].location, event.duration + debug message end def render_page_part event message = " PufferPages: rendered page_part #{event.payload[:subject].name} #{duration(event)}" + persistent_log event.payload[:subject].name, event.duration debug message end def render_layout event message = " PufferPages: rendered layout #{event.payload[:subject].name} #{duration(event)}" + persistent_log event.payload[:subject].name, event.duration debug message end def render_snippet event message = " PufferPages: rendered snippet #{event.payload[:subject].name} #{duration(event)}" + persistent_log event.payload[:subject].name, event.duration debug message end + def persistent_log id, duration + if Rails.env != 'development' + message = "Template debug - id: #{CmsEngine::DomainConfig.current.locale}_#{id} time: #{duration}" + debug message + end + end + def duration event '(%.1fms)' % event.duration end diff --git a/puffer_pages.gemspec b/puffer_pages.gemspec index aa794f9..f190c44 100644 --- a/puffer_pages.gemspec +++ b/puffer_pages.gemspec @@ -21,7 +21,7 @@ Gem::Specification.new do |s| # specify any dependencies here; for example: s.add_runtime_dependency "rails", ">= 3.1" s.add_runtime_dependency "puffer" - s.add_runtime_dependency "liquid" + s.add_runtime_dependency "liquid", ">= 2.5.2" s.add_runtime_dependency "nested_set" s.add_runtime_dependency "activeuuid", ">= 0.4.0" s.add_runtime_dependency "contextuality" diff --git a/test b/test new file mode 100644 index 0000000..e69de29