diff --git a/lib/chili_project/liquid.rb b/lib/chili_project/liquid.rb index 9dae8d24..d9da7d5b 100644 --- a/lib/chili_project/liquid.rb +++ b/lib/chili_project/liquid.rb @@ -3,5 +3,6 @@ require 'chili_project/liquid/tags' module ChiliProject module Liquid + Liquid::Template.file_system = FileSystem.new end end \ No newline at end of file diff --git a/lib/chili_project/liquid/file_system.rb b/lib/chili_project/liquid/file_system.rb new file mode 100644 index 00000000..d6fe60f9 --- /dev/null +++ b/lib/chili_project/liquid/file_system.rb @@ -0,0 +1,18 @@ +module ChiliProject + module Liquid + class FileSystem + def read_template_file(template_name, context) + raise ::Liquid::FileSystemError.new("Page not found") if template_name.blank? + project = Project.find(context['project'].identifier) if context['project'].present? + + cross_project_page = template_name.include?(':') + page = Wiki.find_page(template_name.to_s.strip, :project => (cross_project_page ? nil : project)) + if page.nil? || !page.visible? + raise ::Liquid::FileSystemError.new("No such page '#{template_name}'") + end + + page.content + end + end + end +end \ No newline at end of file diff --git a/lib/chili_project/liquid/tags.rb b/lib/chili_project/liquid/tags.rb index e44ab0ea..41a28f7b 100644 --- a/lib/chili_project/liquid/tags.rb +++ b/lib/chili_project/liquid/tags.rb @@ -23,10 +23,9 @@ module ChiliProject::Liquid end end - # TODO: reimplement old macros as tags and register them here register_tag('child_pages', ChildPages, :html => true) register_tag('hello_world', HelloWorld) - # include + register_tag('include', Include, :html => true) register_tag('tag_list', TagList, :html => true) register_tag('variable_list', VariableList, :html => true) end @@ -36,3 +35,4 @@ end # existing pages to the new syntax. ChiliProject::Liquid::Legacy.add('child_pages', :tag) ChiliProject::Liquid::Legacy.add('hello_world', :tag) +ChiliProject::Liquid::Legacy.add('include', :tag) diff --git a/lib/chili_project/liquid/tags/include.rb b/lib/chili_project/liquid/tags/include.rb new file mode 100644 index 00000000..6de3df92 --- /dev/null +++ b/lib/chili_project/liquid/tags/include.rb @@ -0,0 +1,82 @@ +#-- copyright +# ChiliProject is a project management system. +# +# Copyright (C) 2010-2011 the ChiliProject Team +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# See doc/COPYRIGHT.rdoc for more details. +#++ + +module ChiliProject::Liquid::Tags + class Include < ::Liquid::Include + + # This method follows the basic flow of the default include in liquid + # We just add some additional flexibility. This method can be removed once + # https://github.com/Shopify/liquid/pull/78 got accepted + def render(context) + context.stack do + template = _read_template_from_file_system(context) + partial = Liquid::Template.parse _template_source(template) + variable = context[@variable_name || @template_name[1..-2]] + + @attributes.each do |key, value| + context[key] = context[value] + end + + if variable.is_a?(Array) + variable.collect do |variable| + context[@template_name[1..-2]] = variable + _render_partial(partial, template, context) + end + else + context[@template_name[1..-2]] = variable + _render_partial(partial, template, context) + end + end + end + + private + def break_circle(context) + context.registers[:included_pages] ||= [] + + project = context['project'].identifier if context['project'].present? + template_name = context[@template_name] + cross_project_page = template_name.include?(':') + page_title = cross_project_page ? template_name : "#{project}:#{template_name}" + + raise ::Liquid::FileSystemError.new("Circular inclusion detected") if context.registers[:included_pages].include?(page_title) + context.registers[:included_pages] << page_title + + yield + ensure + context.registers[:included_pages].pop + end + + def _template_source(wiki_content) + wiki_content.text + end + + def _render_partial(partial, template, context) + break_circle(context) do + textile = partial.render(context) + + # Call textilizable on the view so all of the helpers are loaded + # based on the view and not this tag + context.registers[:view].textilizable(textile, :attachments => template.page.attachments, :headings => false, :object => template) + end + end + + def _read_template_from_file_system(context) + wiki_content = super + + # Set the new project to that additional includes use the correct + # base project + context['project'] = wiki_content.page.wiki.project + wiki_content + end + end +end diff --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb index b343b4f2..faef7a8b 100644 --- a/lib/redmine/wiki_formatting/macros.rb +++ b/lib/redmine/wiki_formatting/macros.rb @@ -66,19 +66,6 @@ module Redmine @@desc = txt end end - - # Builtin macros - desc "Include a wiki page. Example:\n\n !{{include(Foo)}}\n\nor to include a page of a specific project wiki:\n\n !{{include(projectname:Foo)}}" - macro :include do |obj, args| - page = Wiki.find_page(args.first.to_s, :project => @project) - raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) - @included_wiki_pages ||= [] - raise 'Circular inclusion detected' if @included_wiki_pages.include?(page.title) - @included_wiki_pages << page.title - out = textilizable(page.content, :text, :attachments => page.attachments, :headings => false) - @included_wiki_pages.pop - out - end end end end