The personal menu and notifications are rendered separately in the existing Timeless and Minerva. This will soon be the case in Vector as well (T266536). This creates a need for architectural changes at the skin level.
# Acceptance criteria
[] It's proposed that a new menu placeholder is added to core for notification menu items
[] SkinMustache will read from this menu item and prepend to personal tools for skins so that they are not impacted by this change.
[] SkinMustache will be versioned so that skins using SkinMustache can update themselves safely to include the new menu.
[] Echo will be updated to use the new menu
[] Vector will be updated to read from the new menu
[] Modern will be updated to read from the new menu
[] Compatibility code in core will be dropped.
# Developer notes
We'd need some kind of versioning for this in SkinMustache to make the transition as smooth as possible. The existence of SkinTemplate skins would have to be handled separately.
```
diff --git a/includes/skins/SkinMustache.php b/includes/skins/SkinMustache.php
index 1888d21a6c..303112b0bd 100644
--- a/includes/skins/SkinMustache.php
+++ b/includes/skins/SkinMustache.php
@@ -24,11 +24,26 @@ use Wikimedia\WrappedStringList;
* @since 1.35
*/
class SkinMustache extends SkinTemplate {
+ /**
+ * @var integer current skin version
+ */
+ private $skinVersion = 1;
+
/**
* @var TemplateParser|null
*/
private $templateParser = null;
+
+ /**
+ * @inheritdoc
+ */
+ public function __construct( $options = null ) {
+ parent::__construct( $options );
+ // used for backwards compatibility skin changes.
+ $this->skinVersion = $options['version'] ?? 1;
+ }
+
/**
* @since 1.36
* @stable for overriding
@@ -223,13 +238,27 @@ class SkinMustache extends SkinTemplate {
}
}
}
+
+ $personalMenuData = self::getPersonalToolsForMakeListItem(
+ $this->buildPersonalUrls()
+ );
+
+ // Merge notifications and personal menu for old SkinMustache skins
+ $notifications = $contentNavigation['notifications'] ?? [];
+
+ if ( $this->skinVersion === 1 && count( $notifications ) > 0 ) {
+ // Make backwards compatibility changes for skins using 1.35 SkinMustache spec here.
+
+ $personalMenuData = wfArrayInsertAfter( $personalMenuData, $notifications, 'userpage' );
+ unset( $contentNavigation['notifications'] );
+ }
+
foreach ( $contentNavigation as $name => $items ) {
$portlets['data-' . $name] = $this->getPortletData( $name, $items );
}
+
$portlets['data-personal'] = $this->getPortletData( 'personal',
- self::getPersonalToolsForMakeListItem(
- $this->buildPersonalUrls()
- )
+ $personalMenuData
);
return [
'data-portlets' => $portlets,
diff --git a/includes/skins/SkinTemplate.php b/includes/skins/SkinTemplate.php
index 62a0d514d7..b79f43cc8b 100644
--- a/includes/skins/SkinTemplate.php
+++ b/includes/skins/SkinTemplate.php
@@ -359,8 +359,11 @@ class SkinTemplate extends Skin {
$tpl->set( 'language_urls', $this->getLanguages() ?: false );
# Personal toolbar
- $tpl->set( 'personal_urls', $this->buildPersonalUrls() );
$content_navigation = $this->buildContentNavigationUrls();
+ $personalMenuData = $this->buildPersonalUrls();
+ $tpl->set( 'personal_urls', $personalMenuData );
+ // these are included in personal tools.
+ unset( $content_navigation['notifications'] );
$content_actions = $this->buildContentActionUrls( $content_navigation );
$tpl->set( 'content_navigation', $content_navigation );
$tpl->set( 'content_actions', $content_actions );
@@ -434,6 +437,13 @@ class SkinTemplate extends Skin {
);
}
+
+ wfArrayInsertAfter( $personalTools, $notifications, 'userpage' );
+
+ $content_navigation = $this->buildContentNavigationUrls();
+ var_dump( $content_navigation['notifications'] );die;
+ wfArrayInsertAfter( $personalTools, $content_navigation['notifications'], 'userpage' );
+
foreach ( $personalTools as $key => $item ) {
$html .= $this->makeListItem( $key, $item, $options );
}
@@ -820,6 +830,7 @@ class SkinTemplate extends Skin {
$permissionManager = MediaWikiServices::getInstance()->getPermissionManager();
$content_navigation = [
+ 'notifications' => [],
'namespaces' => [],
'views' => [],
'actions' => [],
```