You are here: Foswiki>Tasks Web>Item14032 (31 Jan 2018, GeorgeClark)Edit Attach

Item14032: INCLUDE doesn't rewrite other webs' links in 2.1.

pencil
Priority: Normal
Current State: Closed
Released In: 2.1.1
Target Release: patch
Applies To: Engine
Component: INCLUDE
Branches: master Release02x01 Item14033 Item13897 Item14380 Item14537
Reported By: AaronHall
Waiting For:
Last Change By: GeorgeClark
When using INCLUDE to include a page from another web, links are not being rewritten to point to the originating web.

For example: I've got a page in the SysNet web and I want to include part of it from another web (I've tested this in a subweb and Sandbox). The INCLUDE looks like:

%INCLUDE{"SysNet.WSUS"}%

And the included part of the SysNet.WSUS page is this. (I'm using the different link types as an example.)

%STARTINCLUDE%
   * WindowsPatchingSchedule, including proposed revisions
   * [[Special Windows Systems Patching]] -- Odyssey and Micros
%ENDINCLUDE%

The links are not at all rewritten to refer to SysNet/WindowsPatchingSchedule or SysNet/SpecialWindowsSystemsPatching. There are no web specifiers, so I get a link like this /bin/edit/Sandbox/WindowsPatchingSchedule?topicparent=Sandbox.WSUSIncludeTest.

On a hunch, I looked at the GitHub history for INCLUDE.pm and it seems that 79f1f42 touches that code. I manually subbed in the INCLUDE.pm from 060fcbc and then the [[Bracket Notation]] link works, but not the WikiWord link. I don't know enough to submit a patch, but hopefully that gives you a lead. I'd classify this as Urgent, but for my installation I can hack around it with the old INCLUDE.pm and bracket notation for now.

-- AaronHall - 22 Mar 2016

Okay, great report. There are two bugs here:
  1. The trailing comma on the first bullet is breaking the regex that fixes up standalone wikiwords. (This is broken in Foswiki 1.1.9 as well).
  2. The code that checks for "valid topics" doesn't run the algorithm to convert a spaced wikiword into a topic name.

Should be easy enough to fix for Foswiki 2.1.1

-- GeorgeClark - 23 Mar 2016

Actually it's got more issues, comparing the regexes we use for WikiWord in Foswiki::Render, add to this list:
  • If the link is an ACRONYM, it won't be fixed.
  • If the link has an anchor SomeTopic#head2, it will also be missed
Fixing these makes it a bit more complex. The following patch seems to work:

diff --git a/core/lib/Foswiki/Macros/INCLUDE.pm b/core/lib/Foswiki/Macros/INCLUDE.pm
index 47d641f..bdd3fa2 100644
--- a/core/lib/Foswiki/Macros/INCLUDE.pm
+++ b/core/lib/Foswiki/Macros/INCLUDE.pm
@@ -4,6 +4,9 @@ package Foswiki;
 use strict;
 use warnings;
 
+use Foswiki::Render;
+use Foswiki::Func;
+
 BEGIN {
     if ( $Foswiki::cfg{UseLocale} ) {
         require locale;
@@ -53,8 +56,23 @@ sub _fixupIncludedTopic {
     unless ( $options->{Pref_NOAUTOLINK} || $options->{in_noautolink} ) {
 
         # 'TopicName' to 'Web.TopicName'
-        $text =~
-s#(?:^|(?<=[\s(]))($Foswiki::regex{wikiWordRegex})(?=\s|\)|$)#$fromWeb.$1#g;
+        $text =~ s{
+              $Foswiki::Render::STARTWW
+              (
+               (:? $Foswiki::regex{wikiWordRegex})    # Wikiword
+               (:?$Foswiki::regex{anchorRegex})?      # Optional anchor
+              )
+              $Foswiki::Render::ENDWW
+           }
+           {$fromWeb.$1}gx;
+
+        $text =~ s{
+              $Foswiki::Render::STARTWW
+               ($Foswiki::regex{abbrevRegex})      # Acronym
+               ($Foswiki::regex{anchorRegex})?     # Optional anchor
+              $Foswiki::Render::ENDWW
+           }
+           {_fixAcronymLink($fromWeb,$1,$2)}gex;
     }
 
     # Handle explicit [[]] everywhere
@@ -65,6 +83,17 @@ s#(?:^|(?<=[\s(]))($Foswiki::regex{wikiWordRegex})(?=\s|\)|$)#$fromWeb.$1#g;
     return $text;
 }
 
+sub _fixAcronymLink {
+    my $anchor = $_[2] || '';
+
+    if ( Foswiki::Func::topicExists( $_[0], $_[1] ) ) {
+        return "$_[0].$_[1]$anchor";
+    }
+    else {
+        return "$_[1]$anchor";
+    }
+}
+
 # Add a web reference to a [[...][...]] link in an included topic
 sub _fixIncludeLink {
     my ( $web, $link, $label ) = @_;
@@ -90,6 +119,10 @@ m#^($Foswiki::regex{webNameRegex}\.|$Foswiki::regex{defaultWebNameRegex}\.|$Fosw
     # If link is only an anchor, leave it as is (Foswikitask:Item771)
     return "[[$link][$label]]" if $link =~ m/^#/;
 
+    # Collapse a spaced out wikiword
+    $link = ucfirst($link);
+    $link =~ s/\s([[:alnum:]])/\U$1/g;
+
     if ( Foswiki::isValidTopicName( $link, 1 ) ) {
         return "[[$web.$link][$label]]";
     }

-- GeorgeClark - 23 Mar 2016

That seems to work for me. Thanks!

-- AaronHall - 23 Mar 2016
 
Topic revision: r10 - 31 Jan 2018, GeorgeClark
The copyright of the content on this website is held by the contributing authors, except where stated elsewhere. See Copyright Statement. Creative Commons License    Legal Imprint    Privacy Policy