diff --git a/lib/chili_project/liquid/tags.rb b/lib/chili_project/liquid/tags.rb index 9438213d..e44ab0ea 100644 --- a/lib/chili_project/liquid/tags.rb +++ b/lib/chili_project/liquid/tags.rb @@ -24,7 +24,7 @@ module ChiliProject::Liquid end # TODO: reimplement old macros as tags and register them here - # child_pages + register_tag('child_pages', ChildPages, :html => true) register_tag('hello_world', HelloWorld) # include register_tag('tag_list', TagList, :html => true) @@ -34,4 +34,5 @@ end # FIXME: remove the deprecated syntax for 4.0, provide a way to migrate # existing pages to the new syntax. +ChiliProject::Liquid::Legacy.add('child_pages', :tag) ChiliProject::Liquid::Legacy.add('hello_world', :tag) diff --git a/lib/chili_project/liquid/tags/child_pages.rb b/lib/chili_project/liquid/tags/child_pages.rb new file mode 100644 index 00000000..ca373a3e --- /dev/null +++ b/lib/chili_project/liquid/tags/child_pages.rb @@ -0,0 +1,60 @@ +module ChiliProject::Liquid::Tags + class ChildPages < Tag + def initialize(tag_name, markup, tokens) + markup = markup.strip.gsub(/["']/, '') + if markup.present? + tag_args = markup.split(',') + @args, @options = extract_macro_options(tag_args, :parent) + else + @args = [] + @options = {} + end + super + end + + def render(context) + # inside of a project + @project = Project.find(context['project'].identifier) if context['project'].present? + + if @args.present? + page_name = @args.first.to_s + cross_project_page = page_name.include?(':') + + page = Wiki.find_page(page_name, :project => (cross_project_page ? nil : @project)) + # FIXME: :object and :attribute should be variables, not registers + elsif context.registers[:object].is_a?(WikiContent) + page = context.registers[:object].page + page_name = page.title + elsif @project + return render_all_pages(context) + else + raise TagError.new('With no argument, this tag can be called from projects only.') + end + + raise TagError.new("No such page '#{page_name}'") if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) + pages = ([page] + page.descendants).group_by(&:parent_id) + context.registers[:view].render_page_hierarchy(pages, @options[:parent] ? page.parent_id : page.id) + end + + private + def render_all_pages(context) + return '' unless @project.wiki.present? && @project.wiki.pages.present? + raise TagError.new('Page not found') if !User.current.allowed_to?(:view_wiki_pages, @project) + + context.registers[:view].render_page_hierarchy(@project.wiki.pages.group_by(&:parent_id)) + end + + # @param args [Array, String] An array of strings in "key=value" format + # @param keys [Hash, Symbol] List of keyword args to extract + def extract_macro_options(args, *keys) + options = {} + args.each do |arg| + if arg.to_s.gsub(/["']/,'').strip =~ %r{^(.+)\=(.+)$} && keys.include?($1.downcase.to_sym) + options[$1.downcase.to_sym] = $2 + args.pop + end + end + return [args, options] + end + end +end \ No newline at end of file diff --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb index 8b4468a5..b343b4f2 100644 --- a/lib/redmine/wiki_formatting/macros.rb +++ b/lib/redmine/wiki_formatting/macros.rb @@ -68,25 +68,6 @@ module Redmine end # Builtin macros - desc "Displays a list of child pages. With no argument, it displays the child pages of the current wiki page. Examples:\n\n" + - " !{{child_pages}} -- can be used from a wiki page only\n" + - " !{{child_pages(Foo)}} -- lists all children of page Foo\n" + - " !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo" - macro :child_pages do |obj, args| - args, options = extract_macro_options(args, :parent) - page = nil - if args.size > 0 - page = Wiki.find_page(args.first.to_s, :project => @project) - elsif obj.is_a?(WikiContent) - page = obj.page - else - raise 'With no argument, this macro can be called from wiki pages only.' - end - raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) - pages = ([page] + page.descendants).group_by(&:parent_id) - render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id) - end - 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)