Extension:TernaryPipedLinks

From Linux Web Expert

Ternary Piped Links provides shortcut link markup to avoid repetition in writing piped links in certain common situations. It is a generalization of the "Pipe trick".

MediaWiki extensions manual
Ternary Piped Links
Release status: unmaintained
Implementation Parser extension , Link markup
Description Provides shortcut markup for the link title and the displayed text with a common ending.
Author(s) Miran Božičević (Miranchetalk)
MediaWiki
License GNU General Public License 2.0
Download cut & paste
Quarterly downloads Lua error in Module:Extension at line 172: bad argument #1 to 'inNamespace' (unrecognized namespace name 'skin').
Public wikis using Lua error in Module:Extension at line 172: bad argument #1 to 'inNamespace' (unrecognized namespace name 'skin').

What can this extension do?

The Ternary Piped Links extension extends link markup with a shortcut in situations when the link title and the displayed text have a common ending. The standard so-called "pipe trick" allows for a shortcut for displaying only the part of the wiki name after the first colon. For example, in interwiki links, e.g. to Wikipedia, you do not want every link to display with a "w:" in front, so you type

you do not [[w:want|]] [[w:every|]] [[w:link|]] to [[w:display|]] with a "w:" in [[w:front|]].

MediaWiki takes care of the rest, guessing that you want to drop the "w:". Unfortunately, this trick goes only so far. For example, if you have more than one colon, e.g. if you feel an urge to say that Miranche simply WikiLoves the Pipe trick, you need to type

  1. [[w:User:Miranche|Miranche]] simply [[w:Wikipedia:WikiLove|WikiLove]]s the [[meta:Piped link#Pipe trick|Pipe trick]]

In the same vein, to add some context to a link on the Montenegrin Royal House of Petrović-Njegoš, you need to type

  1. [[w:House of Petrović-Njegoš|Montenegrin Royal House of Petrović-Njegoš]]

Similarly, to simply have a link that says what it does, e.g. "Go to Main Page", you again need to repeat yourself:

  1. [[Main Page|Go to Main Page]]

This extension provides a simple shortcut markup for these situations.

Usage

The link markup is extended to allow for two pipe delimiters, which break the markup text into three parts (hence "ternary"). The parts are, in order,

Title start: the start of the title of link target.
Text start: the start of displayed link text.
Common end: the common ending to both.

The extension turns the ternary link into a regular piped link as follows:

[[<title start>|<text start>|<common end>]]

becomes

[[<title start><common end>|<text start><common end>]]

Examples

In the three above situations:

  1. [[w:User:||Miranche]] simply [[w:Wikipedia:||WikiLove]]s the [[meta:Piped link#||Pipe trick]]
    displays as
    Miranche simply WikiLoves the Pipe trick
  2. [[w:|Montenegrin Royal |House of Petrović-Njegoš]]
    displays as
    Montenegrin Royal House of Petrović-Njegoš
  3. [[|Go to |Main Page]]
    displays as
    Go to Main Page

Limitations

TernaryPipedLinks does not currently allow a way to specify a common beginning between the link title and displayed text, or more generally a common middle. Doing this would require allowing for up to four pipes, dividing the markup into up to five parts, which is not a problem to implement but seems like overkill from UI design POV. However, such a feature would save trouble with some grammatical constructions, and when linking to pages that need to be disambiguated. The "pipe trick" does provide some functionality in this regard, e.g. to display just the movie title in a link to the 1954 adaptation of A Star is Born you only need to type

[[w:A Star is Born (1954)|]]

However, trying a more complicated link, such as the one to the 1954 adaptation of A Star is Born still requires repetition:

[[w:A Star is Born (1954)|the 1954 adaptation of ''A Star is Born'']]

Finally, this extension limits the extent to which the pipe (|) can be used in article titles, though doing so does not look like a good idea in the first place.

Download and Installation

Please cut and paste the code found below and place it in

$IP/extensions/TernaryPipedLinks/TernaryPipedLinks.php

Then add the following to LocalSettings.php :

require_once("$IP/extensions/TernaryPipedLinks/TernaryPipedLinks.php");

Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php .

Code

/*
  MediaWiki extension, provides shortcut markup in Wikitext links.
  Copyright (c) 2010 Miran Bozicevic

  This program is free software; you can redistribute it and/or
  modify it under the terms of the GNU General Public License
  as published by the Free Software Foundation; either version 2
  of the License, or (at your option) any later version.

  This program is distributed in the hope that it will be useful,
  but WITHOUT ANY WARRANTY; without even the implied warranty of
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  GNU General Public License for more details.

  You should have received a copy of the GNU General Public License
  along with this program; if not, write to the Free Software
  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
  USA.
*/

//  Thanks to authors of Extension:FlowchartWiki for the skeleton code.

if( !defined( 'MEDIAWIKI' ) ) {
    echo <<<EOT
This is an extension to the MediaWiki software and cannot be used alone.
To install it, please put the following line in LocalSettings.php:
require_once( "\$IP/extensions/TernaryPipedLinks/TernaryPipedLinks.php" );

EOT;
    exit(1);
}

$wgExtensionCredits['parser'][] = array(
    'name' => 'Ternary Piped Links',
    'author' =>'Miran Božičević',
    'url' => 'http://www.mediawiki.org/wiki/Extension:TernaryPipedLinks',
    'description' => 'Provides shortcut markup for the link title and the displayed text with a common ending.'
                                                     );

//  Parser hook looking for ternary piped links
$wgHooks['InternalParseBeforeLinks'][] = 'efParseTernaryPipedLinks';

//  If a link with two pipes is found, treat it as having three arguments:
//    (1) "title start" : the start of the title of link target
//    (2) "text start"  : the start of displayed link text
//    (3) "common end"  : the common ending to both

//  Combine these arguments into a regular piped link, so
//    [[(1)|(2)|(3)]]  becomes  [[(1)(3)|(2)(3)]]

function efParseTernaryPipedLinks( &$parser, &$text ) {
    $output = $lastch = '';
    $linkStarted = false;
    $len = strlen($text);
    for( $i=0; $i<$len; $i++ ) {
        $ch = $text[$i];

        if ( $ch == '[' && $lastch == '[' ) {
            //  link starts -- register it
            $linkStarted = true;
            $linkDelay = 1;
            $linkText = '';

        } else if ( $ch == ']' && $lastch == ']' ) {
            //  link ends -- check if it's ternary
            $out = "[$linkText]]"; // default: do nothing out of the ordinary
            $linkStarted = false;
            $linkParts = explode('|', $linkText, 3);
            if ( count($linkParts) == 3 ) {
                //  we found two pipes, see if we can put together the ternary link
                list( $titleStart, $textStart, $commonEnd ) = $linkParts;
                $title = Title::newFromText( $titleStart );
                if ( !$title || $title->getNamespace() != NS_FILE )
                    //  not a file link - ok, combine name parts
                    $out = "[$titleStart$commonEnd|$textStart$commonEnd]]";
            }
            $output .= $out;

        } else if ($linkStarted) {
            //  within link text -- keep track of it
            if ( !$linkDelay )
                //  grow link text using the previous character
                //  so we don't have to trim an ending bracket
                $linkText .= $lastch;
            else
                //  wait before growing link text
                //  so we don't have to trim a starting bracket
                --$linkDelay;

        } else {
            //  outside of link text -- pass text through
            $output .= $ch;
        }
        $lastch = $ch;
    }

    if ($linkStarted) {
        //  page ends within putative link text
        $output .= $linkDelay ? '[' : "[$linkText$ch";
    }
    $text = $output;
    return true;
}

See also