Daniel Friesen has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/63378


Change subject: Improve language handling of page titles.
......................................................................

Improve language handling of page titles.

* The title's lang="auto" and pageviewlang is moved into SkinTemplate
* Setting of the language attributes is done inside the same place as it's done 
for mw-content-text
  to avoid the bug where the title for an edit page is given the page's lang 
instead of the user's lang.
* Fix getPageLanguage usage that should probably be getPageViewLanguage instead.
* Add getPageTitleLanguage to Title and ContextHandler to declare the language 
of the title
* Add context to Title and ContextHandler's getPage*Language methods instead of 
using $wgLang.

Change-Id: I0ff707d5f04218bef5721e6fc162c6359bb7538a
---
M includes/Article.php
M includes/CategoryViewer.php
M includes/OutputPage.php
M includes/SkinTemplate.php
M includes/Title.php
M includes/content/ContentHandler.php
M skins/CologneBlue.php
M skins/Modern.php
M skins/MonoBook.php
M skins/Vector.php
M tests/phpunit/includes/content/ContentHandlerTest.php
11 files changed, 137 insertions(+), 54 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/core 
refs/changes/78/63378/1

diff --git a/includes/Article.php b/includes/Article.php
index 87b94ae..f8ed4e6 100644
--- a/includes/Article.php
+++ b/includes/Article.php
@@ -1346,7 +1346,7 @@
                        $target = array( $target );
                }
 
-               $lang = $this->getTitle()->getPageLanguage();
+               $lang = $this->getTitle()->getPageViewLanguage();
                $imageDir = $lang->getDir();
 
                if ( $appendSubtitle ) {
diff --git a/includes/CategoryViewer.php b/includes/CategoryViewer.php
index 970adb5..df56561 100644
--- a/includes/CategoryViewer.php
+++ b/includes/CategoryViewer.php
@@ -480,7 +480,7 @@
                        $list = self::shortList( $articles, 
$articles_start_char );
                }
 
-               $pageLang = $this->title->getPageLanguage();
+               $pageLang = $this->title->getPageViewLanguage();
                $attribs = array( 'lang' => $pageLang->getCode(), 'dir' => 
$pageLang->getDir(),
                        'class' => 'mw-content-' . $pageLang->getDir() );
                $list = Html::rawElement( 'div', $attribs, $list );
diff --git a/includes/OutputPage.php b/includes/OutputPage.php
index 746cd0e..52f2449 100644
--- a/includes/OutputPage.php
+++ b/includes/OutputPage.php
@@ -3029,7 +3029,7 @@
                        $pageID = $wikiPage->getId();
                }
 
-               $lang = $title->getPageLanguage();
+               $lang = $title->getPageViewLanguage();
 
                // Pre-process information
                $separatorTransTable = $lang->separatorTransformTable();
diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php
index e53d424..060e2e4 100644
--- a/includes/SkinTemplate.php
+++ b/includes/SkinTemplate.php
@@ -247,10 +247,6 @@
                wfProfileOut( __METHOD__ . '-stuff-head' );
 
                wfProfileIn( __METHOD__ . '-stuff2' );
-               $tpl->set( 'title', $out->getPageTitle() );
-               $tpl->set( 'pagetitle', $out->getHTMLTitle() );
-               $tpl->set( 'displaytitle', $out->mPageLinkTitle );
-
                $tpl->setRef( 'thispage', $this->thispage );
                $tpl->setRef( 'titleprefixeddbkey', $this->thispage );
                $tpl->set( 'titletext', $title->getText() );
@@ -435,20 +431,39 @@
 
                # An ID that includes the actual body text; without categories, 
contentSub, ...
                $realBodyAttribs = array( 'id' => 'mw-content-text' );
+               $realTitleAttribs = array();
+
+               // @fixme We shouldn't be using these methods on title. Page 
language can potentially
+               // depend on content of the revision being displayed. But these 
methods use the most
+               // recent revision of the page. Trying to guess whether the 
user is on a page view or
+               // something like an action is also really hacky. Defining the 
language of what we are
+               // outputting to the user should be the job of whatever class 
is rendering the view
+               // we're looking at, whether it's an article, action, or 
special page.
+               $pageLang = $title->getPageViewLanguage( $this->getContext() );
+               $pageTitleLang = $title->getPageTitleLanguage( 
$this->getContext() );
 
                # Add a mw-content-ltr/rtl class to be able to style based on 
text direction
                # when the content is different from the UI language, i.e.:
                # not for special pages or file pages AND only when viewing AND 
if the page exists
                # (or is in MW namespace, because that has default content)
-               if ( !in_array( $title->getNamespace(), array( NS_SPECIAL, 
NS_FILE ) ) &&
+               if ( !$title->inNamespaces( NS_SPECIAL, NS_FILE ) &&
                        Action::getActionName( $this ) === 'view' &&
-                       ( $title->exists() || $title->getNamespace() == 
NS_MEDIAWIKI ) ) {
-                       $pageLang = $title->getPageViewLanguage();
+                       ( $title->exists() || $title->inNamespace( NS_MEDIAWIKI 
) ) ) {
                        $realBodyAttribs['lang'] = $pageLang->getHtmlCode();
                        $realBodyAttribs['dir'] = $pageLang->getDir();
                        $realBodyAttribs['class'] = 'mw-content-' . 
$pageLang->getDir();
+                       $realTitleAttribs['lang'] = 
$pageTitleLang->getHtmlCode();
+                       $realTitleAttribs['dir'] = $pageTitleLang->getDir();
                }
 
+               // Override the directionality of the title with auto until we 
properly fix 32403
+               $realTitleAttribs['dir'] = 'auto';
+
+               $titleHtml = Html::rawElement( 'span', $realTitleAttribs, 
$out->getPageTitle() );
+               $tpl->set( 'title', $titleHtml );
+               $tpl->set( 'pagetitle', $out->getHTMLTitle() );
+               $tpl->set( 'displaytitle', $out->mPageLinkTitle );
+
                $out->mBodytext = Html::rawElement( 'div', $realBodyAttribs, 
$out->mBodytext );
                $tpl->setRef( 'bodytext', $out->mBodytext );
 
diff --git a/includes/Title.php b/includes/Title.php
index 70e8cd4..23ba3db 100644
--- a/includes/Title.php
+++ b/includes/Title.php
@@ -4730,52 +4730,81 @@
        /**
         * Get the language in which the content of this page is written in
         * wikitext. Defaults to $wgContLang, but in certain cases it can be
-        * e.g. $wgLang (such as special pages, which are in the user language).
+        * others such as the user lang on special pages.
         *
         * @since 1.18
+        * @param IContextSource $context The context to use in case we're 
using something like the user's language.
         * @return Language
         */
-       public function getPageLanguage() {
-               global $wgLang;
+       public function getPageLanguage( IContextSource $context = null ) {
                if ( $this->isSpecialPage() ) {
                        // special pages are in the user language
-                       return $wgLang;
+                       if ( is_null( $context ) ) {
+                               $context = RequestContext::getMain();
+                       }
+                       return $context->getLanguage();
                }
 
                //TODO: use the LinkCache to cache this! Note that this may 
depend on user settings, so the cache should be only per-request.
                //NOTE: ContentHandler::getPageLanguage() may need to load the 
content to determine the page language!
                $contentHandler = ContentHandler::getForTitle( $this );
-               $pageLang = $contentHandler->getPageLanguage( $this );
+               $pageLang = $contentHandler->getPageLanguage( $this, null, 
$context );
 
                return wfGetLangObj( $pageLang );
        }
 
        /**
         * Get the language in which the content of this page is written when
-        * viewed by user. Defaults to $wgContLang, but in certain cases it can 
be
-        * e.g. $wgLang (such as special pages, which are in the user language).
+        * viewed by user. Defaults to $wgContLang, but in certain cases it
+        * can be others such as the user lang on special pages.
         *
         * @since 1.20
+        * @param IContextSource $context The context to use in case we're 
using something like the user's language.
         * @return Language
         */
-       public function getPageViewLanguage() {
-               global $wgLang;
-
+       public function getPageViewLanguage( IContextSource $context = null ) {
                if ( $this->isSpecialPage() ) {
                        // If the user chooses a variant, the content is 
actually
                        // in a language whose code is the variant code.
-                       $variant = $wgLang->getPreferredVariant();
-                       if ( $wgLang->getCode() !== $variant ) {
+                       if ( is_null( $context ) ) {
+                               $context = RequestContext::getMain();
+                       }
+                       $lang = $context->getLanguage();
+                       $variant = $lang->getPreferredVariant();
+                       if ( $lang->getCode() !== $variant ) {
                                return Language::factory( $variant );
                        }
-
-                       return $wgLang;
+                       return $lang;;
                }
 
                //NOTE: can't be cached persistently, depends on user settings
                //NOTE: ContentHandler::getPageViewLanguage() may need to load 
the content to determine the page language!
                $contentHandler = ContentHandler::getForTitle( $this );
-               $pageLang = $contentHandler->getPageViewLanguage( $this );
+               $pageLang = $contentHandler->getPageViewLanguage( $this, null, 
$context );
+               return $pageLang;
+       }
+
+       /**
+        * Get the language in which the content of this page is written when
+        * viewed by user. Defaults to $wgContLang, but in certain cases it
+        * can be others such as the user lang on special pages.
+        *
+        * @since 1.22
+        * @param IContextSource $context The context to use in case we're 
using something like the user's language.
+        * @return Language
+        */
+       public function getPageTitleLanguage( IContextSource $context = null ) {
+               global $wgLang;
+
+               if ( $this->isSpecialPage() ) {
+                       // If it's a special page just use getPageViewLanguage.
+                       return $this->getPageViewLanguage( $context );
+               }
+
+               //NOTE: can't be cached persistently, depends on user settings
+               //NOTE: ContentHandler::getPageTitleLanguage() may need to load 
the content to determine the page language!
+               $contentHandler = ContentHandler::getForTitle( $this );
+               $pageLang = $contentHandler->getPageTitleLanguage( $this, null, 
$context );
                return $pageLang;
        }
 
diff --git a/includes/content/ContentHandler.php 
b/includes/content/ContentHandler.php
index dcd33bc..5f87ba5 100644
--- a/includes/content/ContentHandler.php
+++ b/includes/content/ContentHandler.php
@@ -609,17 +609,20 @@
         *
         * @return Language the page's language
         */
-       public function getPageLanguage( Title $title, Content $content = null 
) {
-               global $wgContLang, $wgLang;
+       public function getPageLanguage( Title $title, Content $content = null, 
IContextSource $context = null ) {
+               global $wgContLang;
                $pageLang = $wgContLang;
 
-               if ( $title->getNamespace() == NS_MEDIAWIKI ) {
+               if ( $title->inNamespace( NS_MEDIAWIKI ) ) {
                        // Parse mediawiki messages with correct target language
                        list( /* $unused */, $lang ) = 
MessageCache::singleton()->figureMessage( $title->getText() );
                        $pageLang = wfGetLangObj( $lang );
                }
 
-               wfRunHooks( 'PageContentLanguage', array( $title, &$pageLang, 
$wgLang ) );
+               if ( is_null( $context ) ) {
+                       $context = RequestContext::getMain();
+               }
+               wfRunHooks( 'PageContentLanguage', array( $title, &$pageLang, 
$context->getLanguage() ) );
                return wfGetLangObj( $pageLang );
        }
 
@@ -643,10 +646,10 @@
         *
         * @return Language the page's language for viewing
         */
-       public function getPageViewLanguage( Title $title, Content $content = 
null ) {
-               $pageLang = $this->getPageLanguage( $title, $content );
+       public function getPageViewLanguage( Title $title, Content $content = 
null, IContextSource $context = null ) {
+               $pageLang = $this->getPageLanguage( $title, $content, $context 
);
 
-               if ( $title->getNamespace() !== NS_MEDIAWIKI ) {
+               if ( !$title->inNamespace( NS_MEDIAWIKI ) ) {
                        // If the user chooses a variant, the content is 
actually
                        // in a language whose code is the variant code.
                        $variant = $pageLang->getPreferredVariant();
@@ -659,6 +662,39 @@
        }
 
        /**
+        * Get the language in which the title of this page is written when
+        * viewed by user. Defaults to $this->getPageViewLanguage().
+        *
+        * This default implementation just returns $this->getPageViewLanguage( 
$title, $content ).
+        *
+        * Note that the page title's view language is not cacheable, since it 
depends on user settings.
+        *
+        * Also note that the page title's language may or may not depend on 
the actual content of the page,
+        * that is, this method may load the content in order to determine the 
language.
+        *
+        * @since 1.22
+        *
+        * @param Title        $title the page to determine the language title 
for.
+        * @param Content|null $content the page's content, if you have it 
handy, to avoid reloading it.
+        *
+        * @return Language the page title's language for viewing
+        */
+       public function getPageTitleLanguage( Title $title, Content $content = 
null, IContextSource $context = null ) {
+               if ( is_null( $context ) ) {
+                       $context = RequestContext::getMain();
+               }
+               $pageLang = $this->getPageViewLanguage( $title, $content, 
$context );
+
+               if ( $title->inNamespace( NS_MEDIAWIKI ) ) {
+                       // MediaWiki: namespace titles are always in English
+                       $pageLang = Language::factory( 'en' );
+               }
+
+               wfRunHooks( 'PageTitleLanguage', array( $title, &$pageLang, 
$context->getLanguage() ) );
+               return $pageLang;
+       }
+
+       /**
         * Determines whether the content type handled by this ContentHandler
         * can be used on the given page.
         *
diff --git a/skins/CologneBlue.php b/skins/CologneBlue.php
index 3ada578..9d88bae 100644
--- a/skins/CologneBlue.php
+++ b/skins/CologneBlue.php
@@ -289,10 +289,7 @@
                <?php if ( $this->getSkin()->getSiteNotice() ) { ?>
                <div id="siteNotice"><?php echo 
$this->getSkin()->getSiteNotice() ?></div>
                <?php } ?>
-               <h1 id="firstHeading" lang="<?php
-                       $this->data['pageLanguage'] = 
$this->getSkin()->getTitle()->getPageViewLanguage()->getCode();
-                       $this->html( 'pageLanguage' );
-               ?>"><span dir="auto"><?php echo $this->data['title'] 
?></span></h1>
+               <h1 id="firstHeading"><?php echo $this->data['title'] ?></h1>
                <?php if ( $this->translator->translate( 'tagline' ) ) { ?>
                <p class="tagline"><?php echo htmlspecialchars( 
$this->translator->translate( 'tagline' ) ) ?></p>
                <?php } ?>
diff --git a/skins/Modern.php b/skins/Modern.php
index 52f9fa2..6ed0898 100644
--- a/skins/Modern.php
+++ b/skins/Modern.php
@@ -66,10 +66,7 @@
 ?>
 
        <!-- heading -->
-       <div id="mw_header"><h1 id="firstHeading" lang="<?php
-               $this->data['pageLanguage'] = 
$this->getSkin()->getTitle()->getPageViewLanguage()->getCode();
-               $this->html( 'pageLanguage' );
-       ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1></div>
+       <div id="mw_header"><h1 id="firstHeading"><?php $this->html( 'title' ) 
?></h1></div>
 
        <div id="mw_main">
        <div id="mw_contentwrapper">
diff --git a/skins/MonoBook.php b/skins/MonoBook.php
index aeeb0f8..4017320 100644
--- a/skins/MonoBook.php
+++ b/skins/MonoBook.php
@@ -85,10 +85,7 @@
        <a id="top"></a>
        <?php if ( $this->data['sitenotice'] ) { ?><div id="siteNotice"><?php 
$this->html( 'sitenotice' ) ?></div><?php } ?>
 
-       <h1 id="firstHeading" class="firstHeading" lang="<?php
-               $this->data['pageLanguage'] = 
$this->getSkin()->getTitle()->getPageViewLanguage()->getCode();
-               $this->html( 'pageLanguage' );
-       ?>"><span dir="auto"><?php $this->html( 'title' ) ?></span></h1>
+       <h1 id="firstHeading" class="firstHeading"><?php $this->html( 'title' ) 
?></h1>
        <div id="bodyContent" class="mw-body">
                <div id="siteSub"><?php $this->msg( 'tagline' ) ?></div>
                <div id="contentSub"<?php $this->html( 'userlangattributes' ) 
?>><?php $this->html( 'subtitle' ) ?></div>
diff --git a/skins/Vector.php b/skins/Vector.php
index d477c65..b72abe0 100644
--- a/skins/Vector.php
+++ b/skins/Vector.php
@@ -161,10 +161,7 @@
                        <?php if ( $this->data['sitenotice'] ) { ?>
                        <div id="siteNotice"><?php $this->html( 'sitenotice' ) 
?></div>
                        <?php } ?>
-                       <h1 id="firstHeading" class="firstHeading" lang="<?php
-                               $this->data['pageLanguage'] = 
$this->getSkin()->getTitle()->getPageViewLanguage()->getCode();
-                               $this->html( 'pageLanguage' );
-                       ?>"><span dir="auto"><?php $this->html( 'title' ) 
?></span></h1>
+                       <h1 id="firstHeading" class="firstHeading"><?php 
$this->html( 'title' ) ?></h1>
                        <div id="bodyContent">
                                <?php if ( $this->data['isarticle'] ) { ?>
                                <div id="siteSub"><?php $this->msg( 'tagline' ) 
?></div>
diff --git a/tests/phpunit/includes/content/ContentHandlerTest.php 
b/tests/phpunit/includes/content/ContentHandlerTest.php
index c345513..85bbfb6 100644
--- a/tests/phpunit/includes/content/ContentHandlerTest.php
+++ b/tests/phpunit/includes/content/ContentHandlerTest.php
@@ -113,12 +113,17 @@
                }
        }
 
-       public static function dataGetPageLanguage() {
+       public static function dataGetPageLanguages() {
                global $wgLanguageCode;
 
+               // Title, page lang, page view lang, title lang
+               // For brevity lang codes that are omitted or null will fall 
back to the prev arg
                return array(
                        array( "Main", $wgLanguageCode ),
                        array( "Dummy:Foo", $wgLanguageCode ),
+                       array( "MediaWiki:Version", $wgLanguageCode ),
+                       array( "MediaWiki:Version/en", 'en', null, 'en' ),
+                       array( "MediaWiki:Version/fr", 'fr', null, 'en' ),
                        array( "MediaWiki:common.js", 'en' ),
                        array( "User:Foo/common.js", 'en' ),
                        array( "MediaWiki:common.css", 'en' ),
@@ -130,19 +135,29 @@
        }
 
        /**
-        * @dataProvider dataGetPageLanguage
+        * @dataProvider dataGetPageLanguages
         */
-       public function testGetPageLanguage( $title, $expected ) {
+       public function testGetPageLanguages( $title, $pageLang, $pageViewLang 
= null, $pageTitleLang = null ) {
                if ( is_string( $title ) ) {
                        $title = Title::newFromText( $title );
                }
 
-               $expected = wfGetLangObj( $expected );
+               if ( is_null( $pageViewLang ) ) {
+                       $pageViewLang = $pageLang;
+               }
+               if ( is_null( $pageTitleLang ) ) {
+                       $pageTitleLang = $pageViewLang;
+               }
+
+               $pageLang = wfGetLangObj( $pageLang );
+               $pageViewLang = wfGetLangObj( $pageViewLang );
+               $pageTitleLang = wfGetLangObj( $pageTitleLang );
 
                $handler = ContentHandler::getForTitle( $title );
-               $lang = $handler->getPageLanguage( $title );
 
-               $this->assertEquals( $expected->getCode(), $lang->getCode() );
+               $this->assertEquals( $pageLang->getCode(), 
$handler->getPageLanguage( $title )->getCode() );
+               $this->assertEquals( $pageViewLang->getCode(), 
$handler->getPageViewLanguage( $title )->getCode() );
+               $this->assertEquals( $pageTitleLang->getCode(), 
$handler->getPageTitleLanguage( $title )->getCode() );
        }
 
        public static function dataGetContentText_Null() {

-- 
To view, visit https://gerrit.wikimedia.org/r/63378
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I0ff707d5f04218bef5721e6fc162c6359bb7538a
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/core
Gerrit-Branch: master
Gerrit-Owner: Daniel Friesen <[email protected]>

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to