mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/CategoryTree
synced 2024-11-27 09:43:06 +00:00
Show member counts in category tree. Requires r36814 of Category.php and CategoryPage.php.
This commit is contained in:
parent
2daa80d3a5
commit
595c3cfaef
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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>−</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>×</b>]', # do not translate or duplicate this message to other languages
|
||||
'categorytree-page-bullet' => ' ', # 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',
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" ) );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue