update
The
alloy extract-i18n
command 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-i18n
is as follows:
// 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
This command, when applied with --apply, will only add new i18n entries. It will leave any existing entries untouched. So in general,
alloy extract-i18n --apply
is always safe, but just in case, we provide the preview functionality when not using --apply.
original
The 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:
$ alloy extract-i18n <language>
and this would introspect all the tss and js files, searching for i18n strings (those in the
L()
method) and adding the new strings to the i18n file for the requested language. If no
language
parameter 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
--force
option is passed.
This command:
$ alloy extract-i18n fr
Would display:
[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.
this means: "the tool has found 52 i18n strings in the app, 12 of them didn't exist in the
i18n/fr/strings.xml
file.
This command:
$ alloy extract-i18n fr --force
Would display:
[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.
Which means the same like the command before, except that, in that case, the strings are appended to
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
--prune
This command proposal is inspired by [Symfony](
http://symfony.com)'s
translation:update
command ([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.
PR: https://github.com/appcelerator/alloy/pull/194 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
Ti.Locale.getString()
andTitanium.Locale.getString()
, not justL()
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.
Calling
alloy extract-i18n
without --apply will show you a before and after of the target strings.xml file.Calling
alloy extract-i18n --apply
will 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 usingalloy extract-i18n
.Underscore.js functions were used in a number of places to make the code a bit tighter.
File writes use
os.EOL
instead of\n
so that the files print correctly on all host OSes.Added a test app for ensuring it works as expected
That 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
Run
alloy extract-i18n
. You should see a before and after that looks like this:Next run
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.
Run
alloy extract-i18n --apply
again. You should get a warning message telling you that there's nothing to do since the file is already up to date.Run
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
Verified as working as expected. Titanium SDK 3.1.2.v20130726192706 Alloy 1.2.0-alpha Appcelerator Studio 3.1.3.201307252418 CLI 3.1.2 Node 0.8.22 Android 4.1.2 device and iOS 5 (6.1.4) Closing.