TWIG 2.8 Language Scripts Written December 13, 2000 (for 2.6 series) Revised June 25, 2003 (for 2.8 series) Intro ===== Starting with TWIG 2.6, a centralized system for maintaining translation strings was introduced. This system helps to achieve greater modularity by placing in each feature exactly the strings which it requires, yet also facilitates the translators by keeping all source strings in one place. Starting with TWIG 2.8, a function based, rather than lookup based, string display idiom was introduced. In this function we have socked away code which gracefully handles situations of missing strings and typos, provides positional replacements ala gettext and supports rich pluralization. Ensuring that this structure is managable and achives it's goals to reduce overhead several additonal scripts have been created, these scripts will not be used by end users or administrators, but instead by the TWIG development team. *** Note to Translators *** Do not directly edit any string files other than the ones that reside in setup/Strings/SourceFiles otherwise they will be overwritten the next time these scripts are run! Even if this technical stuff doesn't interest you, please read down to the end for information about when to use non-breaking-spaces ( ) and how to use the positional and plural replacements. The Theory ========== The theory beind the language scripts is simple, separate the translation information from the feature requirements. This allows the language maintainers to continue to update a single file (that has no duplicates in it) but allows for the distribution to split these files up in to the required pieces for better performance. The Scripts =========== generate.strings.php3 Converts the files in setup/Strings/SourceFiles in to the individual feature string files, which are output to setup/Strings/Output. populate.strings.pl Is used to move the files from setup/Strings/Output to the appropriate directories. strings.layout.php3 Supports generate, by defining what strings are required for each of the features. Running generate.strings.php3 ============================= The is a PHP script which can be run either from a web browser, where you have provided for accessing scripts in your TWIG source directory, or from the command line (available in PHP 4 and up). The page should be fairly self-explanatory; in brief, pick the languages and features you want to generate from the two pull-down-menus and click Go. Starting in 2.8, you can also run generate from the command line. Options are specified very similarly to HTTP's GET method rather than typical command line options such as those found in DOS or GNU software. Try this: shell$ php generate.strings.php3 genlang=english Note that you will need write access to your source directory. This is normally not a problem from the command line, but if running from a browser you may need to allow universal write access to the Output directory. Running populate.strings.pl =========================== This is a quick Perl script to move the files generated by generate.strings.php3 in to the right directories. You need to run this script as a user who can write to the TWIG source tree that you are working on. By default this file assumes you are running on a Windows based system, you will have to edit this file to run it on a UNIX based system. Around line 25 you will find instructions on what to do. strings.layout.php3 =================== This file is at the core or the operation of the script system, it tells generate.strings.php3 what strings to put in what files. It's format is based upon three arrays: 1. $StringFiles This is a one-dimensional array of the features that need string files defined. 2. $StringSections This is a one-dimensional array of sections that are contained in $StringLayout. 3. $StringLayout This is a three-dimensional array that contains all the key names that are required for each feature. The first dimension is the feature (as defined in $StringFiles[] ). The second dimension is the section (as defined in $StringSections). The third dimension is an increasing numeric index. For example: $StringLayout["admin"]["TWIGphrase"][0] = "Accounts"; defines the first reequired TWIGphrase index to be Accounts for the admin feature. Adding new TWIGphrases ====================== In TWIG 2.5 and below, if you wanted to add a phrase to the translation files you simply edited the files in lib/strings an you were done. TWIG 2.6 requires a bit more. 1. edit setup/Strings/SourceFiles to add the new phrase 2. edit setup/Strings/strings.layout.php3 and add a new entry under the feature you want to add the phrase 3. run generate.strings.php3 4. run populate.strings.pl This ensures that the change does not get overridden the next time steps 3 and 4 are executed. Non-breaking TWIGphrases ======================== Most TWIGphrases are used as menu options, entry box labels, and other such short phrases. The non-breaking space HTML entity ( ) is therefore desired to keep these short phrases together when a browser might otherwise split the words of the phrase over two (or more!) lines. Because of the heavy internationalization of TWIG, non-breaking spaces will not be found among the keys of a phrase. The reasoning for this is straightforward: some single words in English translate into multiple words in other languages. So, just because there wasn't a non-breaking space in the English version (which was only one word) a non-breaking space would certainly be desired in the translated language (where several words are required). When translating, please keep this in mind, and add non-breaking spaces to your language's phrases as necessary to keep a short phrase on one line. Some TWIGphrases are fairly long sentences, and are used as explanations or error messages. For these phrases, the non-breaking space is *not* desired. Positional Replacements and Plurals =================================== Not every language shares the same syntax and word ordering. Because of these differences, simple string concatenation works very poorly: echo $TWIGphrase["Welcome to TWIG version"] . " " . $version; Those of you who speak SOV and VSO languages are surely bristling by now; this just isn't how you express this in your language. Perhaps what you need to say is approximately, "To TWIG version $version, you are welcome." Enter the positional replacement. By defining the string with its argument internally, your translation can move the argument to whatever location within the string that is needed for correct grammer in your language. echo TWIGPhrase( "Welcome to TWIG version %1", array( $version ) ); This simple mechanism can handle up to 9 replacements in version 2.8 (that is, only a single digit may follow the % sign). Now the astute reader is wondering what about plurals, too? Indeed, not all languages follow the same conventions of pluralization, either! Take this string for instance: echo $TWIGphrase["You have"] . " " . $number . " " . $TWIGphrase["new messages in"] . " " . $mailbox ; English speakers might be mildly annoyed by having "1 new messages" but those languages for which there are 2, 3 or even 4 plural forms, this is a mess! To handle this situation, no changes are needed in the application code; rather, the TWIGPhrase() function knows how to help when asked. Normally, $TWIGphrase is a one-dimensional array with simple mappings from English to your language. However, if a positional replacement needs to be correctly matched to a plural form, $TWIGphrase can be grown to fit. $TWIGphrase["Welcome to TWIG %1"] = "To TWIG %1 you are welcome."; $TWIGphrase["You have %1 messages"]["position"] = 1; $TWIGphrase["You have %1 messages"]["zero"] = "No new messages you have"; $TWIGphrase["You have %1 messages"]["singular"] = "One new message you have"; $TWIGphrase["You have %1 messages"]["plural"] = "%1 new messages you are having"; The "position" element has special meaning: it tells TWIGPhrase() which of the arguments contains the degree number. With only one replacement, this is trivial, but when there are several it is quite important! In order to supply data to the selection algorithm, you must also define a function which returns an index into the phrase's array. This function should be defined in setup/Strings/SourceFiles/yourlanguage.strings.php3: $function["TWIGPluralyourlanguage"] = <<<FUNC_END if( $n == 0 ) return "zero"; else if( $n == 1 ) return "singular"; else return "plural"; FUNC_END; There's isn't really a defined pattern for the return values here, but do make sure to be consistent within your own language file!