There are many ways to do site translation depending on your requirements. Let me share a method I used once that was not mentioned here. My requirement was one translation file (for easy editing in one place - but you could use any other storage format like a database) and best performance (I didn’t want translation logic to performed on each page request). I used both the translation file and a template engine (Smarty, but I believe the same could be done with other template engines). The template engine was normally used on the whole site for html rendering.
My translation file looked like this:
$trans_table = array(
"DE PAGE_NOT_FOUND" => "Nicht gefunden",
"EN PAGE_NOT_FOUND" => "Page Not Found",
"DE DEFAULT_PAGE_TITLE" => "Kleine Schule",
"EN DEFAULT_PAGE_TITLE" => "Small School",
...
);
Eventually it got as big as 70 KB but this wasn’t problematic at all - you could use a database if it got really huge, no problem.
In templates this was used like this:
<title>## DEFAULT_PAGE_TITLE ##</title>
or for items with parameters (much more rare) that had %s placeholders replaced with sprintf, I used my custom function:
<title>{translate('DEFAULT_PAGE_TITLE', $param1, $param2)}</title>
Naturally, the parametrized translations had to be parsed on every page request. However, I managed to get rid of all translation overhead for unparametrized translations with a trick in Smarty. Smarty compiles templates to PHP code and allows for multiple compiled versions of the same template based on a supplied compile_id. Therefore, I used the language token as the compile_id so that every template compiled to two PHP files (because I had two languages). And then I used another feature of Smarty - pre-filters. With the pre-filters I replaced all unparametrized translation placeholders with the actual translated texts before compilation so that
<title>## DEFAULT_PAGE_TITLE ##</title>
became
<title>Small School</title>
for the English compiled template, and
<title>Kleine Schule</title>
for the German compiled template.
Then it was only a matter of telling Smarty which compile_id to use on page display.
Thanks to this set-up static translations had zero performance impact on the site because the translating logic was only performed once the template was compiled (changed) and then was cached - so the translation table didn’t even have to be loaded on subsequent requests. I had very few parametrized translations so I didn’t bother creating a specific template expansions for them before the compilation stage (I simply used the translate($placeholder, $params)
function in the templates). But for improving their performance I might compile them to something like this:
<title>{sprintf("Small School Number %s", $schoolNumber)}</title>
for English compiled templates, etc.
This may not be a method that is most elegant, because it needs to make use of features that not every template engine supports - otherwise we would need to write our own template compiling solution - at least just for expanding the language placeholders to actual text into separate files. However, I don’t think there are many/any other solutions that would equal or beat this in terms of performance