TalkPHP
 
 
Account Login
Latest Articles
» The basic usage of PHPTAL, a XML/XHTML template library for PHP
» Vulnerable methods and the areas they are commonly trusted in.
» Simple way to protect a form from bot
» The Basics On: How Session Stealing Works
» How to keep your forms from double posting data
Advertisement
Associates
Associates
techtuts Darkmindz
CSS Tutorials Tutorialsphere.com - Free Online Tutorials
Boston PHP SurfnLearn
Advertisement
The Framework Basics of Creating Multilingual PHP Applications
   This article will inform you on how many people go about creating multilingual websites, as from the title, the article will outline the lingual framework which then allows you to then introduce other languages with ease.

This article, however, will not attempt to convey how you would automate the translations for one very good reason, and that is a computer translation is nowhere near as good as a human translation. Although computer translations can detect word patterns, the translation still becomes nonsensical in many places, and often unreadable. Thus hiring somebody who speaks fluently both the language you wish to translate to, and the native language of the website, is greatly beneficial to both your website's usability and credibility.

The basic structure introduces what we call phrases. This allows you to specify a phrase for each block of text on your website. It's nothing overly complex, but getting the structure correct is imperative to creating a maintainable system that is still manageable once you expand. I remember creating a system which supported many languages, but because the framework for the system was flawed, the system soon become bloated and thus unmanageable.

Phrases are nothing more than pre-defined phrases in an external file which are then pulled from a file and displayed. For speed reasons I used to use PHP constants for the multi-linguistics. However, since then I have become wiser and therefore the framework I would propose for the phrase framework, would be XML documents.

The fundamental principle is elementary: a parent folder is created and then within the parent folder are language directories - UK for the UK, for instance, and DE for Germany. Each child folder then possesses an XML phrase file for each page of your website. These files contain all the phrases that are used on that particular page, with a unique identification attribute, aptly being id.

An XML phrase is utterly simple and terse as XML should be, but it gives us a very powerful markup-language to work with in terms of its flexibility and scalability:

xml Code:
<phrases>

    <phrase id="introduction">Hello! How are you?</phrase>
    <phrase id="login">You may login below.</phrase>

</phrases>

We have therefore defined two phrases. One of the introduction and the other is the login section. It is vitally important the the id attributes are unique for that file, but may be reprised in other XML phrase documents.

Once we have our basic structure set-up, we can begin creating a simple class which will perform the actions we desire, and extract the exact phrase we're seeking.

php Code:
public function __construct($szPage, $szLanguage = 'UK')
{
    $this->m_pXML = simplexml_load_file(sprintf('./lang/%s/%s.xml', $szLanguage, $szPage));
}

The __construct gives us the perfect opportunity to parse the precise phrase document we're after. It accepts two arguments, $szPage and $szLanguage, respectively:
  1. The unique identifier of the phrase we require.
  2. The language to use for this particular session.

As you can clearly see, we are utilising the SimpleXML library, which is native to PHP 5, to parse our XML document. From those two arguments we can determine exactly which phrase document it is we're going to be using. Once the member variable contains the correct object, we can return from that function and await further instructions.

The only other function we need to construct is one which pulls the exact phrase from the XML phrase document in which we have loaded. We'll be using XPath to query the XML file but will not be going into XPath in this article. The XPath query, in essence, instructs SimpleXML to locate the node that has the unique identifier matching that of which we request via its solitary argument.

php Code:
public function getPhrase($szItem)
{
    $aItem = $this->m_pXML->xpath(sprintf("//phrase[@id='%s']", $szItem));
    $szItem = empty($aItem[0]) ? null : (string) $aItem[0];

    return $szItem;
}

Therefore if our $szItem variable had the value of introduction then the correct phrase would be returned to the front-end. This would thus work something like the following:

php Code:
$pLang = new TalkPHP_MultiLingual('index', 'UK');

echo $pLang->getPhrase('introduction');

In the object instantiation we tell the __construct function that we're dealing with the index page, and the index page should be delivered in the English (UK) language. Our XML files are named after the pages, with the PHP extension omitted and replaced with an XML extension. So the index phrase file would be named index.xml.

If the phrase cannot be found in the phrase document then a simple NULL is returned. This will prevent anything from being echoed out, but if used in conjunction with another subsequent function, should be checked if it has a value.

Naturally, issuing the rather verbose line every time to get the phrase would soon become cumbersome, and therefore creating a concisely named function to do our dirty work for us is well advised. In our case, p will do the dirty work:

php Code:
function p($szItem)
{
    global $pLang;
    echo $pLang->getPhrase($szItem);
}

Which allows us to simply use the following line wherever we wanted to output a phrase:

php Code:
p('introduction');

As the p function echoes and doesn't return, there's no need to echo it on the front-end. This may be a really lazy function, but if you decide to take the former function route then I'm sure you will begin to see the incredible benefits of the p function - where p means print, in our case.

Adding another language to our structure is now so simple. However, not only that, when we introduce another page into our project, we create an XML phrase file in the correct language child directory, and then set our language accordingly. So if we created a members.php page, adding an English XML phrase document for that file would be as easy as creating a file in /lang/UK/ called members.xml. We then define our phrases and off we go.

If in the long run we decide to add the Russian language to our project, we create a folder called RU in /lang/ and then begin creating our phrase file for each individual page. Therefore we'll have index.xml and members.xml, just as we do in the UK directory. Our Russian index.xml may look something like so:

xml Code:
<phrases>

    <phrase id="introduction">Privet! Kak dela?</phrase>

</phrases>

Thanks to my Russian friend. (bless her!). We then change our index.php language to Russian by simply modifying the second argument in the __construct:

php Code:
$pLang = new TalkPHP_MultiLingual('index', 'RU');

echo $pLang->getPhrase('introduction');

This would then output: Privet! Kak dela?

Now, the very reason I've decided to utilise the undeniably powerful XML interchange format is for extendibility purposes, as mentioned at the beginning of this article, but also for the fact that reading, writing and otherwise manipulating XML documents is child's play for SimpleXML.

A year or so ago when I tackled the multilingual framework, I ended up using a series of constants, as aforementioned. However, apart from the scalability issues that arise quite quickly, there's the difficulty of parsing PHP code, and more specifically defines, to create an administrative interface for the facilitation of managing phrases - in whatever language we choose. Parsing XML documents, on the other hand, as well as appending to them is easy and therefore, in my opinion, should be numero uno in anybody's book for storing phrases, it also allows you to easily parse them and therefore if you wanted to create a user interface for adding and removing phrases, then it'd be fairly straightforward with even the most basic of XML knowledge.

Of course, as this article is a basic look at the framework, I have attached the files I have used. Once you have the basic structure in place, which you do now have, it's rather simple to extend onto that however you see fit. And so you should!

Further reading
  • W3Schools on XPath - Link.
  • RSS Parsing with SimpleXML - Link.
  • Creating RSS Documents with DOMDocument - Link.

Download Project

http://www.talkphp.com/downloads/Tal...ltilingual.zip
Report this Article
Last 5 Article Reviews Read All Reviews
   Absolutly Excellent!
Review added by ryanmr on 06-14-2008
This is one of the greatest Articles I've seen here!
Very informative and great examples.
Just two quick questions.
1) How would you handle phrases with Variable parts?
2) How about an article explaining language detection?

All times are GMT. The time now is 05:05 AM.

 
     

Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Optimization by vBSEO 3.1.0