Translation links

From Internationalization

This page documents how links to translated pages are managed for articles, tutorials, and the like (all referred to here as articles) in the W3C I18n Activity pages.

I'll use the following (live instance) as an example. See the 6 links to translations at the top right of the page. http://www.w3.org/International/questions/qa-doc-charset

Until now, every time a new translation was added I had to update all the currently translated pages for a given article, plus set up the newly translated page, to get the right links to display. Although I could cut and paste the code from http://www.w3.org/International/style/langlinks.txt, it involved opening, saving and re-uploading every version of a translated article. A pain for an article with as many translations as the one above.

There are several parts to the solution, all PHP-based, but only one file (the *-trans.php described below) now needs to be changed to add a new translation, and that change is tiny.

Here are the parts:

The article itself

I don't need to change any of the article pages (including the new one). (This is the key benefit of the new approach.)

Each article (or translation) contains the following code:

<?php
include($filename.'-trans.php');
include('../php/bp/nativetext.php'); 
include('../php/bp/boilerplate-'.$clang.'2.php'); 
?>

The article already defines the $clang variable as a language tag, eg. $clang = 'en'; This is unchanged from before, as is the following.

At the place where the link elements appear in the head element you also find: <?php echo $langLinks; ?>

The visible XHTML links are produced as part of the boilerplate text for the top of the document body. Which brings us to...

The boilerplate text

There is one boilerplate file per language on the site. Among other boilerplate stuff, this file contains the following code (this is the Ukrainian boilerplate):

$currLang = array(
'ar'=>'Арабська',
'de'=>'Німецька',
'el'=>'Грецька',
'en'=>'Англійська',
'es'=>'Іспанська',
'fr'=>'Французька',
'he'=>'Іврит',
'it'=>'Італійська',
'ja'=>'Японська',
'ko'=>'Корейська',
'pl'=>'Польська',
'pt'=>'Портуґальська',
'pt-br'=>'Портуґальська',
'ro'=>'Румунська',
'ru'=>'Російська',
'sv'=>'Шведська',
'th'=>'Тайська',
'tr'=>'Турецька',
'uk'=>'Українська',
'vi'=>'Вʼєтнамська',
'zh-hans'=>'Китайський спрощений'
);

$versionList = '';
if (isset($versions) && !($versions[0]['lang'] == $clang && count($versions) == 1) ) { 
	$versionList = '<p class="noprint">&gt; ';
	foreach ($versions as $item) {
		if ($clang != $item) {
			$versionList .= '<span title="'.$currLang[$item].'"><a href="/International/'.$directory.$filename.'.'.$item.'.php" lang="'.$item.
			'" xml:lang="'.$item.'">'.$nativeText[$item].'</a></span>  ';
			}
		}
	$versionList .= '</p>';
	}

$langLinks = '';
if (isset($versions)) { 
	foreach ($versions as $item) {
		if ($clang != $item) {
			$langLinks .= '<link title="'.$nativeText[$item].'" type="text/html" rel="alternate" hreflang="'.$item.'" href="'.$filename.'.'.
			$item.'.php" lang="'.$item.'" xml:lang="'.$item.'" />';
			}
		}
	}

The major change here is the addition of the $currLang array. The $currLang array is used to provide the name of a language in the language of the current page.

The nativetext.php file

This file contains an array declaration that lists language names in the language itself. There is just one such file on the site, and it is included in every article. The content currently looks like this:

<?php
$nativeText = array(
'ar'=>'عربي',
'de'=>'Deutsch',
'el'=>'Ελληνικά',
'en'=>'English',
'es'=>'Español',
'fr'=>'Français',
'he'=>'עברית',
'it'=>'Italiano',
'ja'=>'日本語',
'ko'=>'한국어',
'pl'=>'Polski',
'pt'=>'Português',
'pt-br'=>'Português-BR',
'ro'=>'Română',
'ru'=>'Pусский',
'sv'=>'Svenska',
'th'=>'ไทย',
'tr'=>'Türkçe',
'uk'=>'Українська',
'vi'=>'Tiếng Anh',
'zh-hans'=>'简体汉语'
);
?>

The *-trans.php file

This is what ties everything together, and this is the only file I need to edit, unless we are dealing with a completely new language. There is a *-trans.php file for each article, that lists all the available translations of that article. If the page above is translated into another language I just need to add the new language code to the list. That's it. Job done. None of the other files mentioned above need to be changed at all. That's going to save me a huge amount of time.

Here is the full contents of the http://www.w3.org/International/questions/qa-doc-charset-trans.php file, to complete our example:

<?php
$versions = array('en', 'it', 'ja', 'pl', 'ru', 'sv', 'uk');
?>

I could, of course, have implemented the various *-trans.php files as a single file that lists all articles, and lists languages for each article, and looked for that information automatically. It just seemed easier to maintain and faster to serve if I have one file per article. The current approach also shows more clearly which articles have so far been migrated to the new approach (most articles at the moment use the old boilerplate still - I plan to migrate them mostly as new translations are introduced).

New languages

If we receive a translation into a completely new language, I will need to update each of the boilerplate files and the nativetext.php file, but that's not very often, nor is it much work.