From 24a581731585cf6db66051dcd438a27c858fd4ad Mon Sep 17 00:00:00 2001 From: Nicholas Ray Date: Fri, 3 Dec 2021 16:33:21 -0700 Subject: [PATCH] Feature flag language button in main page header Per the ticket, when this flag is enabled (and the VectorLanguageInHeader config is enabled) we want to move the language button from the bottom of the main page to beside the main page's title. This config can be toggled with the `languageinmainpageheader` query param (e.g. `?languageinmainpageheader=1`). Bug: T293470 Change-Id: I41b4677f80b939810d16907b508ab29936f8629c --- includes/Constants.php | 25 +++++++++++++++++ includes/ServiceWiring.php | 31 +++++++++++++++++++++ includes/SkinVector.php | 43 +++++++++++++++++++++++------ includes/templates/Sidebar.mustache | 4 +-- includes/templates/skin.mustache | 24 ++++++++-------- skin.json | 7 +++++ 6 files changed, 111 insertions(+), 23 deletions(-) diff --git a/includes/Constants.php b/includes/Constants.php index 61c8854..4f33181 100644 --- a/includes/Constants.php +++ b/includes/Constants.php @@ -251,6 +251,31 @@ final class Constants { */ public const CONFIG_SEARCH_TREATMENT_AB_TEST = 'VectorSearchTreatmentABTest'; + /** + * @var string + */ + public const REQUIREMENT_IS_MAIN_PAGE = 'IsMainPage'; + + /** + * @var string + */ + public const REQUIREMENT_LANGUAGE_IN_MAIN_PAGE_HEADER = 'LanguageInMainPageHeader'; + + /** + * @var string + */ + public const CONFIG_LANGUAGE_IN_MAIN_PAGE_HEADER = 'VectorLanguageInMainPageHeader'; + + /** + * @var string + */ + public const QUERY_PARAM_LANGUAGE_IN_MAIN_PAGE_HEADER = 'languageinmainpageheader'; + + /** + * @var string + */ + public const FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER = 'LanguageInMainPageHeader'; + /** * This class is for namespacing constants only. Forbid construction. * @throws FatalError diff --git a/includes/ServiceWiring.php b/includes/ServiceWiring.php index 6193538..f17ba5b 100644 --- a/includes/ServiceWiring.php +++ b/includes/ServiceWiring.php @@ -135,6 +135,37 @@ return [ ] ); + // Feature: T293470: Language in main page header + // ================================ + $featureManager->registerRequirement( + new OverridableConfigRequirement( + $services->getMainConfig(), + $context->getUser(), + $context->getRequest(), + null, + Constants::CONFIG_LANGUAGE_IN_MAIN_PAGE_HEADER, + Constants::REQUIREMENT_LANGUAGE_IN_MAIN_PAGE_HEADER, + Constants::QUERY_PARAM_LANGUAGE_IN_MAIN_PAGE_HEADER, + null + ) + ); + + $featureManager->registerSimpleRequirement( + Constants::REQUIREMENT_IS_MAIN_PAGE, + $context->getTitle() ? $context->getTitle()->isMainPage() : false + ); + + $featureManager->registerFeature( + Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER, + [ + Constants::REQUIREMENT_FULLY_INITIALISED, + Constants::REQUIREMENT_LATEST_SKIN_VERSION, + Constants::REQUIREMENT_IS_MAIN_PAGE, + Constants::REQUIREMENT_LANGUAGE_IN_HEADER, + Constants::REQUIREMENT_LANGUAGE_IN_MAIN_PAGE_HEADER + ] + ); + // Feature: Use Wvui Search // ================================ $featureManager->registerRequirement( diff --git a/includes/SkinVector.php b/includes/SkinVector.php index 1e1bc42..a2cbdd7 100644 --- a/includes/SkinVector.php +++ b/includes/SkinVector.php @@ -154,15 +154,40 @@ class SkinVector extends SkinMustache { } /** + * @param string $location Either 'top' or 'bottom' is accepted. * @return bool */ - private function isLanguagesInHeader() { + private function isLanguagesInContentAt( $location ) { + if ( !$this->canHaveLanguages() ) { + return false; + } $featureManager = VectorServices::getFeatureManager(); - // Disable button on pages without languages (based on Wikibase RepoItemLinkGenerator class) - - return $this->canHaveLanguages() && $featureManager->isFeatureEnabled( + $inContent = $featureManager->isFeatureEnabled( Constants::FEATURE_LANGUAGE_IN_HEADER ); + $isMainPage = $this->getTitle() ? $this->getTitle()->isMainPage() : false; + + switch ( $location ) { + case 'top': + return $isMainPage ? $inContent && $featureManager->isFeatureEnabled( + Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER + ) : $inContent; + case 'bottom': + return $inContent && $isMainPage && !$featureManager->isFeatureEnabled( + Constants::FEATURE_LANGUAGE_IN_MAIN_PAGE_HEADER + ); + default: + throw new RuntimeException( 'unknown language button location' ); + } + } + + /** + * Whether or not the languages are out of the sidebar and in the content either at + * the top or the bottom. + * @return bool + */ + private function isLanguagesInContent() { + return $this->isLanguagesInContentAt( 'top' ) || $this->isLanguagesInContentAt( 'bottom' ); } /** @@ -174,7 +199,7 @@ class SkinVector extends SkinMustache { return !$this->isLegacy() && !$this->canHaveLanguages() || // NOTE: T276950 - This should be revisited when an empty state for the language button is chosen. - ( $this->isLanguagesInHeader() && empty( $this->getLanguagesCached() ) ); + ( $this->isLanguagesInContent() && empty( $this->getLanguagesCached() ) ); } /** @@ -437,7 +462,9 @@ class SkinVector extends SkinMustache { 'sidebar-visible' => $this->isSidebarVisible(), - 'is-language-in-header' => $this->isLanguagesInHeader(), + 'is-language-in-content' => $this->isLanguagesInContent(), + 'is-language-in-content-top' => $this->isLanguagesInContentAt( 'top' ), + 'is-language-in-content-bottom' => $this->isLanguagesInContentAt( 'bottom' ), 'data-search-box' => $this->getSearchData( $parentData['data-search-box'], @@ -705,7 +732,7 @@ class SkinVector extends SkinMustache { break; } - if ( $portletData['id'] === 'p-lang' && $this->isLanguagesInHeader() ) { + if ( $portletData['id'] === 'p-lang' && $this->isLanguagesInContent() ) { $portletData = array_merge( $portletData, $this->getULSPortletData() ); } $class = $portletData['class']; @@ -737,7 +764,7 @@ class SkinVector extends SkinMustache { $type = self::MENU_TYPE_DEFAULT; break; case 'lang': - $type = $this->isLanguagesInHeader() ? + $type = $this->isLanguagesInContent() ? self::MENU_TYPE_DROPDOWN : self::MENU_TYPE_PORTAL; break; default: diff --git a/includes/templates/Sidebar.mustache b/includes/templates/Sidebar.mustache index 3a916ba..635872b 100644 --- a/includes/templates/Sidebar.mustache +++ b/includes/templates/Sidebar.mustache @@ -18,7 +18,7 @@ {{/data-emphasized-sidebar-action}} {{#array-portlets-rest}}{{>Menu}}{{/array-portlets-rest}} - {{^is-language-in-header}} + {{^is-language-in-content}} {{#data-portlets.data-languages}}{{>Menu}}{{/data-portlets.data-languages}} - {{/is-language-in-header}} + {{/is-language-in-content}} diff --git a/includes/templates/skin.mustache b/includes/templates/skin.mustache index 44ee02d..101c08a 100644 --- a/includes/templates/skin.mustache +++ b/includes/templates/skin.mustache @@ -51,28 +51,28 @@
{{{html-site-notice}}}
- {{^is-language-in-header}} + {{^is-language-in-content}} {{>Indicators}}

{{{html-title}}}

- {{/is-language-in-header}} + {{/is-language-in-content}} - {{#is-language-in-header}} + {{#is-language-in-content}}
- {{^is-mainpage}} + {{#is-language-in-content-top}} {{#data-portlets.data-languages}}{{>Menu}}{{/data-portlets.data-languages}} - {{/is-mainpage}} + {{/is-language-in-content-top}}

{{{html-title}}}

{{>Indicators}} {{#is-article}}
{{msg-tagline}}
{{/is-article}}
- {{/is-language-in-header}} + {{/is-language-in-content}}
- {{^is-language-in-header}} + {{^is-language-in-content}} {{#is-article}}
{{msg-tagline}}
{{/is-article}} - {{/is-language-in-header}} + {{/is-language-in-content}}
{{{html-subtitle}}}
{{{html-undelete-link}}}
{{{html-user-message}}} @@ -80,11 +80,9 @@ {{{html-categories}}}
- {{#is-mainpage}} - {{#is-language-in-header}} - {{#data-portlets.data-languages}}{{>Menu}}{{/data-portlets.data-languages}} - {{/is-language-in-header}} - {{/is-mainpage}} + {{#is-language-in-content-bottom}} + {{#data-portlets.data-languages}}{{>Menu}}{{/data-portlets.data-languages}} + {{/is-language-in-content-bottom}} {{{html-after-content}}} diff --git a/skin.json b/skin.json index 515b8c2..8de49d1 100644 --- a/skin.json +++ b/skin.json @@ -358,6 +358,13 @@ }, "description": "@var array Moves the language links from the sidebar into a menu beside the page title. Also moves the indicators to the line below, next to the tagline (siteSub)." }, + "VectorLanguageInMainPageHeader": { + "value": { + "logged_in": false, + "logged_out": false + }, + "description": "@var When `VectorLanguageInHeader` is enabled, determines whether the Main Page's language button should be at the top or bottom of the content. The default position on the main page is at the bottom." + }, "VectorLanguageInHeaderTreatmentABTest": { "value": false, "description": "@var boolean Enables or disables the language in header treatment A/B test. See https://phabricator.wikimedia.org/T280825 and associated tasks for additional detail."