User:Robchurch/NCL fixup
Hacked-about version of JohanTheGhost's hacked-about version; this one shouldn't cause problems with the parser chain referencing $wgOut.
<?php /* * Nice Category List extension. * Generates a list of all pages in the category, including subcategories. * Unlike the default category list, the generated list is flat and shows * well, even with long page names. * * Usage: * <ncl [options]>Category:Some Category</ncl> * * The following options are available: * maxdepth Maximum category depth; default 32 * style 'bullet' to show category contents as bullet lists * 'compact' for a more compact listing * showcats Non-0 to display sub-category links in "bottom" (ie. * maxdepth) categories (default 0). * showarts Non-0 to display articles in categories (default 1). * headings 'head' to display category headings as Wiki headings; * 'bullet' to display category headings as large bullets * ('bullet' works well with 'style=compact'). * headstart With 'headings=head', the heading level to list * top-level categories with (level increases for sub-cats). * sort With 'sort=1', the list is sorted alphabetically * else the category index key is used (as usual) * * Examples: * 1. This: * <ncl>Category:Some Category</ncl> * generates a full, recursive listing. * * 2. Use this in a template: * <ncl style=compact maxdepth=2 headings=bullet headstart=2 * showcats=1 showarts=1>Category:{{PAGENAME}}</ncl> * and include it in major category pages to provide a nice 2-level (or however * many you like) index of the category. * * 3. This: * <ncl style=compact headings=bullet headstart=2 showcats=1 * showarts=0>Category:Categories</ncl> * generates a full cagtegory listing, with indentation indicating category * containment. */ if (!defined('MEDIAWIKI')) die(); $wgExtensionFunctions[] = 'wfNiceCategoryList'; $wgExtensionCredits['parserhook'][] = array( 'name'=>'NiceCategoryList', 'author'=>'Kichik', 'url'=>'http://meta.wikimedia.org/wiki/NiceCategoryList_extension', 'description'=>'generate a category page showing all pages in a category, including subcategories', ); /* * Global settings for the Nice Category List extension. */ $wgNiceCategoryListSettings = array( 'maxdepth' => 32, // Sanity stop level. 'style' => 'bullet', // Default style for "leaf" level. 'showcats' => 0, // Non-0 to display sub-cat links in a category. 'showarts' => 1, // Non-0 to display article links in a category. 'headings' => 'head', // Show category headings as headings. 'headstart' => 1, // Heading level to start at. 'sort' => 0, // Non-0 to sort the list alphabetically, else sort the list regarding the index key ); /* * Setup Nice Category List extension. * Sets a parser hook for <ncl></ncl>. */ function wfNiceCategoryList() { global $wgParser; $wgParser->setHook('ncl', 'hookNiceCategoryList'); } /* * The hook function. Handles <ncl></ncl>. * Receives the category name as a parameter. */ function hookNiceCategoryList($category, $argv, &$parser) { global $wgNiceCategoryListSettings; // Get any user-specified parameters. foreach (array_keys($argv) as $key) { $wgNiceCategoryListSettings[$key] = $argv[$key]; } // Replace variables in cat. This is still pretty crappy, as template // params still won't work. $poutput = $parser->parse( $category, $parser->mTitle, $parser->mOptions, false, false ); $category = $poutput->getText(); $dbr =& wfGetDB(DB_SLAVE); $title = Title::newFromText($category); if (!$title) return ''; $ct = fetchCategoryLinks($dbr, $title, 0); $poutput = $parser->parse( outputCategory( $ct ), $parser->mTitle, $parser->mOptions, true, false ); return $poutput->getText(); } /* * Get all links in a category. */ function getCategoryLinks($dbr, $title) { return $dbr->select( array( 'page', 'categorylinks' ), array( 'page_title', 'page_namespace', 'page_len', 'cl_sortkey' ), array( 'cl_from = page_id', 'cl_to' => $title->getDBKey()), #'page_is_redirect' => 0), #+ $pageCondition, '', array( 'ORDER BY' => 'cl_sortkey' ) ); } /* * Title comparison function */ function titleCmp($a, $b) { return $a->getText() > $b->getText(); } /* * CategoryLinks comparison function */ function categoryCmp($a, $b) { return titleCmp($a->title, $b->title); } /* * Simple class to hold category's title, links list, * and categories list. */ class CategoryLinks { var $title; var $links = array(); var $categories = array(); var $subcats = array(); function CategoryLinks($title) { $this->title = $title; } /* * Sort links and categories alphabetically. */ function sort() { global $wgNiceCategoryListSettings; if ($wgNiceCategoryListSettings['sort']) { usort($this->links, "titleCmp"); usort($this->categories, "categoryCmp"); } } } /* * */ function fetchCategoryLinks($dbr, $category_title, $depth, $processed = array()) { global $wgNiceCategoryListSettings; // avoid recursion if (in_array($category_title->getText(), $processed)) return NULL; $processed[] = $category_title->getText(); $cl = new CategoryLinks($category_title); // get category links from db $res = getCategoryLinks($dbr, $category_title); // process all category links while ($x = $dbr->fetchObject($res)) { $title = Title::makeTitle($x->page_namespace, $x->page_title); if ($title->getNamespace() == NS_CATEGORY) { // if category, recurse. Stop at max depth - but record the cat. if ($depth + 1 < $wgNiceCategoryListSettings['maxdepth']) { $fc = fetchCategoryLinks($dbr, $title, $depth + 1, $processed); if ($fc) $cl->categories[] = $fc; } $cl->subcats[] = $title; } else { // if regular page, add to list $cl->links[] = $title; } } // sort $cl->sort(); return $cl; } /* * Generate output for the list. */ function outputCategory($category, $level = 0) { global $wgContLang, $wgUser; global $wgNiceCategoryListSettings; $sk =& $wgUser->getSkin(); if ($level == 0) { // no need for TOC $output = "__NOTOC__\n"; } else { // second level and onwards, has a heading. // the heading gets smaller as the level grows. $title = $category->title; $ptitle = $title->getPrefixedText(); $title = $wgContLang->convert($title->getText()); $link = "[[:" . $ptitle . "|'''" . $title . "''']]"; if ($wgNiceCategoryListSettings['headings'] == 'head') { $heading = str_repeat('=', $level + $wgNiceCategoryListSettings['headstart']); $output = $heading . $title . $heading . "\n"; } else { $stars = str_repeat('*', $level); if ($level <= 1) $output = "<big>\n" . $stars . " " . $link . "</big>\n"; else $output = $stars . " " . $link . "\n"; } } $pieces = array(); // output each subcategory if ($wgNiceCategoryListSettings['showcats'] && !$category->categories) { foreach ($category->subcats as $title) { $ptitle = $title->getPrefixedText(); $title = $wgContLang->convert($title->getText()); $disp = "[[:" . $ptitle . "|'''" . $title . "''']]"; $pieces[] = $disp; } } // output each link if ($wgNiceCategoryListSettings['showarts']) { foreach ($category->links as $link) { $ptitle = $link->getPrefixedText(); $title = $link->getText(); $disp = "[[:" . $ptitle . "|" . $title . "]]"; $pieces[] = $disp; } } if (count($pieces) > 0) { if ($wgNiceCategoryListSettings['style'] == 'bullet') $output .= "* " . implode("\n* ", $pieces) . "\n"; else $output .= ":<div style=\"font-size: small\">" . implode(" ¤ ", $pieces) . "</div><br>\n"; } // recurse into each subcategory foreach ($category->categories as $cat) { $output .= outputCategory($cat, $level + 1); } return $output; } ?>