Index: includes/DefaultSettings.php =================================================================== --- includes/DefaultSettings.php (revision 92156) +++ includes/DefaultSettings.php (working copy) @@ -1827,6 +1827,12 @@ $wgExtraLanguageNames = array(); /** + * Array of interwiki links for which a link in the sidebar should be shown + * Syntax: 'prefix' => 'Project name' (like 'q' => 'Wikiquote') + */ +$wgInterProjectLinks = array(); + +/** * List of language codes that don't correspond to an actual language. * These codes are leftoffs from renames, or other legacy things. * Also, qqq is a dummy "language" for documenting messages. Index: includes/OutputPage.php =================================================================== --- includes/OutputPage.php (revision 92156) +++ includes/OutputPage.php (working copy) @@ -90,6 +90,9 @@ /// Should be private. Array of Interwiki Prefixed (non DB key) Titles (e.g. 'fr:Test page') var $mLanguageLinks = array(); + /// Should be private. Array of inter-project links + var $mInterProjectLinks = array(); + /** * Should be private. Used for JavaScript (pre resource loader) * We should split js / css. @@ -1080,6 +1083,15 @@ } /** + * Get the list of inter-project links + * + * @return Array of inter-project links + */ + public function getInterProjectLinks() { + return $this->mInterProjectLinks; + } + + /** * Add an array of categories, with names in the keys * * @param $categories Array mapping category name => sort key @@ -1429,6 +1441,7 @@ */ public function addParserOutputNoText( &$parserOutput ) { $this->mLanguageLinks += $parserOutput->getLanguageLinks(); + $this->mInterProjectLinks = $parserOutput->getInterProjectLinks(); $this->addCategoryLinks( $parserOutput->getCategories() ); $this->mNewSectionLink = $parserOutput->getNewSection(); $this->mHideNewSectionLink = $parserOutput->getHideNewSection(); Index: includes/parser/Parser.php =================================================================== --- includes/parser/Parser.php (revision 92156) +++ includes/parser/Parser.php (working copy) @@ -1939,6 +1939,15 @@ } wfProfileOut( __METHOD__."-interwiki" ); + # Interprojects + wfProfileIn( __METHOD__."-interproject" ); + global $wgInterProjectLinks; + if ( is_array( $wgInterProjectLinks ) && isset( $wgInterProjectLinks[$iw] ) && $nottalk ) { + $this->mOutput->addInterProjectLink( $iw, $nt, ( $wasblank ? '' : $text ) ); + wfProfileOut( __METHOD__."-interproject" ); + } + wfProfileOut( __METHOD__."-interproject" ); + if ( $ns == NS_FILE ) { wfProfileIn( __METHOD__."-image" ); if ( !wfIsBadImage( $nt->getDBkey(), $this->mTitle ) ) { Index: includes/parser/ParserOutput.php =================================================================== --- includes/parser/ParserOutput.php (revision 92156) +++ includes/parser/ParserOutput.php (working copy) @@ -125,6 +125,7 @@ $mImageTimeKeys = array(), # DB keys of the images used mapped to sha1 and MW timestamp $mExternalLinks = array(), # External link URLs, in the key only $mInterwikiLinks = array(), # 2-D map of prefix/DBK (in keys only) for the inline interwiki links in the document. + $mInterProjectLinks = array(),# Interproject links $mNewSection = false, # Show a new section link? $mHideNewSection = false, # Hide the new section link? $mNoGallery = false, # No gallery on category page? (__NOGALLERY__) @@ -181,6 +182,7 @@ function &getLanguageLinks() { return $this->mLanguageLinks; } function getInterwikiLinks() { return $this->mInterwikiLinks; } + function getInterProjectLinks() { return $this->mInterProjectLinks; } function getCategoryLinks() { return array_keys( $this->mCategories ); } function &getCategories() { return $this->mCategories; } function getTitleText() { return $this->mTitleText; } @@ -214,6 +216,10 @@ function addLanguageLink( $t ) { $this->mLanguageLinks[] = $t; } function addWarning( $s ) { $this->mWarnings[$s] = 1; } + function addInterProjectLink( $iw, $t, $text = '' ) { + $this->mInterProjectLinks[] = array( $iw, $t, $text ); + } + function addOutputHook( $hook, $data = false ) { $this->mOutputHooks[] = array( $hook, $data ); } Index: includes/SkinTemplate.php =================================================================== --- includes/SkinTemplate.php (revision 92156) +++ includes/SkinTemplate.php (working copy) @@ -141,6 +141,7 @@ global $wgPageShowWatchingUsers; global $wgUseTrackbacks, $wgUseSiteJs, $wgDebugComments; global $wgArticlePath, $wgScriptPath, $wgServer; + global $wgInterProjectLinks; wfProfileIn( __METHOD__ ); Profiler::instance()->setTemplated( true ); @@ -488,6 +489,32 @@ } else { $tpl->set( 'language_urls', false ); } + + # Interproject links + $otherprojects = array(); + $getInterprojectLinks = $out->getInterProjectLinks(); + + if ( is_array( $wgInterProjectLinks ) && is_array( $getInterprojectLinks ) ) { + foreach( $getInterprojectLinks as $ipl ) { + $iplPrefix = $ipl[0]; + $iplTitle = $ipl[1]; + $iplText = $ipl[2]; + # For links like [[x:Link|Text]], the "Text" is shown. + # If just [[x:Link]], fall back to default project name as in configuration. + $projectname = ( $iplText ? $iplText : $wgInterProjectLinks[$iplPrefix] ); + $otherprojects[] = array( + 'href' => $iplTitle->getFullURL(), + 'text' => $projectname, + 'title' => $projectname, + 'class' => 'interproject-' . $projectname, + ); + } + } + if( count( $otherprojects ) ) { + $tpl->setRef( 'otherprojects', $otherprojects ); + } else { + $tpl->set( 'otherprojects', false ); + } wfProfileOut( __METHOD__ . '-stuff4' ); wfProfileIn( __METHOD__ . '-stuff5' ); Index: languages/messages/MessagesEn.php =================================================================== --- languages/messages/MessagesEn.php (revision 92156) +++ languages/messages/MessagesEn.php (working copy) @@ -833,6 +833,7 @@ 'viewhelppage' => 'View help page', 'categorypage' => 'View category page', 'viewtalkpage' => 'View discussion', +'otherprojects' => 'On other projects', 'otherlanguages' => 'In other languages', 'redirectedfrom' => '(Redirected from $1)', 'redirectpagesub' => 'Redirect page', Index: skins/MonoBook.php =================================================================== --- skins/MonoBook.php (revision 92156) +++ skins/MonoBook.php (working copy) @@ -177,6 +177,7 @@ protected function renderPortals( $sidebar ) { if ( !isset( $sidebar['SEARCH'] ) ) $sidebar['SEARCH'] = true; if ( !isset( $sidebar['TOOLBOX'] ) ) $sidebar['TOOLBOX'] = true; + if ( !isset( $sidebar['OTHERPROJECTS'] ) ) $sidebar['OTHERPROJECTS'] = true; if ( !isset( $sidebar['LANGUAGES'] ) ) $sidebar['LANGUAGES'] = true; foreach( $sidebar as $boxName => $content ) { @@ -187,6 +188,8 @@ $this->searchBox(); } elseif ( $boxName == 'TOOLBOX' ) { $this->toolbox(); + } elseif ( $boxName == 'OTHERPROJECTS' ) { + $this->projectBox(); } elseif ( $boxName == 'LANGUAGES' ) { $this->languageBox(); } else { @@ -281,6 +284,25 @@ } /*************************************************************************************************/ + function projectBox() { + if( $this->data['otherprojects'] ) { +?> +
+ html('userlangattributes') ?>>msg('otherprojects') ?> +
+
    +data['otherprojects'] as $key => $langlink) { ?> + makeListItem($key, $langlink); ?> + + +
+
+
+data['language_urls'] ) { ?> Index: skins/Vector.php =================================================================== --- skins/Vector.php (revision 92156) +++ skins/Vector.php (working copy) @@ -269,6 +269,9 @@ if ( !isset( $portals['TOOLBOX'] ) ) { $portals['TOOLBOX'] = true; } + if ( !isset( $portals['OTHERPROJECTS'] ) ) { + $portals['OTHERPROJECTS'] = true; + } if ( !isset( $portals['LANGUAGES'] ) ) { $portals['LANGUAGES'] = true; } @@ -284,6 +287,11 @@ case 'TOOLBOX': $this->renderPortal( 'tb', $this->getToolbox(), 'toolbox', 'SkinTemplateToolboxEnd' ); break; + case 'OTHERPROJECTS': + if ( $this->data['otherprojects'] ) { + $this->renderPortal( 'projects', $this->data['otherprojects'], 'otherprojects' ); + } + break; case 'LANGUAGES': if ( $this->data['language_urls'] ) { $this->renderPortal( 'lang', $this->data['language_urls'], 'otherlanguages' );