[ALOY-728] Add a CLI command to extract i18n strings from alloy code and update the strings.xml files
|Fix Version/s||Alloy 1.2.0, 2013 Sprint 15|
alloy extract-i18ncommand will inspect your TSS and JS files for instances of Titanium's localization functions: * Titanium.Locale.getString() * Ti.Locale.getString() * L() and when it finds them, it will take the i18n key from the first parameter (if it is a string) and add it as an entry to your target language's i18n strings.xml file. The syntax for calling
alloy extract-i18nis as follows:
This command, when applied with --apply, will only add new i18n entries. It will leave any existing entries untouched. So in general,// Shows a before and after of your i18n file, does NOT write the changes $ alloy extract-i18n // Writes the changes to "i18n/en/strings.xml" $ alloy extract-i18n --apply // Specify a different language with another parameter ("en" is the default) $ alloy extract-i18n es // Specify "es" as the language and write the changes to "i18n/es/strings.xml" $ alloy extract-i18n es --apply
alloy extract-i18n --applyis always safe, but just in case, we provide the preview functionality when not using --apply.
originalThe alloy CLI tool is really useful and streamlines the development process. It should propose more tools to the Alloy developer. One tool that i would have loved to have on one of our last projects is a tool to extract internationalized strings from the alloy code (either tss or js files). The user could type:
and this would introspect all the tss and js files, searching for i18n strings (those in the$ alloy extract-i18n <language>
L()method) and adding the new strings to the i18n file for the requested language. If no
languageparameter is passed, the default language is used. In order to act safely with precious i18n files, the behavior could only display the i18n strings found in the project, and only modify the i18n files if the
--forceoption is passed. This command:
Would display:$ alloy extract-i18n fr
this means: "the tool has found 52 i18n strings in the app, 12 of them didn't exist in the[DEBUG] app/styles/account/create.tss: 5 strings found. [DEBUG] app/styles/account/edit.tss: 13 strings found. [DEBUG] ... [INFO] Found 52 unique i18n strings in the code. [INFO] Did not write the i18n file - please pass the "--force" option. [INFO] Completed i18n extraction. Found 12 new strings.
i18n/fr/strings.xmlfile. This command:
Would display:$ alloy extract-i18n fr --force
Which means the same like the command before, except that, in that case, the strings are appended to[DEBUG] app/styles/account/create.tss: 5 strings found. [DEBUG] app/styles/account/edit.tss: 13 strings found. [DEBUG] ... [INFO] Found 52 unique i18n strings in the code. [INFO] Did not write the i18n file - please pass the "--force" option. [INFO] Completed i18n extraction. Found 12 new strings.
i18n/fr/strings.xml. note that: * the tool must be clever enough to remove duplicates (if a string is used several times, it must appear only once in the i18n file) * there could be another option to prune the messages that are not used in the app anymore, for instance
--pruneThis command proposal is inspired by [Symfony](http://symfony.com)'s
translation:updatecommand ([see its code](https://github.com/symfony/symfony/blob/master/src/Symfony/Bundle/FrameworkBundle/Command/TranslationUpdateCommand.php)), which allows to perform the same type of operation within this PHP framework.
- Tony Lukasavage 2013-07-22
test app: https://github.com/appcelerator/alloy/tree/master/test/apps/testing/ALOY-728
Significant refactoring and changes were made to the original PR. The code was made much safer, cleaner, and more powerful. You can peruse the PR for full details, but the highlights are:
Now supports searching for
Titanium.Locale.getString(), not just
The regex for matching more closely follows the guidelines set forth for i18n keys in the wiki
Handles the situation where there's no i18n folder, or no strings.xml file
Fixed a few argument handling bugs
merge() code now merges successfully instead of overwriting the existing strings.xml file with only the new keys
I created a new option "-A, --apply" for writing the i18n files, instead of "-f, --force}}. --force feels like you're doing something wrong, --apply feels cleaner.
alloy extract-i18nwithout --apply will show you a before and after of the target strings.xml file.
alloy extract-i18n --applywill not totally overwrite the existing strings.xml file, but will instead append nodes to the end of the list. This helps preserve the file formatting previous to using
Underscore.js functions were used in a number of places to make the code a bit tighter.
File writes use
\nso that the files print correctly on all host OSes.
Added a test app for ensuring it works as expectedThat should cover it. :) Functional testing should execute the following steps:
Run the test app (ALOY-728)
You should see a label on the screen that says "nothing assigned yet"
After the app starts, delete the existing *i18n* folder
alloy extract-i18n. You should see a before and after that looks like this:
[INFO] ######## BEFORE ######## <?xml version="1.0" encoding="UTF-8"?><resources> </resources> [INFO] ######## AFTER ######## <?xml version="1.0" encoding="UTF-8"?><resources> <?xml version="1.0" encoding="UTF-8"?><resources> <string name="foo">foo</string> <string name="foo1good">foo1good</string> <string name="found_me">found_me</string> <string name="thekey1">thekey1</string> <string name="thekey2">thekey2</string> <string name="thekey3">thekey3</string> <string name="tester">tester</string> </resources> </resources>
alloy extract-i18n --apply
Ensure that after running the above command that the *i18n/en/strings.xml* file contains the contents that you saw in the previous "after" data.
alloy extract-i18n --applyagain. You should get a warning message telling you that there's nothing to do since the file is already up to date.
alloy extract-i18n --apply es.
Ensure that after running the above command that the *i18n/es/strings.xml* file contains the contents that you saw in the previous "after" data.
Go into the *i18n/en/strings.xml* and change the value for the "tester" key to "I work!"
Make sure that your testing emulator/simulator/device is set for english language
Restart the app
You should see a label that says "I work!" now
- Federico Casali 2013-07-30 Verified as working as expected. Titanium SDK 3.1.2.v20130726192706 Alloy 1.2.0-alpha Appcelerator Studio 220.127.116.11307252418 CLI 3.1.2 Node 0.8.22 Android 4.1.2 device and iOS 5 (6.1.4) Closing.