From mediawiki.org
Jump to navigation Jump to search
MediaWiki extensions manual
OOjs UI icon advanced.svg
Release status: unmaintained
Implementation Parser extension , Parser function
Description Create id attribute values using a similar mechanism that headers use
Author(s) David M. Sledge
Latest version 0.7.0 (2007-12-07)
MediaWiki 1.11.0+
License GNU General Public License 2.0 or later
Download See instructions

Check usage and version matrix.


One thing about wiki headers is that, with the following:

==='''[[some page|Header Text]] More ''Text'''''===

MediaWiki is smart enough to strip out all the markup and hyper-linking from the text to create an anchor with the name "Header_Text_More_Text." However, it's been found that sometimes this mechanism is desired outside the headers, because, although, it does a great job making destination anchors, one doesn't necessarily want every destination anchor showing up in the TOC. And though you can manually create the destination anchor like so:

<span id="Header Text More Text">'''[[some page|Header Text]] More ''Text'''''</span>

Some of us are just plain lazy. This is where this simple little extension comes into play.


{{#anc: wikitext [| count ]}}

Where count is 0 or any positive integer. It specifies the number of wiki-headers that already have "wikitext". This is needed because there no way for the extension to know what IDs are already in use. (See bugzilla:7356.)


{{#anc: '''Runnin' Down''' [[A Dream]] }}

gives Runnin' Down A Dream where the ID of the surrounding span tag is Runnin.27_Down_A_Dream. So if I want to link to that section I can just copy the text and paste into a wiki-syntax link:

[[#Runnin' Down A Dream|Link!  Damn you!]]

yields Link! Damn you!.

Specifying count as "4"

{{#anc: '''Runnin' Down''' [[A Dream]] | 4 }}

gives the id as Runnin.27_Down_A_Dream_5 without changing the displayed text.

Don't Templates Like Anchor Already Do This?[edit]

The template doesn't strip out any markup. So if a template named Template:Anchor were used whose content is

<span id="{{{id|{{{1}}}}}}">{{{1}}}</span>

using the above example like so

{{anchor|'''Runnin' Down''' [[A Dream]]}}

would give the id as .27.27.27Runnin.27_Down.27.27.27_.5B.5BA_Dream.5D.5D.

Known Issues[edit]

Download instructions[edit]

Please cut and paste the code found below and place it in $IP/extensions/AutoAnchor/AutoAnchor.php and $IP/extensions/AutoAnchor/AutoAnchor.i18n.php. Note: $IP stands for the root directory of your MediaWiki installation, the same directory that holds LocalSettings.php .


To install this extension, add the following to LocalSettings.php :





$wgExtensionFunctions[] = array( 'ExtAutoAnchor', 'setup' );
$wgHooks['LanguageGetMagic'][] = 'ExtAutoAnchor::languageGetMagic';
$wgExtensionCredits['parserhook'][] = array(
    'name' => 'Auto-Anchor Extension',
    'author' => 'David M. Sledge',
    "url"    => "http://www.mediawiki.org/wiki/Extension:Auto-Anchor",
    'version' => ExtAutoAnchor::VERSION,
    "description" => "Create header-like anchors IDs without headers",

class ExtAutoAnchor
    const VERSION = '0.7.0';
    public static $ids = array();

    public static function setup()
        global $wgParser;

        $wgParser->setFunctionHook( 'anc', array( __CLASS__, 'autoAnchor' ) );

    public static function languageGetMagic( &$magicWords, $langCode )
        require_once( dirname( __FILE__ ) . '/AutoAnchor.i18n.php' );

        foreach( AutoAnchor_i18n::magicWords( $langCode ) as $word => $trans )
            $magicWords[$word] = $trans;

        return true;

    public static function autoAnchor( &$parser, $input, $count = '0' )
        // need some input to make the id
        if ( $input === '' )
            // error:  no input
            return '';

        // get the value of the 'count' attribute  This attribute indicates the
        // number of wiki headers that use this text.  This extension is unable
        // to get that information itself so it must be supplied by the user; if
        // not specified, it defaults to 0.
        $count = intval( $attrs["count"] );

        // make sure it's not less than 0
        if ( $count < 0 )
            $count = 0;

        // parse the input
        $parsedInput = $parser->recursiveTagParse( $input );
        // strip out the encoded link to get the displayed text which
        // will be used to generate the span tag's id attribute value.
        $id = $parser->replaceLinkHoldersText( $parsedInput );
        // strip out any HTML markup
        $id = trim( preg_replace( '/<.*?>/m', '', $id ) );
        // escape the string so it contains valid
        // characters for the id attribute
        $id = Sanitizer::escapeId( $id, Sanitizer::NONE );
        // make sure the ID is unique
        $id = self::getUniqueID( $id, $count );
        // put it all together
        $spanid = "<span id=\"$id\">$input</span>";

        return $spanid;

    // known limitation:  MediaWiki currently (v1.11.0) has no mechanism for
    // enforcing id-uniqueness within an article, so it's entirely possible that
    // another HTML tag will have the same id attribute value as the ones
    // supplied by this method.  We can however, enforce uniqueness the with IDs
    // generated within this extension
    private static function getUniqueID( $id, $count )

        // if this isn't the first instance of this id, we append the number of
        // this instance to the id:  "wikitext_2", "wikitext_3",
        // "wikitext_4",... "wikitext_n".
        if ( in_array( $count == 1 ? $id : $id . '_' . $count, self::$ids ) )
            // of course we have to make sure "wikitext_x" doesn't already exist
            // if it does, we increment x by one until we hit an id that doesn't
            // exist yet
            for ( $count++; in_array( $id . '_' . $count, self::$ids ); $count++ ) ;

            self::$ids[] = $id . '_' . $count;

            return end( self::$ids );

        self::$ids[] = $count == 1 ? $id : $id . '_' . $count;

        return end( self::$ids );



class AutoAnchor_i18n
    private static $words = array(
    // English
        'en' => array(
            'anc'  => array( 0, 'anc' ),

    private static $messages = array(
    // English
        'en' => array(),

    public static function getMessages()
        return self::$messages;

     * Get translated magic words, if available
     * @param string $lang Language code
     * @return array
    public static function magicWords( $lang )
        // English is used as a fallback, and the English synonyms are
        // used if a translation has not been provided for a given word
        return ( $lang == 'en' || !isset( self::$words[$lang] ) ) ?
            self::$words['en'] :
            array_merge( self::$words['en'], self::$words[$lang] );

See also[edit]