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
This commit is contained in:
Nicholas Ray 2021-12-03 16:33:21 -07:00
parent 2bccc4e8d4
commit 24a5817315
6 changed files with 111 additions and 23 deletions

View File

@ -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

View File

@ -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(

View File

@ -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:

View File

@ -18,7 +18,7 @@
</div>
{{/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}}
</div>

View File

@ -51,28 +51,28 @@
<a id="top"></a>
<div id="siteNotice">{{{html-site-notice}}}</div>
{{^is-language-in-header}}
{{^is-language-in-content}}
{{>Indicators}}
<h1 id="firstHeading" class="firstHeading" {{{html-user-language-attributes}}}>{{{html-title}}}</h1>
{{/is-language-in-header}}
{{/is-language-in-content}}
{{#is-language-in-header}}
{{#is-language-in-content}}
<header class="mw-body-header">
{{^is-mainpage}}
{{#is-language-in-content-top}}
{{#data-portlets.data-languages}}{{>Menu}}{{/data-portlets.data-languages}}
{{/is-mainpage}}
{{/is-language-in-content-top}}
<h1 id="firstHeading" class="firstHeading" {{{html-user-language-attributes}}}>{{{html-title}}}</h1>
{{>Indicators}}
{{#is-article}}
<div id="siteSub" class="noprint">{{msg-tagline}}</div>
{{/is-article}}
</header>
{{/is-language-in-header}}
{{/is-language-in-content}}
<div id="bodyContent" class="vector-body">
{{^is-language-in-header}}
{{^is-language-in-content}}
{{#is-article}}<div id="siteSub" class="noprint">{{msg-tagline}}</div>{{/is-article}}
{{/is-language-in-header}}
{{/is-language-in-content}}
<div id="contentSub"{{{html-user-language-attributes}}}>{{{html-subtitle}}}</div>
<div id="contentSub2">{{{html-undelete-link}}}</div>
{{{html-user-message}}}
@ -80,11 +80,9 @@
{{{html-categories}}}
</div>
{{#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}}
</main>
{{{html-after-content}}}

View File

@ -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."