Bug #2179
Updated by liaham 9 months ago
## Problem Exporting a wiki pages has broken links in pdf and html format when macro `child_pages` is in use. ### PDF Export * Exporting to **pdf** gives nonexecutable links for child pages. It does not matter if a single page will be exported or all wiki pages at once. A wiki link in contrast (`[[First-child-page]]`) is integrated as absolute url to the wiki page in the Redmine instance. ### HTML Export * Exporting of a single wiki page to **html** gives relative URLs as child pages links such that `file:///projects/ecookbook/wiki/First-child-page`. In contrast a wiki link to where the same page written like so `[[First-child-page]]` gives a link to the page as if it would be stored local too. The link looks like `file://First-child-page.html`. * Exporting all wiki pages into a single html document behaves as expected. All links are anchors in the document. The user can jump to whatever section she likes. Even the wikis table of content macro `child_pages` is exported. This is perfect. ### How to reproduce? You can reproduce the behavior by importing the attached patch files and trying the exports as follows: * PDF: * single page (main page is enough) * all pages (got to *index by title* page first and export then) * HTML: * single page (both main page and child page) * all pages (got to *index by title* page first and export then) ## Reason The reason for these broken used links is the definition of the `href` variable in the method `ApplicationHelper#render_page_hierarchy`. This is the method with Redmine trunk (https://svn.redmine.org/redmine/trunk@22902): ```ruby def render_page_hierarchy(pages, node=nil, options={}) content = +'' if pages[node] content << "<ul class=\"pages-hierarchy\">\n" pages[node].each do |page| content << "<li>" if controller.controller_name == 'wiki' && controller.action_name == 'export' href = "##{page.title}" # <-- problematic definition else href = {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil} # <-- problematic definition end content << link_to( h(page.pretty_title), href, :title => (if options[:timestamp] && page.updated_on l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) else nil end) ) content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id] content << "</li>\n" end content << "</ul>\n" end content.html_safe end ``` ## Solution (proposal) ### PDF Export Anchor links in a text transformed to pdf created by the gem rbpdf do not align with pdf bookmarks. Therefore, I would like to put forward the proposal to integrate child pages links the same way as wiki links, hence, as absolute URL to the Redmine instance wiki page. macro are broken. This should apply to both single wiki page export and all wiki page export to pdf. Exporting to a single html page should integrate the link as local link instead which would be the same as for wiki links in a single page export to html. The code below will considers these link formats: ```ruby def render_page_hierarchy(pages, node=nil, options={}) content = +'' if pages[node] content << "<ul class=\"pages-hierarchy\">\n" pages[node].each do |page| content << "<li>" href = if controller.request.format.pdf? # absolute link for pdf export of single page or all pages in a single document options[:target] = '_blank' options[:rel] = 'noopener' project_wiki_page_url(project_id: page.project, id: page.title, version: nil) elsif controller.params[:format] == 'html' && controller.action_name == 'export' # relative link for to html export of all pages in a single document "##{page.title}" elsif controller.params[:format] == 'html' # absolute for html export of single page "#{h(page.pretty_title)}.html" else # link handling for rendering pages in UI {:controller => 'wiki', :action => 'show', :project_id => page.project, :id => page.title, :version => nil} end content << link_to( h(page.pretty_title), href, :target => options[:target], :rel => options[:rel], :title => (if options[:timestamp] && page.updated_on l(:label_updated_time, distance_of_time_in_words(Time.now, page.updated_on)) else nil end) ) content << "\n" + render_page_hierarchy(pages, page.id, options) if pages[page.id] content << "</li>\n" end content << "</ul>\n" end content.html_safe end links are working. ``` The patch file contains also some test changes and additional tests. Reason: `ApplicationHelper#parse_non_pre_blocks` returns relative links when resolving `child_pages` macro.