ShoutWiki/Patches/Interwiki

Patch description
MediaWiki's interwiki/interlanguage link handling just plain sucks. Why? Because both interwikis (links to other wikis, such as foo) and interlanguage links (links between the different language versions of the same wiki) are stored in the same table.

Due to this, we cannot add the interwiki table into $wgSharedTables &mdash; that would mean that ShoutWiki Hub's interlanguage links (i.e. fr or fi) would work outside ShoutWiki Hub. Obviously on fi.24, fr: should link to fr.24.shoutwiki.com and not to fr.shoutwiki.com.

To work around these limitations, we have written an extension and patched Special:Interwiki extension code.

The interwiki prefixes will always be fetched from the shared DB, $wgSharedDB. The interwiki table in this database should never be empty! Interlanguage links, such as en, fi or fr will be fetched from local interwiki table. Local interwiki tables can be and in most cases, are empty.

extensions/Interwiki/
ShoutWiki uses the SpecialInterwiki extension for managing interwiki and interlanguage links, so we also had to patch that.

This patch was built against a recent version (r83697 for the body file, Special:Code/MediaWiki/83612 for the i18n file) of the Interwiki extension and should be perfectly up-to-date.

extensions/Interwiki/Interwiki_body.php
'; 		$wgOut->addWikiMsg( 'interwiki_intro' ); -		$wgOut->addHTML( $out ); +		$wgOut->addHTML( $lolOut ); $wgOut->addWikiMsg( 'interwiki_intro_footer' ); $selfTitle = $this->getTitle; @@ -281,17 +315,17 @@ 			$wgOut->addHTML( ' ' . $addlink . ' ' ); } -		$dbr = wfGetDB( DB_SLAVE ); -		$res = $dbr->select( 'interwiki', '*', false, __METHOD__ ); +		// Unconditionally load this data from the shared table, no exceptions +		// We assume that the shared interwiki table will always have some rows +		// and will never be empty, because that's the way it should be +		global $wgSharedDB; +		$dbr_shared = wfGetDB( DB_SLAVE, array, $wgSharedDB ); +		$res = $dbr_shared->select( 'interwiki', '*', false, __METHOD__ ); $numrows = $res->numRows; -		if ( $numrows == 0 ) { -			// If the interwiki table is empty, display an error message -			$this->error( 'interwiki_error' ); -			return; -		} 		$out = " -		'; + +		// Build the list of local interlanguage prefixes +		$out .= " $localinterlanguagemsg "; +		$dbr = wfGetDB( DB_SLAVE ); +		$res = $dbr->select( 'interwiki', '*', false, __METHOD__ ); +		$numrows = $res->numRows; +		$lolError = ''; +		if ( $numrows == 0 ) { +			// We can't use $this->error here or else the red, scary error msg will be misplaced...sigh +			$lolError = ' ' . wfMsgHtml( 'interwiki-languagelinks-empty' ) . ' '; +		} else { +			// There is data in local interwiki table, we can safely open the table and fetch stuff +			$out .= " +			'; +		} +		$out .= $lolError; // yes, I know that this is a fucking hack, so what? + 		$wgOut->addHTML( $out ); }