Extension:CategoryFunctions

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

Release status: stable

Implementation Parser function
Description Two parser functions to see if a page belongs to a given category
Author(s) Thomas Bleher (Tblehertalk)
Latest version 1.0 (2007-11-30)
MediaWiki 1.11+
License GPL
Download See code section
Hooks used
LanguageGetMagic

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

Check usage and version matrix; code metrics

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 | edit source]

{{#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 | edit source]

  • Copy the code and extract the tarball in your extensions/ folder. It should generate a new folder called CategoryFunctions directly inside your extensions/ folder.
  • Add the following code at the bottom of your LocalSettings.php:
require_once "$IP/extensions/CategoryFunctions/CategoryFunctions.php";
  • Done! Navigate to "Special:Version" on your wiki to verify that the extension is successfully installed.

Code[edit | edit source]

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 | edit source]