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:
<phrase id="introduction">Hello! How are you?</phrase>
<phrase id="login">You may login below.</phrase>
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.
public function __construct($szPage, $szLanguage = 'UK')
$this->m_pXML = simplexml_load_file(sprintf('./lang/%s/%s.xml', $szLanguage, $szPage));
__constructgives us the perfect opportunity to parse the precise phrase document we're after. It accepts two arguments,
- The unique identifier of the phrase we require.
- 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.
Therefore if our
$szItemvariable had the value of introduction then the correct phrase would be returned to the front-end. This would thus work something like the following:
$pLang = new TalkPHP_MultiLingual('index', 'UK');
In the object instantiation we tell the
__constructfunction 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,
pwill do the dirty work:
Which allows us to simply use the following line wherever we wanted to output a phrase:
pfunction 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
pfunction - where
pmeans 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:
<phrase id="introduction">Privet! Kak dela?</phrase>
Thanks to my Russian friend. (bless her!). We then change our index.php language to Russian by simply modifying the second argument in the
$pLang = new TalkPHP_MultiLingual('index', 'RU');
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!
- W3Schools on XPath - Link.
- RSS Parsing with SimpleXML - Link.
- Creating RSS Documents with DOMDocument - Link.