Abstract: I just released the first stable version of Translation2. Here's an overview of the package, its purpose and its design.
One recurring topic on many PHP forums is how to deal with the internationalization (i18n) of a website. In particular, an hot question is where to store the translations. Some people like to have them in the database, as it's more convenient to access, others prefer the speed of gettext but are not too enthusiastic about the editing tools, many simply store them in INI files or as PHP arrays. Other people wonder what is the most efficient solution and if they're able to implement it.
PEAR::Translation2 tries to address all these concerns. Now that a stable release is out, let's have a first overview of the package and its features; some tutorials on its usage will follow. If you want to try this package, all you have to do is:
$ pear install Translation2
Translation2 was written with three goals in mind:
- ease of use
1) Ease of use
The Translation2 API is essential, yet powerful. There are two main methods to retrieve the translated strings:
- get($stringID, $pageID, $languageID) to get a single translation for a given language;
- getPage($pageID, $languageID) to get all the translations of a group in a language. NB: a "page" is not necessarily a "web page", it's just a group of strings that are related or belong to the same "section", so it may make sense to group them into a single unit.
You can set a default language with setLang() and a a default page (i.e. the default group of translated strings) with setPageID() so you don't have to pass it as a parameter to each get() or getPage() call.
Along with the base class, there is also an Admin module to manage all the translations in an easy way. Again, the methods are kept to a minimum and are very intuitive:
- addLang(), updateLang() and removeLang() to manage the available languages
- add() and remove() to manage the translated strings
By design, Translation2 has a layered structure: upon the base layer, you can stack one or many decorators to add extra functionality: a fallback language to deal with strings not yet translated in the chosen language, a caching layer (memory-based or file-based), a charset converter, etc...
Adding a decorator is as simple as this:
// $tr is a Translation2 object // english is the main language $tr->setLang('en'); // add a fallback language layer $tr =& $tr->getDecorator('Lang'); $tr->setOption('fallbackLang', 'it') // add a memory-based cache layer: $tr =& $tr->getDecorator('CacheMemory');
Another key feature of Translation2 is having a container abstraction interface, so you can plug different storage containers and access the data in the same way for them all. The official package already provides some database containers (for PEAR DB, MDB and MDB2), one for GetText (using the native extension or a PHP parser), and one XML-based. The API is consistent among all the containers, so the choice is not driven by "how hard it is to set up gettext", but can be made depending on the tools that you might already use, or the confidence you have in a given storage solution.
The last goal of Translation2 is performance. The lightweight and layered design allows a fine-grained choice of what the specific application needs, so if you don't need a feature, you don't have to load it. This holds true for the decorators (you can have none or many of them) and the Admin module. Many translation classes make the mistake to include the administrative tasks in the same unit as the retrieving routines, even if the former are used once every XXX times (where XXX is usually a BIG number) the page is accessed.
I hope this brief page can shed some light on some of the design decisions behind Translation2, and that it can spark some curiosity in those of you who haven't tried it yet. Next time, we'll see some actual usage examples to get it working.
Bookmark this page, I'll link the tutorials from here.
- On batching vs. latency, and jobqueue models
- Updated Kafka PHP client library
- Musings on some technical papers I read this weekend: Google Dremel, NoSQL comparison, Gossip Protocols
- Historical Twitter access - A journey into optimising Hadoop jobs
- Kafka proposed as Apache incubator project
- NoSQL Databases: What, When and Why (PHPUK2011)
- PHPNW10 slides and new job!