diff --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb index a2acd07eb..8bae09fdc 100644 --- a/lib/redmine/wiki_formatting/macros.rb +++ b/lib/redmine/wiki_formatting/macros.rb @@ -213,6 +213,40 @@ module Redmine render_page_hierarchy(pages, options[:parent] ? page.parent_id : page.id) end + desc "Displays a list of recently updated Wiki pages. With no argument, it displays pages that have been updated within the past 7 days. Examples:\n\n" + + "{{recent_pages}} -- displays pages updated within the past 7 days\n" + + "{{recent_pages(days=3)}} -- displays pages updated within the past 3 days\n" + + "{{recent_pages(limit=5)}} -- limits the maximum number of pages to display to 5\n" + + "{{recent_pages(time=true)}} -- displays pages updated within the past 5 days with updated time" + + macro :recent_pages do |obj, args| + return '' if @project.nil? + return '' unless User.current.allowed_to?(:view_wiki_pages, @project) + + args, options = extract_macro_options(args, :days, :limit, :time) + days_to_list = (options[:days].presence || 7).to_i + limit = options[:limit].to_i if options[:limit].present? + is_show_time = options[:time].to_s == 'true' + + pages = WikiPage. + joins(:content, :wiki). + where(["#{Wiki.table_name}.project_id = ? AND #{WikiContent.table_name}.updated_on >= ?", @project.id, days_to_list.days.ago]). + order("#{WikiContent.table_name}.updated_on desc, id"). + limit(limit) + + tag.ul do + pages.each do |page| + concat( + tag.li do + html = link_to(h(page.pretty_title), project_wiki_page_path(@project, page.title)) + html << " (#{time_ago_in_words(page.content.updated_on)})" if is_show_time + html + end + ) + end + end + end + desc "Includes a wiki page. Examples:\n\n" + "{{include(Foo)}}\n" + "{{include(projectname:Foo)}} -- to include a page of a specific project wiki" diff --git a/test/unit/lib/redmine/wiki_formatting/macros_test.rb b/test/unit/lib/redmine/wiki_formatting/macros_test.rb index 04781ca21..ad5faa09e 100644 --- a/test/unit/lib/redmine/wiki_formatting/macros_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/macros_test.rb @@ -502,4 +502,71 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest ) end end + + def test_recent_pages_macro + @project = Project.find(1) + freeze_time do + WikiContent.update_all(updated_on: Time.current) + @project.wiki.pages.each_with_index do |page, i| + page.content.update_attribute(:updated_on, (i + 1).days.ago) + end + + with_settings :text_formatting => 'textile' do + result = textilizable('{{recent_pages}}') + assert_select_in result, 'ul>li', :count => 7 + assert_select_in result, 'ul>li:first-of-type', :text => 'Another page' + assert_select_in result, 'ul>li:last-of-type', :text => 'Page with sections' + end + end + end + + def test_recent_pages_macro_with_limit_option + @project = Project.find(1) + freeze_time do + WikiContent.update_all(updated_on: Time.current) + @project.wiki.pages.each_with_index do |page, i| + page.content.update_attribute(:updated_on, (i + 1).days.ago) + end + + with_settings :text_formatting => 'textile' do + result = textilizable('{{recent_pages(limit=5)}}') + assert_select_in result, 'ul>li', :count => 5 + assert_select_in result, 'ul>li:first-of-type', :text => 'Another page' + assert_select_in result, 'ul>li:last-of-type', :text => 'CookBook documentation' + end + end + end + + def test_recent_pages_macro_with_time_option + @project = Project.find(1) + WikiContent.update_all(updated_on: Time.current) + freeze_time do + @project.wiki.pages.each_with_index do |page, i| + page.content.update_attribute(:updated_on, (i + 1).days.ago) + end + + with_settings :text_formatting => 'textile' do + result = textilizable('{{recent_pages(time=true)}}') + assert_select_in result, 'ul>li:first-of-type', :text => 'Another page (1 day)' + assert_select_in result, 'ul>li:last-of-type', :text => 'Page with sections (7 days)' + end + end + end + + def test_recent_pages_macro_with_days_option + @project = Project.find(1) + freeze_time do + WikiContent.update_all(updated_on: Time.current) + @project.wiki.pages.each_with_index do |page, i| + page.content.update_attribute(:updated_on, (i + 1).days.ago) + end + + with_settings :text_formatting => 'textile' do + result = textilizable('{{recent_pages(time=true, days=3)}}') + assert_select_in result, 'ul>li', :count => 3 + assert_select_in result, 'ul>li:first-of-type', :text => 'Another page (1 day)' + assert_select_in result, 'ul>li:last-of-type', :text => 'Child 1 1 (3 days)' + end + end + end end