From e02e6e9588acc8a9dff9c3fefafd5300c89c0a7f Mon Sep 17 00:00:00 2001 From: ishikawa999 Date: Wed, 17 Dec 2025 01:40:57 +0000 Subject: [PATCH] Fix include and recent_pages macros --- app/helpers/application_helper.rb | 4 -- app/helpers/projects_helper.rb | 2 +- lib/redmine/wiki_formatting/macros.rb | 16 ++++-- test/integration/projects_test.rb | 39 ++++++++++++++ .../redmine/wiki_formatting/macros_test.rb | 51 +++++++++++++++++++ 5 files changed, 102 insertions(+), 10 deletions(-) diff --git a/app/helpers/application_helper.rb b/app/helpers/application_helper.rb index 1180d4427..48373f72a 100644 --- a/app/helpers/application_helper.rb +++ b/app/helpers/application_helper.rb @@ -459,10 +459,7 @@ module ApplicationHelper s = +'' if projects.any? ancestors = [] - original_project = @project projects.sort_by(&:lft).each do |project| - # set the project environment to please macros. - @project = project if ancestors.empty? || project.is_descendant_of?(ancestors.last) s << "\n" * ancestors.size) - @project = original_project end s.html_safe end diff --git a/app/helpers/projects_helper.rb b/app/helpers/projects_helper.rb index bae1c4e3a..f079c743a 100644 --- a/app/helpers/projects_helper.rb +++ b/app/helpers/projects_helper.rb @@ -83,7 +83,7 @@ module ProjectsHelper s << tag.span(sprite_icon('user', l(:label_my_projects), icon_only: true), class: 'icon-only icon-user my-project') if User.current.member_of?(project) s << tag.span(sprite_icon('bookmarked', l(:label_my_bookmarks), icon_only: true), class: 'icon-only icon-bookmarked-project') if bookmarked_project_ids.include?(project.id) if project.description.present? - s << content_tag('div', textilizable(project.short_description, :project => project), :class => 'wiki description') + s << content_tag('div', textilizable(project, :short_description, :project => project), :class => 'wiki description') end s end diff --git a/lib/redmine/wiki_formatting/macros.rb b/lib/redmine/wiki_formatting/macros.rb index 8ac0011f6..dbc29d20c 100644 --- a/lib/redmine/wiki_formatting/macros.rb +++ b/lib/redmine/wiki_formatting/macros.rb @@ -65,6 +65,10 @@ module Redmine end return [args, options] end + + def current_project(obj) + @project || (obj.is_a?(Project) && obj) || (obj.respond_to?(:project) && obj.project) + end end @@available_macros = {} @@ -223,8 +227,9 @@ module Redmine "{{recent_pages(time=true)}} -- displays pages updated within the last 7 days with updated time" macro :recent_pages do |obj, args| - return '' if @project.nil? - return '' unless User.current.allowed_to?(:view_wiki_pages, @project) + project = current_project(obj) + 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 @@ -233,7 +238,7 @@ module Redmine pages = WikiPage. joins(:content, :wiki). - where(["#{Wiki.table_name}.project_id = ? AND #{WikiContent.table_name}.updated_on >= ?", @project.id, days_to_list.days.ago]). + 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) @@ -241,7 +246,7 @@ module Redmine pages.each do |page| concat( tag.li do - html = link_to(h(page.pretty_title), project_wiki_page_path(@project, page.title)) + 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 @@ -254,7 +259,8 @@ module Redmine "{{include(Foo)}}\n" + "{{include(projectname:Foo)}} -- to include a page of a specific project wiki" macro :include do |obj, args| - page = Wiki.find_page(args.first.to_s, :project => @project) + project = current_project(obj) + page = Wiki.find_page(args.first.to_s, :project => project) raise t(:error_page_not_found) if page.nil? || !User.current.allowed_to?(:view_wiki_pages, page.wiki.project) @included_wiki_pages ||= [] diff --git a/test/integration/projects_test.rb b/test/integration/projects_test.rb index 35a39cfce..96519a14e 100644 --- a/test/integration/projects_test.rb +++ b/test/integration/projects_test.rb @@ -68,4 +68,43 @@ class ProjectsTest < Redmine::IntegrationTest assert_select 'td.buttons', text: '' end end + + def test_index_should_render_include_macro_in_short_description + project = Project.find(1) + project.update!(:description => '{{include(Another page)}}') + + log_user('admin', 'admin') + + get '/projects', :params => {:display_type => 'list'} + assert_response :success + assert_select 'td.short_description div.wiki', :text => /This is a link to a ticket/ + + get '/projects', :params => {:display_type => ''} + assert_response :success + assert_select 'div.wiki.description', :text => /This is a link to a ticket/ + end + + def test_index_should_render_recent_pages_macro_in_short_description + freeze_time do + project = Project.find(1) + project.update!(:description => '{{recent_pages}}') + + 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 + + log_user('admin', 'admin') + + get '/projects', :params => {:display_type => 'list'} + assert_response :success + assert_select 'td.short_description div.wiki ul li a', :count => 7 + assert_select 'td.short_description div.wiki ul li:first a', :text => 'Another page' + + get '/projects', :params => {:display_type => ''} + assert_response :success + assert_select 'div.wiki.description ul li a', :count => 7 + assert_select 'div.wiki.description ul li:first a', :text => 'Another page' + end + end end diff --git a/test/unit/lib/redmine/wiki_formatting/macros_test.rb b/test/unit/lib/redmine/wiki_formatting/macros_test.rb index ed07f77c8..d2997e8eb 100644 --- a/test/unit/lib/redmine/wiki_formatting/macros_test.rb +++ b/test/unit/lib/redmine/wiki_formatting/macros_test.rb @@ -232,6 +232,23 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest assert_include 'Page not found', textilizable(text) end + def test_include_macro_accepts_project_from_multiple_sources + project = Project.find(1) + + # Resolve using the @project + @project = project + assert_include 'This is a link to a ticket', textilizable('{{include(Another page)}}') + @project = nil + + # Resolve using object: project + assert_include 'This is a link to a ticket', textilizable('{{include(Another page)}}', {object: project}) + + # Resolve using issue.project + issue = Issue.first + issue.update(description: '{{include(Another page)}}') + assert_include 'This is a link to a ticket', textilizable(issue, :description) + end + def test_macro_collapse text = "{{collapse\n*Collapsed* block of text\n}}" with_locale 'en' do @@ -517,6 +534,40 @@ class Redmine::WikiFormatting::MacrosTest < Redmine::HelperTest end end + def test_recent_pages_macro_accepts_project_from_multiple_sources + 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 + results = {} + + # Resolve using the @project + @project = project + results[:project_instance_variable] = textilizable('{{recent_pages}}') + @project = nil + + # Resolve using object: project + results[:object_project] = textilizable('{{recent_pages}}', {object: project}) + + # Resolve using issue.project + issue = Issue.first + issue.update(description: '{{recent_pages}}') + results[:issue_argument] = textilizable(issue, :description) + + # Assertions + results.each do |key, result| + assert_select_in result, 'ul>li', {:count => 7}, "[#{key}] unexpected number of list items" + assert_select_in result, 'ul>li:first-of-type', {:text => 'Another page'}, "[#{key}] first list item text mismatch" + assert_select_in result, 'ul>li:last-of-type', {:text => 'Page with sections'}, "[#{key}] last list item text mismatch" + end + end + end + end + def test_recent_pages_macro_with_limit_option @project = Project.find(1) freeze_time do -- 2.52.0