aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--includes/OutputPage.php1
-rw-r--r--includes/skins/Skin.php8
-rw-r--r--includes/skins/SkinTemplate.php51
-rw-r--r--tests/phpunit/includes/skins/SkinMustacheTest.php2
4 files changed, 56 insertions, 6 deletions
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index 5d09168f0452..2b8567175469 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -1483,6 +1483,7 @@ class OutputPage extends ContextSource {
* page
*
* @return string[][]
+ * @return-taint none
*/
public function getCategoryLinks() {
return $this->mCategoryLinks;
diff --git a/includes/skins/Skin.php b/includes/skins/Skin.php
index 0ff6011a085d..6c40766c34f0 100644
--- a/includes/skins/Skin.php
+++ b/includes/skins/Skin.php
@@ -2124,6 +2124,8 @@ abstract class Skin extends ContextSource {
* link from.
* @param array $item Contains some of a specific set of keys.
*
+ * If "html" key is present, this will be returned. All other keys will be ignored.
+ *
* The text of the link will be generated either from the contents of the
* "text" key in the $item array, if a "msg" key is present a message by
* that name will be used, and if neither of those are set the $key will be
@@ -2176,6 +2178,10 @@ abstract class Skin extends ContextSource {
*/
final public function makeLink( $key, $item, $linkOptions = [] ) {
$options = $linkOptions + $this->defaultLinkOptions;
+ $html = $item['html'] ?? null;
+ if ( $html ) {
+ return $html;
+ }
$text = $item['text'] ?? $this->msg( $item['msg'] ?? $key )->text();
$html = htmlspecialchars( $text );
@@ -2263,7 +2269,7 @@ abstract class Skin extends ContextSource {
* if "active" contains a value of true a "active" class will also be appended to class.
* The "class" key currently accepts both a string and an array of classes, but this will be
* changed to only accept an array in the future.
- * @phan-param array{id?:string,class?:string|string[],itemtitle?:string,active?:bool} $item
+ * @phan-param array{id?:string,html?:string,class?:string|string[],itemtitle?:string,active?:bool} $item
*
* @param array $options
* @phan-param array{tag?:string} $options
diff --git a/includes/skins/SkinTemplate.php b/includes/skins/SkinTemplate.php
index c5810680022f..a90a2876eda7 100644
--- a/includes/skins/SkinTemplate.php
+++ b/includes/skins/SkinTemplate.php
@@ -648,6 +648,25 @@ class SkinTemplate extends Skin {
}
/**
+ * @param array $links return value from OutputPage::getCategoryLinks
+ * @return array of data
+ */
+ private function getCategoryPortletsData( array $links ): array {
+ $categories = [];
+ foreach ( $links as $group => $links ) {
+ $allLinks = [];
+ $groupName = 'category-' . $group;
+ foreach ( $links as $i => $link ) {
+ $allLinks[$groupName . '-' . $i] = [
+ 'html' => $link,
+ ];
+ }
+ $categories[ $groupName ] = $allLinks;
+ }
+ return $categories;
+ }
+
+ /**
* @since 1.37 for non-SkinMustache base classes. Available since 1.36 for SkinMustache
* @stable to override
* @param string $name of the portal e.g. p-personal the name is personal.
@@ -671,10 +690,22 @@ class SkinTemplate extends Skin {
$name = 'personal';
}
- $id = Sanitizer::escapeIdForAttribute( "p-$name" );
+ $legacyClasses = '';
+ if ( $name === 'category-normal' ) {
+ // retain historic category IDs and classes
+ $id = 'mw-normal-catlinks';
+ $legacyClasses .= ' mw-normal-catlinks';
+ } elseif ( $name === 'category-hidden' ) {
+ // retain historic category IDs and classes
+ $id = 'mw-hidden-catlinks';
+ $legacyClasses .= ' mw-hidden-catlinks mw-hidden-cats-hidden';
+ } else {
+ $id = Sanitizer::escapeIdForAttribute( "p-$name" );
+ }
+
$data = [
'id' => $id,
- 'class' => 'mw-portlet ' . Sanitizer::escapeClass( "mw-portlet-$name" ),
+ 'class' => 'mw-portlet ' . Sanitizer::escapeClass( "mw-portlet-$name" ) . $legacyClasses,
'html-tooltip' => Linker::tooltip( $id ),
'html-items' => '',
// Will be populated by SkinAfterPortlet hook.
@@ -710,6 +741,16 @@ class SkinTemplate extends Skin {
}
/**
+ * Extends category links with Skin::getAfterPortlet functionality.
+ * @return string HTML
+ */
+ public function getCategoryLinks() {
+ $afterPortlet = $this->getPortletsTemplateData()['data-portlets']['data-category-normal']['html-after-portal']
+ ?? '';
+ return parent::getCategoryLinks() . $afterPortlet;
+ }
+
+ /**
* @param string $name of the portal e.g. p-personal the name is personal.
* @return string that is human readable corresponding to the menu
*/
@@ -1193,8 +1234,8 @@ class SkinTemplate extends Skin {
$performer = $this->getAuthority();
$action = $this->getAction();
$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
-
- $content_navigation = [
+ $categoriesData = $this->getCategoryPortletsData( $this->getOutput()->getCategoryLinks() );
+ $content_navigation = $categoriesData + [
// Modern keys: Please ensure these get unset inside Skin::prepareQuickTemplate
'user-interface-preferences' => [],
'user-page' => $this->loggedin ? [
@@ -1480,7 +1521,7 @@ class SkinTemplate extends Skin {
foreach ( $content_navigation as $section => &$links ) {
foreach ( $links as $key => &$link ) {
// Allow links to set their own id for backwards compatibility reasons.
- if ( isset( $link['id'] ) ) {
+ if ( isset( $link['id'] ) || isset( $link['html' ] ) ) {
continue;
}
$xmlID = $key;
diff --git a/tests/phpunit/includes/skins/SkinMustacheTest.php b/tests/phpunit/includes/skins/SkinMustacheTest.php
index af624c05b53a..6e2ac4b3461b 100644
--- a/tests/phpunit/includes/skins/SkinMustacheTest.php
+++ b/tests/phpunit/includes/skins/SkinMustacheTest.php
@@ -26,6 +26,8 @@ class SkinMustacheTest extends MediaWikiIntegrationTestCase {
$mock = $this->createMock( OutputPage::class );
$mock->method( 'getHTML' )
->willReturn( $html );
+ $mock->method( 'getCategoryLinks' )
+ ->willReturn( [] );
$mock->method( 'getIndicators' )
->willReturn( [
'id' => '<a>indicator</a>'