Permalink
Browse files

added 'template' and 'list' sub-cmds to build-i18n, and l10n instruct…

…ions.
  • Loading branch information...
1 parent 1b695f9 commit 7176a2f38ff187127230540de404dc81e1cfb909 @toolness committed Jan 16, 2013
Showing with 105 additions and 43 deletions.
  1. +24 −0 README.md
  2. +79 −42 bin/build-i18n.js
  3. +2 −1 package.json
View
@@ -38,6 +38,29 @@ here:
http://localhost:8005/examples/alternate-publisher.html
+## Localization
+
+Before localizing, please read the [requirejs i18n bundle][i18n]
+documentation.
+
+To create a localization, first run `node bin/build-i18n.js list`
+to display a list of i18n bundle modules that can be localized. You'll
+need to localize all of these to create a complete localization, but
+anything you don't localize will just fall-back to English.
+
+Suppose you decide you want to localize the `fc/nls/ui` module to `fr-fr`.
+Just do the following:
+
+1. Create the `fc/nls/fr-fr` directory if it doesn't already exist.
+2. Run `node bin/build-i18n.js template fc/nls/ui > fc/nls/fr-fr/ui.js`.
+3. Localize the strings in `fc/nls/fr-fr/ui.js`.
+4. Edit `fc/nls/ui.js` and add `"fr-fr": true` to the object being returned
+ by the module.
+
+You can test out your localization by setting your browser's language
+preference to `fr-fr` and then loading any embedding of your repository's
+friendlycode widget in your browser.
+
## Updating CodeMirror
In the `codemirror2` directory is a mini-distribution of [CodeMirror][]
@@ -61,6 +84,7 @@ for dirpath, dirnames, filenames in os.walk(OUR_CODEMIRROR_PATH):
open(ourpath, "wb").write(open(newpath, "rb").read())
```
+ [i18n]: http://requirejs.org/docs/api.html#i18n
[slowparse]: https://github.com/toolness/slowparse
[hacktionary]: https://github.com/toolness/hacktionary
[CodeMirror]: http://codemirror.net/
View
@@ -1,16 +1,11 @@
-// If args are specified on the command line, assume they are
-// module names, and only export their localizations.
-var MODULE_FILTER = process.argv.slice(2);
-
var fs = require('fs');
+var sys = require('sys');
var resolve = require('path').resolve;
var buildRequire = require('./build-require');
var rootDir = buildRequire.rootDir;
-var templateDir;
-var templateI18n;
var requirejs = require('requirejs');
-var bundles = exports.bundles = {};
var config = buildRequire.generateConfig();
+var bundles = exports.bundles = {};
function findNlsPaths(root, subdir) {
var nlsPaths = [];
@@ -27,52 +22,94 @@ function findNlsPaths(root, subdir) {
});
return nlsPaths;
-};
-
-config.isBuild = true;
-requirejs.config(config);
+}
-findNlsPaths(rootDir).forEach(function(path) {
+function loadModulesInNlsPath(path) {
fs.readdirSync(rootDir + '/' + path).forEach(function(filename) {
var match = filename.match(/^(.*)\.js$/);
if (match) {
var moduleName = path + '/' + match[1];
-
- if (MODULE_FILTER.length &&
- MODULE_FILTER.indexOf(moduleName) == -1)
- return;
-
var bundle = requirejs(moduleName);
bundles[moduleName] = bundle;
}
});
-});
+}
-// Parse all inline l10n strings out of all templates and fill them into
-// the template i18n bundle.
-templateDir = requirejs.toUrl(config.config.template.htmlPath)
- .replace(".js", "");
-templateI18n = config.config.template.i18nPath;
-
-fs.readdirSync(templateDir).forEach(function(filename) {
+function loadInlineL10nStrings() {
var InlineL10n = requirejs('inline-l10n');
- var root = bundles[templateI18n].root;
- var metadata = bundles[templateI18n].metadata;
- var content = fs.readFileSync(templateDir + '/' + filename, 'utf8');
- var defaultValues = InlineL10n.parse(content);
- for (var key in defaultValues) {
- var value = defaultValues[key];
- if (key in root && root[key] != value)
- throw new Error("conflicting definitions for key: " + key);
- root[key] = value;
- metadata[key] = {
- help: 'This string appears in ' +
- '<a href="' + config.githubUrl + '/blob/gh-pages/templates/' +
- filename + '">' + filename + '</a>.'
- };
+ var templateCfg = config.config.template;
+ var templateDir = requirejs.toUrl(templateCfg.htmlPath).replace(".js", "");
+ var root = bundles[templateCfg.i18nPath].root;
+ var metadata = bundles[templateCfg.i18nPath].metadata;
+
+ fs.readdirSync(templateDir).forEach(function(filename) {
+ var content = fs.readFileSync(templateDir + '/' + filename, 'utf8');
+ var defaultValues = InlineL10n.parse(content);
+ for (var key in defaultValues) {
+ var value = defaultValues[key];
+ if (key in root && root[key] != value)
+ throw new Error("conflicting definitions for key: " + key);
+ root[key] = value;
+ metadata[key] = {
+ help: 'This string appears in ' +
+ '<a href="' + config.githubUrl + '/blob/gh-pages/templates/' +
+ filename + '">' + filename + '</a>.'
+ };
+ }
+ });
+}
+
+function showBundleModuleList(indent) {
+ Object.keys(bundles).forEach(function(name) {
+ sys.puts((indent || "") + name);
+ });
+}
+
+function validateNlsModuleName(moduleName) {
+ if (!(moduleName in bundles)) {
+ if (!moduleName)
+ sys.puts("Unspecified module name. Valid choices are:\n");
+ else
+ sys.puts("'" + moduleName + "' is not a valid module name. " +
+ "Valid choices are:\n");
+ showBundleModuleList(" ");
+ sys.puts("");
+ process.exit(1);
}
-});
+}
+
+function main() {
+ var program = require('commander');
+ program
+ .command('template [module-name]')
+ .description('output JS for an i18n bundle module, which can be ' +
+ 'used as a template for localization')
+ .action(function(moduleName) {
+ validateNlsModuleName(moduleName);
+ var root = JSON.stringify(bundles[moduleName].root, null, 2);
+ sys.puts("define(" + root + ");");
+ });
+ program
+ .command('list')
+ .description('display a list of i18n bundle modules')
+ .action(function() { showBundleModuleList(); });
+ program
+ .command('json')
+ .description('output JSON blob containing strings and metadata for ' +
+ 'all i18n bundles')
+ .action(function() {
+ sys.puts(JSON.stringify(bundles, null, 2));
+ });
+ program.parse(process.argv);
+ if (process.argv.length == 2)
+ program.help();
+}
+
+config.isBuild = true;
+requirejs.config(config);
+
+findNlsPaths(rootDir).forEach(loadModulesInNlsPath);
+loadInlineL10nStrings();
-if (!module.parent)
- require('sys').puts(JSON.stringify(bundles, null, 2));
+if (!module.parent) main();
View
@@ -8,7 +8,8 @@
"requirejs": "2.1.x",
"jsdom": "0.2.19",
"tap": "0.3.x",
- "express": "2.5.x"
+ "express": "2.5.x",
+ "commander": "1.1.x"
},
"scripts": {
"optimize": "node bin/build-require.js",

0 comments on commit 7176a2f

Please sign in to comment.