Fix display of categories in the sidebar

Switching from a unique approach -- getting category names, querying
the database, and then building links -- to the standard
OutputPage::getCategoryLinks() fixes the display of redlinks (T175713),
display order (T197852), and perhaps other bugs in the subtasks
of T160645.

A downside to this approach is that categories will not be shown on
history pages, but this is consistent with other skins (e.g. Vector
and Monobook) not displaying categories on history pages.

Bug: T186089
Bug: T175716
Bug: T175714
Bug: T175713
Bug: T197852
Bug: T160645
Change-Id: Ifad999033e8448615128cba4d6386045a9fc749b
isekai
evad37 7 years ago committed by Kunal Mehta
parent 535c3b8c7e
commit 3139581560

@ -700,95 +700,49 @@ class TimelessTemplate extends BaseTemplate {
/**
* Categories for the sidebar
*
* Assemble an array of categories, regardless of view mode. Just using Skin or
* OutputPage functions doesn't respect view modes (preview, history, whatever)
* But why? I have no idea what the purpose of this is.
* Assemble an array of categories. This doesn't show any categories for the
* action=history view, but that behaviour is consistent with other skins.
*
* @return string html
*/
protected function getCategories() {
global $wgContLang;
$skin = $this->getSkin();
$title = $skin->getTitle();
$catList = false;
$catList = '';
$html = '';
// Get list from outputpage if in preview; otherwise get list from title
if ( in_array( $skin->getRequest()->getVal( 'action' ), [ 'submit', 'edit' ] ) ) {
$allCats = [];
// Can't just use getCategoryLinks because there's no equivalent for Title
$allCats2 = $skin->getOutput()->getCategories();
foreach ( $allCats2 as $displayName ) {
$catTitle = Title::makeTitleSafe( NS_CATEGORY, $displayName );
$allCats[] = $catTitle->getDBkey();
}
} else {
// This is probably to trim out some excessive stuff. Unless I was just high on cough syrup.
$allCats = array_keys( $title->getParentCategories() );
$len = strlen( $wgContLang->getNsText( NS_CATEGORY ) . ':' );
foreach ( $allCats as $i => $catName ) {
$allCats[$i] = substr( $catName, $len );
}
}
if ( $allCats !== [] ) {
$dbr = wfGetDB( DB_REPLICA );
$res = $dbr->select(
[ 'page', 'page_props' ],
[ 'page_id', 'page_title' ],
[
'page_title' => $allCats,
'page_namespace' => NS_CATEGORY,
'pp_propname' => 'hiddencat'
],
__METHOD__,
[],
[ 'page_props' => [ 'JOIN', 'pp_page = page_id' ] ]
);
$hiddenCats = [];
foreach ( $res as $row ) {
$hiddenCats[] = $row->page_title;
}
$normalCats = array_diff( $allCats, $hiddenCats );
$normalCount = count( $normalCats );
$hiddenCount = count( $hiddenCats );
$count = $normalCount;
// Mostly consistent with how Skin does it.
// Doesn't have the classes. Either way can't be good for caching.
if (
$skin->getUser()->getBoolOption( 'showhiddencats' ) ||
$title->getNamespace() == NS_CATEGORY
) {
$count += $hiddenCount;
$allCats = $skin->getOutput()->getCategoryLinks();
if ( !empty( $allCats ) ) {
if ( !empty( $allCats['normal'] ) ) {
$catHeader = 'categories';
$catList .= $this->getCatList(
$allCats['normal'],
'normal-catlinks',
'mw-normal-catlinks',
'categories'
);
} else {
/* We don't care if there are hidden ones. */
$hiddenCount = 0;
$catHeader = 'hidden-categories';
}
// Assemble the html...
if ( $count ) {
if ( $normalCount ) {
$catHeader = 'categories';
if ( isset( $allCats['hidden'] ) ) {
$hiddenCatClass = [ 'mw-hidden-catlinks' ];
if ( $skin->getUser()->getBoolOption( 'showhiddencats' ) ) {
$hiddenCatClass[] = 'mw-hidden-cats-user-shown';
} elseif ( $skin->getTitle()->getNamespace() == NS_CATEGORY ) {
$hiddenCatClass[] = 'mw-hidden-cats-ns-shown';
} else {
$catHeader = 'hidden-categories';
}
$catList = '';
if ( $normalCount ) {
$catList .= $this->getCatList( $normalCats, 'catlist-normal', 'categories' );
}
if ( $hiddenCount ) {
$catList .= $this->getCatList(
$hiddenCats,
'catlist-hidden',
[ 'hidden-categories', $hiddenCount ]
);
$hiddenCatClass[] = 'mw-hidden-cats-hidden';
}
$catList .= $this->getCatList(
$allCats['hidden'],
'hidden-catlinks',
$hiddenCatClass,
[ 'hidden-categories', count( $allCats['hidden'] ) ]
);
}
}
if ( $catList ) {
if ( $catList !== '' ) {
$html = $this->getSidebarChunk( 'catlinks-sidebar', $catHeader, $catList );
}
@ -800,27 +754,28 @@ class TimelessTemplate extends BaseTemplate {
*
* @param array $list
* @param string $id
* @param string|array $class
* @param string|array $message i18n message name or an array of [ message name, params ]
*
* @return string html
*/
protected function getCatList( $list, $id, $message ) {
$html = '';
protected function getCatList( $list, $id, $class, $message ) {
$html = Html::openElement( 'div', [ 'id' => "sidebar-{$id}", 'class' => $class ] );
$categories = [];
// Generate portlet content
foreach ( $list as $category ) {
$title = Title::makeTitleSafe( NS_CATEGORY, $category );
if ( !$title ) {
continue;
}
$categories[ htmlspecialchars( $category ) ] = [ 'links' => [ 0 => [
'href' => $title->getLinkURL(),
'text' => $title->getText()
] ] ];
}
$makeLinkItem = function ( $linkHtml ) {
return Html::rawElement( 'li', [], $linkHtml );
};
$html .= $this->getPortlet( $id, $categories, $message );
$categoryItems = array_map( $makeLinkItem, $list );
$categoriesHtml = Html::rawElement( 'ul',
[],
implode( '', $categoryItems )
);
$html .= $this->getPortlet( $id, $categoriesHtml, $message );
$html .= Html::closeElement( 'div' );
return $html;
}

Loading…
Cancel
Save