From 2f933fedbaba602b04de928035cc86639d6c8531 Mon Sep 17 00:00:00 2001 From: Daniel Friesen Date: Fri, 14 Jan 2011 08:32:10 +0000 Subject: [PATCH] Fix bug 14267 by adding support for a MediaWiki:Mainpage-nstab. Additionally, *cough* *cough*: * Add a Title::isMainPage helper for the fairly common $title->equals( Title::newMainPage() ); test. * Update wfMessageFallback to also accept an array of message keys instead of requiring them listed as arguments to the function. * Move the bulk of wfMessageFallback code into Message.php instead of leaving it in GlobalFunctions.php * Change the wfMessageFallback implementation so that the Message class handles the fallbacks themselves eliminating any side effects caused by the fact that wfEmptyMsg always used usedb=false, language=userlang when one might actually use a different language or usedb setting in the message object that actually returned the text (this may be considered a wfEmptyMsg regression in 1.18). * Make blank "" message contents fallback like nonexistant messages do. * Re use the new tabAction array handling used to support mainpage-nstab in the talk and view tabs instead of making wfEmptyMsg calls directly in SkinTemplate. --- RELEASE-NOTES | 2 ++ includes/GlobalFunctions.php | 11 ++-------- includes/Message.php | 40 ++++++++++++++++++++++++++++++++---- includes/SkinTemplate.php | 22 +++++++++++++++----- includes/Title.php | 13 ++++++++++++ 5 files changed, 70 insertions(+), 18 deletions(-) diff --git a/RELEASE-NOTES b/RELEASE-NOTES index 1671a6d509..b3324968cd 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -75,6 +75,8 @@ it from source control: http://www.mediawiki.org/wiki/Download_from_SVN * (bug 26208) Mark directionality of some interlanguage links * (bug 26034) Make the "View / Read" tab in content_navigation style tabs remain selected when the action is "purge". +* (bug 14267) Support a MediaWiki:Mainpage-nstab override for the subject namespace + tab on the mainpage of a wiki. === API changes in 1.18 === * (bug 26339) Throw warning when truncating an overlarge API result diff --git a/includes/GlobalFunctions.php b/includes/GlobalFunctions.php index 015c6e81cf..1eef74bde5 100644 --- a/includes/GlobalFunctions.php +++ b/includes/GlobalFunctions.php @@ -479,15 +479,8 @@ function wfMessage( $key /*...*/) { * @since 1.18 */ function wfMessageFallback( /*...*/ ) { - $keys = func_get_args(); - $first = $keys[0]; - foreach ( $keys as $key ) { - if ( wfEmptyMsg( $key ) ) { - continue; - } - return wfMessage( $key ); - } - return wfMessage( $first ); + $args = func_get_args(); + return call_user_func_array( array( 'Message', 'newFallbackSequence' ), $args ); } /** diff --git a/includes/Message.php b/includes/Message.php index 97f77c1aa6..4b44ca5f96 100644 --- a/includes/Message.php +++ b/includes/Message.php @@ -96,7 +96,7 @@ class Message { /** * Constructor. - * @param $key String: message key + * @param $key: message key, or array of message keys to try and use the first non-empty message for * @param $params Array message parameters * @return Message: $this */ @@ -121,6 +121,28 @@ class Message { return new self( $key, $params ); } + /** + * Factory function accepting multiple message keys and returning a message instance + * for the first message which is non-empty. If all messages are empty then an + * instance of the first message key is returned. + * @param Varargs: message keys + * @return Message: $this + */ + public static function newFallbackSequence( /*...*/ ) { + global $wgMessageCache; + $keys = func_get_args(); + if ( func_num_args() == 1 ) { + if ( is_array($keys[0]) ) { + // Allow an array to be passed as the first argument instead + $keys = array_values($keys[0]); + } else { + // Optimize a single string to not need special fallback handling + $keys = $keys[0]; + } + } + return new self( $keys ); + } + /** * Adds parameters to the parameter list of this message. * @param Varargs: parameters as Strings @@ -336,7 +358,7 @@ class Message { protected function getMessageText() { $message = $this->fetchMessage(); if ( $message === false ) { - return '<' . htmlspecialchars( $this->key ) . '>'; + return '<' . htmlspecialchars( is_array($this->key) ? $this->key[0] : $this->key ) . '>'; } else { return $message; } @@ -348,9 +370,19 @@ class Message { protected function fetchMessage() { if ( !isset( $this->message ) ) { global $wgMessageCache; - $this->message = $wgMessageCache->get( $this->key, $this->useDatabase, $this->language ); + if ( is_array($this->key) ) { + foreach ( $this->key as $key ) { + $message = $wgMessageCache->get( $key, $this->useDatabase, $this->language ); + if ( $message !== false && $message !== '' ) { + break; + } + } + $this->message = $message; + } else { + $this->message = $wgMessageCache->get( $this->key, $this->useDatabase, $this->language ); + } } return $this->message; } -} \ No newline at end of file +} diff --git a/includes/SkinTemplate.php b/includes/SkinTemplate.php index 864efaade2..f7c5f707c1 100644 --- a/includes/SkinTemplate.php +++ b/includes/SkinTemplate.php @@ -706,8 +706,16 @@ class SkinTemplate extends Skin { $query = 'action=edit&redlink=1'; } - $text = wfMsg( $message ); - if ( wfEmptyMsg( $message, $text ) ) { + // wfMessageFallback will nicely accept $message as an array of fallbacks + // or just a single key + $msg = wfMessageFallback( $message ); + if ( is_array($message) ) { + // for hook compatibility just keep the last message name + $message = end($message); + } + if ( $msg->exists() ) { + $text = $msg->plain(); + } else { global $wgContLang; $text = $wgContLang->getFormattedNsText( MWNamespace::getSubject( $title->getNamespace() ) ); } @@ -828,12 +836,16 @@ class SkinTemplate extends Skin { } // Adds namespace links + $subjectMsg = array( "nstab-$subjectId" ); + if ( $subjectPage->isMainPage() ) { + array_unshift($subjectMsg, 'mainpage-nstab'); + } $content_navigation['namespaces'][$subjectId] = $this->tabAction( - $subjectPage, 'nstab-' . $subjectId, !$isTalk && !$preventActiveTabs, '', $userCanRead + $subjectPage, $subjectMsg, !$isTalk && !$preventActiveTabs, '', $userCanRead ); $content_navigation['namespaces'][$subjectId]['context'] = 'subject'; $content_navigation['namespaces'][$talkId] = $this->tabAction( - $talkPage, !wfEmptyMsg("nstab-$talkId") ? "nstab-$talkId" : 'talk', $isTalk && !$preventActiveTabs, '', $userCanRead + $talkPage, array( "nstab-$talkId", 'talk' ), $isTalk && !$preventActiveTabs, '', $userCanRead ); $content_navigation['namespaces'][$talkId]['context'] = 'talk'; @@ -841,7 +853,7 @@ class SkinTemplate extends Skin { if ( $title->exists() && $userCanRead ) { $content_navigation['views']['view'] = $this->tabAction( $isTalk ? $talkPage : $subjectPage, - !wfEmptyMsg( "$skname-view-view" ) ? "$skname-view-view" : 'view', + array( "$skname-view-view", 'view' ), ( $onPage && ($action == 'view' || $action == 'purge' ) ), '', true ); $content_navigation['views']['view']['redundant'] = true; // signal to hide this from simple content_actions diff --git a/includes/Title.php b/includes/Title.php index 106eabea53..eeaf20085d 100644 --- a/includes/Title.php +++ b/includes/Title.php @@ -1853,6 +1853,19 @@ class Title { return false; } + /** + * Is this the mainpage? + * @note Title::newFromText seams to be sufficiently optimized by the title + * cache that we don't need to over-optimize by doing direct comparisons and + * acidentally creating new bugs where $title->equals( Title::newFromText() ) + * ends up reporting something differently than $title->isMainPage(); + * + * @return Bool + */ + public function isMainPage() { + return $this->equals( Title::newMainPage() ); + } + /** * Is this a talk page of some sort? * -- 2.20.1