Adds a "depth" option to the child_pages macro (#10789).

git-svn-id: svn+ssh://rubyforge.org/var/svn/redmine/trunk@10401 e93f8b46-1217-0410-a6f0-8f06a7374b81
This commit is contained in:
Jean-Philippe Lang 2012-09-16 15:24:35 +00:00
parent ca4f2c59b6
commit 747e4ecd3a
5 changed files with 53 additions and 9 deletions

View File

@ -73,15 +73,20 @@ module ActiveRecord
# Returns list of descendants. # Returns list of descendants.
# #
# root.descendants # => [child1, subchild1, subchild2] # root.descendants # => [child1, subchild1, subchild2]
def descendants def descendants(depth=nil)
children + children.collect(&:descendants).flatten depth ||= 0
result = children.dup
unless depth == 1
result += children.collect {|child| child.descendants(depth-1)}.flatten
end
result
end end
# Returns list of descendants and a reference to the current node. # Returns list of descendants and a reference to the current node.
# #
# root.self_and_descendants # => [root, child1, subchild1, subchild2] # root.self_and_descendants # => [root, child1, subchild1, subchild2]
def self_and_descendants def self_and_descendants(depth=nil)
[self] + descendants [self] + descendants(depth)
end end
# Returns the root node of the tree. # Returns the root node of the tree.

View File

@ -183,7 +183,9 @@ module Redmine
" !{{child_pages(Foo)}} -- lists all children of page Foo\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" " !{{child_pages(Foo, parent=1)}} -- same as above with a link to page Foo"
macro :child_pages do |obj, args| macro :child_pages do |obj, args|
args, options = extract_macro_options(args, :parent) args, options = extract_macro_options(args, :parent, :depth)
options[:depth] = options[:depth].to_i if options[:depth].present?
page = nil page = nil
if args.size > 0 if args.size > 0
page = Wiki.find_page(args.first.to_s, :project => @project) page = Wiki.find_page(args.first.to_s, :project => @project)
@ -193,7 +195,7 @@ module Redmine
raise 'With no argument, this macro can be called from wiki pages only.' raise 'With no argument, this macro can be called from wiki pages only.'
end end
raise 'Page not found' if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) 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) pages = page.self_and_descendants(options[:depth]).group_by(&:parent_id)
render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id) render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id)
end end

View File

@ -76,3 +76,10 @@ wiki_pages_011:
wiki_id: 1 wiki_id: 1
protected: false protected: false
parent_id: parent_id:
wiki_pages_012:
created_on: 2007-03-08 00:18:07 +01:00
title: Child_1_1
id: 12
wiki_id: 1
protected: false
parent_id: 5

View File

@ -182,7 +182,8 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
def test_macro_child_pages def test_macro_child_pages
expected = "<p><ul class=\"pages-hierarchy\">\n" + expected = "<p><ul class=\"pages-hierarchy\">\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" + "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
"<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" + "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
"</ul>\n</p>" "</ul>\n</p>"
@ -196,11 +197,12 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content) assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page)}}", :object => WikiPage.find(1).content)
end end
def test_macro_child_pages_with_option def test_macro_child_pages_with_parent_option
expected = "<p><ul class=\"pages-hierarchy\">\n" + expected = "<p><ul class=\"pages-hierarchy\">\n" +
"<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" + "<li><a href=\"/projects/ecookbook/wiki/Another_page\">Another page</a>\n" +
"<ul class=\"pages-hierarchy\">\n" + "<ul class=\"pages-hierarchy\">\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" + "<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a>\n" +
"<ul class=\"pages-hierarchy\">\n<li><a href=\"/projects/ecookbook/wiki/Child_1_1\">Child 1 1</a></li>\n</ul>\n</li>\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" + "<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
"</ul>\n</li>\n</ul>\n</p>" "</ul>\n</li>\n</ul>\n</p>"
@ -214,6 +216,16 @@ class Redmine::WikiFormatting::MacrosTest < ActionView::TestCase
assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content) assert_equal expected, textilizable("{{child_pages(ecookbook:Another_page, parent=1)}}", :object => WikiPage.find(1).content)
end end
def test_macro_child_pages_with_depth_option
expected = "<p><ul class=\"pages-hierarchy\">\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_1\">Child 1</a></li>\n" +
"<li><a href=\"/projects/ecookbook/wiki/Child_2\">Child 2</a></li>\n" +
"</ul>\n</p>"
@project = Project.find(1)
assert_equal expected, textilizable("{{child_pages(depth=1)}}", :object => WikiPage.find(2).content)
end
def test_macro_child_pages_without_wiki_page_should_fail def test_macro_child_pages_without_wiki_page_should_fail
assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}") assert_match /can be called from wiki pages only/, textilizable("{{child_pages}}")
end end

View File

@ -131,4 +131,22 @@ class WikiPageTest < ActiveSupport::TestCase
assert_equal Time.gm(2007, 3, 6, 23, 10, 51), page.content.updated_on assert_equal Time.gm(2007, 3, 6, 23, 10, 51), page.content.updated_on
assert_equal page.content.updated_on, page.updated_on assert_equal page.content.updated_on, page.updated_on
end end
def test_descendants
page = WikiPage.create!(:wiki => @wiki, :title => 'Parent')
child1 = WikiPage.create!(:wiki => @wiki, :title => 'Child1', :parent => page)
child11 = WikiPage.create!(:wiki => @wiki, :title => 'Child11', :parent => child1)
child111 = WikiPage.create!(:wiki => @wiki, :title => 'Child111', :parent => child11)
child2 = WikiPage.create!(:wiki => @wiki, :title => 'Child2', :parent => page)
assert_equal %w(Child1 Child11 Child111 Child2), page.descendants.map(&:title).sort
assert_equal %w(Child1 Child11 Child111 Child2), page.descendants(nil).map(&:title).sort
assert_equal %w(Child1 Child11 Child2), page.descendants(2).map(&:title).sort
assert_equal %w(Child1 Child2), page.descendants(1).map(&:title).sort
assert_equal %w(Child1 Child11 Child111 Child2 Parent), page.self_and_descendants.map(&:title).sort
assert_equal %w(Child1 Child11 Child111 Child2 Parent), page.self_and_descendants(nil).map(&:title).sort
assert_equal %w(Child1 Child11 Child2 Parent), page.self_and_descendants(2).map(&:title).sort
assert_equal %w(Child1 Child2 Parent), page.self_and_descendants(1).map(&:title).sort
end
end end