Show member counts in category tree. Requires r36814 of Category.php and CategoryPage.php.

This commit is contained in:
Daniel Kinzler 2008-06-30 14:09:47 +00:00
parent 2daa80d3a5
commit 595c3cfaef
5 changed files with 107 additions and 34 deletions

View file

@ -12,7 +12,7 @@ class CategoryTreeCategoryPage extends CategoryPage {
}
class CategoryTreeCategoryViewer extends CategoryViewer {
var $child_titles;
var $child_cats;
function getCategoryTree() {
global $wgOut, $wgCategoryTreeCategoryPageOptions;
@ -29,25 +29,29 @@ class CategoryTreeCategoryViewer extends CategoryViewer {
/**
* Add a subcategory to the internal lists
*/
function addSubcategory( $title, $sortkey, $pageLength ) {
function addSubcategoryObject( $cat, $sortkey, $pageLength ) {
global $wgContLang, $wgOut, $wgRequest;
$title = $cat->getTitle();
if ( $wgRequest->getCheck( 'notree' ) ) {
return parent::addSubcategory( $title, $sortkey, $pageLength );
return parent::addSubcategoryObject( $cat, $sortkey, $pageLength );
}
if ( ! $GLOBALS['wgCategoryTreeUnifiedView'] ) {
$this->child_titles[] = $title;
return parent::addSubcategory( $title, $sortkey, $pageLength );
}
/*if ( ! $GLOBALS['wgCategoryTreeUnifiedView'] ) {
$this->child_cats[] = $cat;
return parent::addSubcategory( $cat, $sortkey, $pageLength );
}*/
$tree = $this->getCategoryTree();
$this->children[] = $tree->renderNode( $title );
$this->children[] = $tree->renderNodeInfo( $title, $cat );
$this->children_start_char[] = $this->getSubcategorySortChar( $title, $sortkey );
}
/*
# this is a pain to keep this consistent, and no one should be using wgCategoryTreeUnifiedView = false anyway.
function getSubcategorySection() {
global $wgOut, $wgRequest, $wgCookiePrefix;
@ -107,14 +111,14 @@ class CategoryTreeCategoryViewer extends CategoryViewer {
if ( $showAs == 'list' ) {
$r .= $this->formatList( $this->children, $this->children_start_char );
} else {
$ct = getCategoryTree();
$ct = $this->getCategoryTree();
foreach ( $this->child_titles as $title ) {
$r .= $ct->renderNode( $title );
foreach ( $this->child_cats as $cat ) {
$r .= $ct->renderNodeInfo( $cat->getTitle(), $cat );
}
}
return $r;
}
}*/
function makeShowAsLink( $targetValue, $currentValue ) {
$msg = htmlspecialchars( CategoryTree::msg( "show-$targetValue" ) );
@ -127,13 +131,13 @@ class CategoryTreeCategoryViewer extends CategoryViewer {
}
function clearCategoryState() {
$this->child_titles = array();
$this->child_cats = array();
parent::clearCategoryState();
}
function finaliseCategoryState() {
if( $this->flip ) {
$this->child_titles = array_reverse( $this->child_titles );
$this->child_cats = array_reverse( $this->child_cats );
}
parent::finaliseCategoryState();
}

View file

@ -34,8 +34,11 @@ If you have a very old browser, or have JavaScript disabled, it will not work.',
'categorytree-expand' => 'expand',
'categorytree-collapse-bullet' => '[<b>&#x2212;</b>]', # do not translate or duplicate this message to other languages
'categorytree-expand-bullet' => '[<b>+</b>]', # do not translate or duplicate this message to other languages
'categorytree-empty-bullet' => '[<b>&#215</b>]', # do not translate or duplicate this message to other languages
'categorytree-page-bullet' => '&nbsp;', # do not translate or duplicate this message to other languages
'categorytree-member-counts' => 'contains $1 subcategories, $2 pages, and $3 files',
'categorytree-load' => 'load',
'categorytree-loading' => 'loading…',
'categorytree-nothing-found' => 'nothing found',
@ -596,6 +599,7 @@ Diese Seite benötigt bestimmte JavaScript-Funktionen (Ajax) und funktioniert m
'categorytree-category' => 'Kategorie:',
'categorytree-go' => 'Laden',
'categorytree-parents' => 'Oberkategorien',
'categorytree-member-counts' => 'enthält $1 Unterkategorien, $2 Seiten und $3 Dateien',
'categorytree-mode-categories' => 'nur Kategorien',
'categorytree-mode-pages' => 'Seiten außer Bilder',
'categorytree-mode-all' => 'alle Seiten',

View file

@ -32,12 +32,13 @@ define('CT_MODE_ALL', 20);
* This way, the cache does not need to be disabled. Default is false.
* $wgCategoryTreeDisableCache - disabled the parser cache for pages with a <categorytree> tag. Default is true.
* $wgCategoryTreeUseCache - enable HTTP cache for anon users. Default is false.
* $wgCategoryTreeUnifiedView - use unified view on category pages, instead of "tree" or "traditional list". Default is true.
* $wgCategoryTreeOmitNamespace - never show namespace prefix. Default is false
* $wgCategoryTreeMaxDepth - maximum value for depth argument; An array that maps mode values to
* the maximum depth acceptable for the depth option.
* Per default, the "categories" mode has a max depth of 2,
* all other modes have a max depth of 1.
* $wgCategoryTreeDefaultOptions - default options for the <categorytree> tag.
* $wgCategoryTreeCategoryPageOptions - options to apply on category pages.
* $wgCategoryTreeSpecialPageOptions - options to apply on Special:CategoryTree.
*/
$wgCategoryTreeMaxChildren = 200;
@ -45,7 +46,7 @@ $wgCategoryTreeAllowTag = true;
$wgCategoryTreeDisableCache = true;
$wgCategoryTreeDynamicTag = false;
$wgCategoryTreeHTTPCache = false;
$wgCategoryTreeUnifiedView = true;
#$wgCategoryTreeUnifiedView = true;
$wgCategoryTreeMaxDepth = array(CT_MODE_PAGES => 1, CT_MODE_ALL => 1, CT_MODE_CATEGORIES => 2);
$wgCategoryTreeExtPath = '/extensions/CategoryTree';
@ -56,11 +57,16 @@ $wgCategoryTreeDefaultMode = CT_MODE_CATEGORIES;
$wgCategoryTreeDefaultOptions = array(); #Default values for most options. ADD NEW OPTIONS HERE!
$wgCategoryTreeDefaultOptions['mode'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
$wgCategoryTreeDefaultOptions['hideprefix'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
$wgCategoryTreeDefaultOptions['showcount'] = false;
#TODO: hideprefix: always, never, catonly, catonly_if_onlycat
$wgCategoryTreeCategoryPageMode = CT_MODE_CATEGORIES;
$wgCategoryTreeCategoryPageOptions = array(); #Options to be used for category pages
$wgCategoryTreeCategoryPageOptions['mode'] = NULL; # will be set to $wgCategoryTreeDefaultMode in efCategoryTree(); compatibility quirk
$wgCategoryTreeCategoryPageOptions['showcount'] = true;
$wgCategoryTreeSpecialPageOptions = array(); #Options to be used for Special:CategoryTree
$wgCategoryTreeSpecialPageOptions['showcount'] = true;
/**
* Register extension setup hook and credits

View file

@ -32,6 +32,7 @@ class CategoryTree {
$this->mOptions['mode'] = self::decodeMode( $this->mOptions['mode'] );
$this->mOptions['hideprefix'] = self::decodeBoolean( $this->mOptions['hideprefix'] );
$this->mOptions['showcount'] = self::decodeBoolean( $this->mOptions['showcount'] );
}
function getOption( $name ) {
@ -66,7 +67,7 @@ class CategoryTree {
if ( is_int( $value ) ) return ( $value > 0 );
$value = trim( strtolower( $value ) );
if ( is_numeric( $value ) ) return ( (int)$mode > 0 );
if ( is_numeric( $value ) ) return ( (int)$value > 0 );
if ( $value == 'yes' || $value == 'y' || $value == 'true' || $value == 't' || $value == 'on' ) return true;
else if ( $value == 'no' || $value == 'n' || $value == 'false' || $value == 'f' || $value == 'off' ) return false;
@ -306,7 +307,7 @@ class CategoryTree {
* $title must be a Title object
*/
function renderChildren( &$title, $depth=1 ) {
global $wgCategoryTreeMaxChildren;
global $wgCategoryTreeMaxChildren, $wgVersion;
if( $title->getNamespace() != NS_CATEGORY ) {
// Non-categories can't have children. :)
@ -315,10 +316,6 @@ class CategoryTree {
$dbr =& wfGetDB( DB_SLAVE );
#additional stuff to be used if "transaltion" by interwiki-links is desired
$transFields = '';
$transJoin = '';
$transWhere = '';
$mode = $this->getOption('mode');
@ -327,14 +324,33 @@ class CategoryTree {
else if ( $mode == CT_MODE_PAGES ) $nsmatch = ' AND cat.page_namespace != ' . NS_IMAGE;
else $nsmatch = ' AND cat.page_namespace = ' . NS_CATEGORY;
#additional stuff to be used if "transaltion" by interwiki-links is desired
$transFields = '';
$transJoin = '';
$transWhere = '';
# fetch member count if possible
$doCount = version_compare( $wgVersion, "1.12", '>' );
$countFields = '';
$countJoin = '';
if ( $doCount ) {
$cat = $dbr->tableName( 'category' );
$countJoin = " LEFT JOIN $cat ON cat_title = page_title AND page_namespace = " . NS_CATEGORY;
$countFields = ', cat_id, cat_title, cat_subcats, cat_pages, cat_files';
}
$page = $dbr->tableName( 'page' );
$categorylinks = $dbr->tableName( 'categorylinks' );
$sql = "SELECT cat.page_namespace, cat.page_title
$transFields
$countFields
FROM $page as cat
JOIN $categorylinks ON cl_from = cat.page_id
$transJoin
$countJoin
WHERE cl_to = " . $dbr->addQuotes( $title->getDBkey() ) . "
$nsmatch
"./*AND cat.page_is_redirect = 0*/"
@ -348,14 +364,20 @@ class CategoryTree {
$categories= '';
$other= '';
while ( $row = $dbr->fetchRow( $res ) ) {
while ( $row = $dbr->fetchObject( $res ) ) {
#TODO: translation support; ideally added to Title object
$t = Title::makeTitle( $row['page_namespace'], $row['page_title'] );
$t = Title::newFromRow( $row );
$s = $this->renderNode( $t, $depth-1, false );
$cat = NULL;
if ( $doCount && $row->page_namespace == NS_CATEGORY ) {
$cat = Category::newFromRow( $row, $t );
}
$s = $this->renderNodeInfo( $t, $cat, $depth-1, false );
$s .= "\n\t\t";
if ($row['page_namespace'] == NS_CATEGORY) $categories .= $s;
if ($row->page_namespace == NS_CATEGORY) $categories .= $s;
else $other .= $s;
}
@ -394,9 +416,9 @@ class CategoryTree {
$s= '';
while ( $row = $dbr->fetchRow( $res ) ) {
while ( $row = $dbr->fetchObject( $res ) ) {
#TODO: translation support; ideally added to Title object
$t = Title::makeTitle( $row['page_namespace'], $row['page_title'] );
$t = Title::newFromRow( $row );
#$trans = $title->getLocalizedText();
$trans = ''; #place holder for when translated titles are available
@ -424,8 +446,18 @@ class CategoryTree {
* Returns a string with a HTML represenation of the given page.
* $title must be a Title object
*/
function renderNode( &$title, $children = 0, $loadchildren = false ) {
global $wgCategoryTreeDefaultMode;
function renderNode( $title, $children = 0, $loadchildren = false ) {
if ( $title->getNamespace() == NS_CATEGORY ) $cat = Category::newFromTitle( $title );
else $cat = NULL;
return $this->renderNodeInfo( $title, $cat, $children, $loadchildren );
}
/**
* Returns a string with a HTML represenation of the given page.
* $info must be an associative array, containing at least a Title object under the 'title' key.
*/
function renderNodeInfo( $title, $cat, $children = 0, $loadchildren = false ) {
static $uniq = 0;
$mode = $this->getOption('mode');
@ -462,6 +494,7 @@ class CategoryTree {
if ( ( $ns % 2 ) > 0 ) $labelClass .= ' CategoryTreeLabelTalk';
$count = false;
$s = '';
#NOTE: things in CategoryTree.js rely on the exact order of tags!
@ -475,25 +508,37 @@ class CategoryTree {
$s .= Xml::openElement( 'span', $attr );
if ( $ns == NS_CATEGORY ) {
if ( $cat ) {
if ( $mode == CT_MODE_CATEGORIES ) $count = $cat->getSubcatCount();
else if ( $mode == CT_MODE_PAGES ) $count = $cat->getPageCount() - $cat->getFileCount();
else $count = $cat->getPageCount();
}
$linkattr= array( 'href' => $wikiLink );
if ( $load ) $linkattr[ 'id' ] = $load;
$linkattr[ 'class' ] = "CategoryTreeToggle";
if ( $children == 0 || $loadchildren ) {
if ( $count === 0 ) {
$tag = 'span';
$txt = $this->msg('empty-bullet');
}
else if ( $children == 0 || $loadchildren ) {
$tag = 'a';
$txt = $this->msg('expand-bullet');
$linkattr[ 'onclick' ] = "this.href='javascript:void(0)'; categoryTreeExpandNode('".Xml::escapeJsString($key)."',".$this->getOptionsAsJsStructure().",this);";
# Don't load this message for ajax requests, so that we don't have to initialise $wgLang
$linkattr[ 'title' ] = $this->mIsAjaxRequest ? '##LOAD##' : self::msg('expand');
}
else {
$tag = 'a';
$txt = $this->msg('collapse-bullet');
$linkattr[ 'onclick' ] = "this.href='javascript:void(0)'; categoryTreeCollapseNode('".Xml::escapeJsString($key)."',".$this->getOptionsAsJsStructure().",this);";
$linkattr[ 'title' ] = self::msg('collapse');
$linkattr[ 'class' ] .= ' CategoryTreeLoaded';
}
$s .= Xml::openElement( 'a', $linkattr ) . $txt . Xml::closeElement( 'a' ) . ' ';
$s .= Xml::openElement( $tag, $linkattr ) . $txt . Xml::closeElement( $tag ) . ' ';
} else {
$s .= $this->msg('page-bullet');
}
@ -501,6 +546,17 @@ class CategoryTree {
$s .= Xml::closeElement( 'span' );
$s .= Xml::openElement( 'a', array( 'class' => $labelClass, 'href' => $wikiLink ) ) . $label . Xml::closeElement( 'a' );
if ( $count !== false && $this->getOption( 'showcount' ) ) {
$pages = $cat->getPageCount() - $cat->getSubcatCount() - $cat->getFileCount();
$attr = array(
'title' => $this->msg( 'member-counts', $cat->getSubcatCount(), $pages , $cat->getFileCount() )
);
$s .= Xml::element( 'span', $attr, ' (' . $count . ')' );
}
$s .= Xml::closeElement( 'div' );
$s .= "\n\t\t";
$s .= Xml::openElement( 'div', array( 'class' => 'CategoryTreeChildren', 'style' => $children > 0 ? "display:block" : "display:none" ) );

View file

@ -40,7 +40,7 @@ class CategoryTreePage extends SpecialPage {
* @param $par Parameters passed to the page
*/
function execute( $par ) {
global $wgRequest, $wgOut, $wgMakeBotPrivileged, $wgUser, $wgCategoryTreeDefaultOptions;
global $wgRequest, $wgOut, $wgCategoryTreeDefaultOptions, $wgCategoryTreeSpecialPageOptions;
$this->setHeaders();
@ -56,6 +56,9 @@ class CategoryTreePage extends SpecialPage {
# grab all known options from the request. Normalization is done by the CategoryTree class
foreach ( $wgCategoryTreeDefaultOptions as $option => $default ) {
if ( isset( $wgCategoryTreeSpecialPageOptions[$option] ) )
$default = $wgCategoryTreeSpecialPageOptions[$option];
$options[$option] = $wgRequest->getVal( $option, $default );
}