Extension:CategoryFunctions

From MediaWiki.org
Jump to: navigation, search
MediaWiki extensions manualManual:Extensions
Crystal Clear action run.png
CategoryFunctions

Release status:Extension status stable

ImplementationTemplate:Extension#type Parser function
DescriptionTemplate:Extension#description Two parser functions to see if a page belongs to a given category
Author(s)Template:Extension#username Thomas Bleher (Tblehertalk)
Latest versionTemplate:Extension#version 1.0 (2007-11-30)
MediaWikiTemplate:Extension#mediawiki 1.11+
LicenseTemplate:Extension#license GPL
Download See code section
Hooks usedTemplate:Extension#hook
LanguageGetMagicManual:Hooks/LanguageGetMagic

Translate the CategoryFunctions extension if it is available at translatewiki.net

Check usage and version matrix.

The CategoryFunctions extension can be used to display text depending on whether a page is in a given category or not.

This example (taken from [1]) shows what you can do with Extension:Semantic MediaWiki and this extension. Both the images and the crosses are generated purely from category information. The templates used are [2] and [3].


Usage[edit]

{{#inCategory:SomePage|SomeCategory|✘| }}
{{#inCatMulti:SomePage|{{!}}{{!}}|6-8,✘;9-12M,9-12J,✘;13-15M,13-15J,✘;15+J,15+M,✘| }}

The first function should be quite clear: It tests if SomePage is in SomeCategory. If yes, it outputs ✘, otherwise  .

The second function could be expressed using the first, but it is provided for convenience and speed, as it makes queries for lots of categories faster and easier. The parameters are a bit switched:

  • The first is again the pagename.
  • The second is the separator between the different return values.
  • The third parameter is the query list + associated return values. It is split first at the ";" into different queries; each part is then split at the ",". All but the last parts are names of categories and the last part is returned in case the page is in one category.
  • Finally, the last parameter is the value that is inserted in case the page is not in a given category.

An example:
We take again the query {{#inCatMulti:SomePage|{{!}}{{!}}|6-8,✘;9-12M,9-12J,✘;13-15M,13-15J,✘;15+J,15+M,✘| }}. Assume that SomePage belongs to categories 9-12M, 13-15M and 13-15J. Then the parser function returns the following value:  ||✘||✘|| .

Installation[edit]

  • Copy the code and place the file(s) in a directory called CategoryFunctions in your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php:
    require_once "$IP/extensions/CategoryFunctions/CategoryFunctions.php";
    
  • YesY Done - Navigate to Special:Version on your wiki to verify that the extension is successfully installed.

Code[edit]

CategoryFunctions.php
<?php

# Check if we are being called directly
if ( !defined( 'MEDIAWIKI' ) ) {
        die( 'This file is an extension to MediaWiki and thus not a valid entry point.' );
}

# Define a setup function
$wgExtensionFunctions[] = 'wfCategoryFunction_Setup';

# Add a hook to initialise the magic word
$wgHooks['LanguageGetMagic'][] = 'wfCategoryFunction_Magic';
$wgExtensionCredits['parserhook'][] = array(
        'name' => 'CategoryFunctions',
        'author' => 'Thomas Bleher',
        'version' => '1.0',
        'url' => 'https://www.mediawiki.org/wiki/Extension:CategoryFunctions',
        'description' => 'Two Parserfunctions to see if a page is in a given category',
);

function wfCategoryFunction_Setup() {
        global $wgParser;
        $wgParser->setFunctionHook( 'inCategory', 'wfCategoryFunction_inCategory' );
        $wgParser->setFunctionHook( 'inCatMulti', 'wfCategoryFunction_inCatMulti' );
}

function wfCategoryFunction_Magic( &$magicWords, $langCode ) {
        # Add the magic word
        # The first array element is case sensitive, in this case it is not case sensitive
        # All remaining elements are synonyms for our parser function
        $magicWords['inCategory'] = array( 0, 'inCategory' );
        $magicWords['inCatMulti'] = array( 0, 'inCatMulti' );
        # unless we return true, other parser functions extensions won't get loaded.
        return true;
}

function wfCategoryFunction_inCategory( &$parser, $title = '', $category = '', $then = '', $else = '' ) {
        wfProfileIn( __METHOD__ );
        if (!(strpos($title, "[[") === false)) {
                preg_match("/\[\[([^\|\]]+)/", $title, $matches);
                $title = $matches[1];
        }
        $title = Title::newFromText( $title );
        $category = Title::newFromText( $category );
        if ((!is_object( $title )) || (!$title->exists()) || (!is_object( $category )) || (!$category->exists())) {
                wfProfileOut( __METHOD__ );
                return $else;
        }

        $dbr = wfGetDB( DB_SLAVE );
        $tables = array( 'categorylinks' );
        $where_clauses = array(
                'cl_from' => $title->getArticleID(),
                'cl_to'   => $category->getDBkey()
        );
        $cols = array( 'cl_from' );

        $res = $dbr->select ( $tables, $cols, $where_clauses, __METHOD__  ) ;
        $result = ($dbr->numRows($res) > 0) ? $then : $else;
        wfProfileOut( __METHOD__ );
        return $result;
}

function wfCategoryFunction_inCatMulti( &$parser, $title = '', $sep = '', $text = '', $else = '' ) {
        wfProfileIn( __METHOD__ );
        if (!(strpos($title, "[[") === false)) {
                preg_match("/\[\[([^\|\]]+)/", $title, $matches);
                $title = $matches[1];
        }
        $title = Title::newFromText( $title );
        if( !is_object( $title ) || !$title->exists() ) {
                wfProfileOut( __METHOD__ );
                return $else;
        }

        $dbr = wfGetDB( DB_SLAVE );
        $tables = array( 'categorylinks' );
        $where_clauses = array(
                'cl_from' => $title->getArticleID(),
        );
        $cols = array( 'cl_to' );

        $res = $dbr->select ( $tables, $cols, $where_clauses, __METHOD__ );

        if($dbr->numRows($res) == 0) {
                wfProfileOut( __METHOD__ );
                return $else;
        }

        while ( $x = $dbr->fetchObject ( $res ) )
                $data[$x->cl_to] = 1;
        $dbr->freeResult ( $res ) ;

        $ret = '';
        $first = true;
        $exploded = explode ( ";", $text );
        foreach ( $exploded as $current ) {
                $array = explode( ",", $current );
                $out = array_pop( $array );
                if( $first )
                        $first = false;
                else
                        $ret .= $sep;

                $found = false;
                foreach ( $array as $cat ) {
                        if ( array_key_exists( $cat, $data ) ) {
                                $ret .= $out;
                                $found = true;
                                break; // only out of the inner foreach
                        }
                }
                if( !$found )
                        $ret .= $else;
        }
        wfProfileOut( __METHOD__ );
        return $ret;
}

See also[edit]