[#604] Adapt the upstream include mechanism to work with Wiki pages

This commit is contained in:
Holger Just 2011-11-20 00:59:52 +01:00
parent 71ecdb57ed
commit 862c9e0fde
5 changed files with 103 additions and 15 deletions

View File

@ -3,5 +3,6 @@ require 'chili_project/liquid/tags'
module ChiliProject
module Liquid
Liquid::Template.file_system = FileSystem.new
end
end

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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