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'] ) {
+?>
+	<div id="p-projects" class="portlet">
+		<h5<?php $this->html('userlangattributes') ?>><?php $this->msg('otherprojects') ?></h5>
+		<div class="pBody">
+			<ul>
+<?php		foreach($this->data['otherprojects'] as $key => $langlink) { ?>
+				<?php echo $this->makeListItem($key, $langlink); ?>
+
+<?php		} ?>
+			</ul>
+		</div>
+	</div>
+<?php
+		}
+	}
+
+	/*************************************************************************************************/
 	function languageBox() {
 		if( $this->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' );
