blob: d709584815f55474df8271621cd37fe7c8563435 [file] [log] [blame]
{
"name": "localize",
"description": "A GNU gettext-inspired (but not conformant) localization library for Node.js",
"homepage": "https://github.com/AGROSICA/node-localize",
"author": {
"name": "David Ellis"
},
"contributors": [
{
"name": "Steven Levithan"
},
{
"name": "Felix Geisendörfer"
},
{
"name": "Clint Andrew Hall"
},
{
"name": "Jerry Jalava"
}
],
"version": "0.4.2",
"main": "./lib/localize",
"dependencies": {},
"devDependencies": {
"expresso": ">=0.8.1"
},
"engines": {
"node": "*"
},
"bin": {
"xlocalize": "./bin/xlocalize.js"
},
"readme": "# The *node-localize* library\nprovides a [GNU gettext](http://www.gnu.org/s/gettext/)-inspired (but not conformant) translation utility for [Node.js](http://nodejs.org) that tries to avoid some of the limitations of the ``sprintf``-bound ``gettext`` (such as translation string parameters being in a fixed order in all translation results) and \"fit in\" better than a straight port.\n\n## Installation\n\nIf you have [npm](http://npmjs.org), just type:\n\n```sh\nnpm install localize\n```\n\n## Usage\n\n``node-localize`` returns an object constructor so multiple simultaneous localization objects may be in use at once (though most cases will probably be a singleton instantiation). The only required parameter on initialization is a ``translations`` object, using the following structure:\n\n```js\nvar Localize = require('localize');\n\nvar myLocalize = new Localize({\n \"Testing...\": {\n \"es\": \"Pruebas...\",\n \"sr\": \"тестирање...\"\n },\n \"Substitution: $[1]\": {\n \"es\": \"Sustitución: $[1]\",\n \"sr\": \"замена: $[1]\"\n }\n});\n\nconsole.log(myLocalize.translate(\"Testing...\")); // Testing...\nconsole.log(myLocalize.translate(\"Substitution: $[1]\", 5)); // Substitution: 5\n\nmyLocalize.setLocale(\"es\");\nconsole.log(myLocalize.translate(\"Testing...\")); // Pruebas...\n\nmyLocalize.setLocale(\"sr\");\nconsole.log(myLocalize.translate(\"Substitution: $[1]\", 5)); // замена: 5\n```\n\n``node-localize`` objects can also be passed a string indicating the directory a ``translations.json`` file can be found. This directory is searched recursively for all ``translations.json`` files in all subdirectories, and their contents combined together, so you can organize your translations as you wish.\n\nThe directory is also searched recursively for directories named ``translations``. These directories are checked for special text files of the form ``varname.txt``, ``varname.es.txt``, ``varname.sr.txt``, etc. The text in ``varname.txt`` is treated as the default language of the application and the ``varname.xx.txt`` are treated as translations of the text. A special ``strings`` object is created where the ``varname`` becomes a property of that object and the default language text is the value of the property. So you can also do the following:\n\n```js\nvar Localize = require('localize');\n\nvar myLocalize = new Localize('./path/to/text/files/');\n\nconsole.log(myLocalize.translate(myLocalize.strings.reallyLongText); // The contents of ./path/to/text/files/translations/reallyLongText.txt, if it exists\n\nmyLocalize.setLocale(\"es\");\nconsole.log(myLocalize.translate(myLocalize.strings.reallyLongText); // The contents of ./path/to/text/files/translations/reallyLongText.es.txt, if it exists\n```\n\n## Dates\n\nBecause date formats differ so wildly in different languages and these differences cannot be solved via simple substitution, there is also a ``localDate`` method for translating these values.\n\n```js\nvar theDate = new Date(\"4-Jul-1776\");\nvar dateLocalize = new Localize(\"./translations\");\ndateLocalize.loadDateFormats({\n\t\"es\": {\n\t\tdayNames: [\n\t\t\t'Dom', 'Lun', 'Mar', 'Mié', 'Jue', 'Vie', 'Sáb',\n\t\t\t'Domingo', 'Lunes', 'Martes', 'Miércoles', 'Jueves', 'Viernes', 'Sábado'\n\t\t],\n\t\tmonthNames: [\n\t\t\t'Ene', 'Feb', 'Mar', 'Abr', 'May', 'Jun', 'Jul', 'Ago', 'Sep', 'Oct', 'Nov', 'Dic',\n\t\t\t'Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio', 'Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre'\n\t\t],\n\t\tmasks: {\n\t\t\t\"default\": \"dddd, d 'de' mmmm yyyy\"\n\t\t}\n\t}\n});\n\nconsole.log(dateLocalize.localDate(theDate)); // Thu Jul 04 1776 00:00:00\nconsole.log(dateLocalize.localDate(theDate, \"fullDate\")); // Thursday, July 4, 1776\nconsole.log(dateLocalize.localDate(theDate, \"mm/dd/yyyy\")); // 07/04/1776\n\ndateLocalize.setLocale(\"es\");\nconsole.log(dateLocalize.localDate(theDate)); // Jueves, 4 de Julio 1776\n```\n\nThe date formatting rules and configuration have been taken from [node-dateformat](https://github.com/felixge/node-dateformat), which has been extended to support multiple simultaneous locales and subsumed into ``node-localize``.\n\n## Complete API\n\n```js\nvar myLocalize = new Localize(translationsObjOrStr, dateFormatObj, defaultLocaleStr);\n// translationsObjOrStr: a conformant translations object or a string indicating\n// the directory where one or more conformant translations.json files are stored\n// dateFormatObj: a conformant date format object, containing one or more locales\n// if not specified, will auto-generate an 'en' locale; if initially specified,\n// will *overwrite* this auto-generated locale object\n// defaultLocale: the locale of all keys in the translations object. Defaults to 'en'\n```\n\n```js\nmyLocalize.setLocale(localeStr);\n// localeStr: a locale string to switch to\n```\n\n```js\nmyLocalize.loadTranslations(translationsObjOrStr);\n// translationsObjOrStr: a conformant translations object or a string indicating\n// the directory where one or more conformant translations.json files are stored\n// Multiple calls to loadTranslations *appends* the keys to the translations\n// object in memory (overwriting duplicate keys).\n```\n\n```js\nmyLocalize.clearTranslations();\n// Wipes out the translations object entirely (if a clean reload is desired)\n```\n\n```js\nmyLocalize.throwOnMissingTranslation(throwBool);\n// throwBool: Boolean indicating whether or not missing translations should\n// throw an error or be silently ignored and the text stay in the default\n// locale. Useful for development to turn off.\n```\n\n```js\nmyLocalize.translate(translateStr, arg1, arg2, ...);\n// translateStr: The string to be translated and optionally perform a\n// substitution of specified args into. Arguments are specified in a RegExp\n// style by number starting with 1 (it is the first argument that can be\n// used and also is the arguments[1] value...), while using a jQuery-style\n// demarcation of $[x], where x is the argument number.\n```\n\n```js\nmyLocalize.loadDateFormats(dateFormatObj);\n// dateFormatObj: a conformant date format object, containing one or more locales\n// Specified locales are appended to the internal object just like\n// loadTranslations.\n```\n\n```js\nmyLocalize.clearDateFormats();\n// Resets the date formats object to just the 'en' locale.\n```\n\n```js\nmyLocalize.localDate(dateObjOrStr, maskStr, utcBool)\n// dateObjOrStr: the date object or string to format as desired in the current\n// locale.\n// maskStr: the predefined mask to use, or a custom mask.\n// utcBool: a boolean indicating whether the timezone should be local or UTC\n```\n\n```js\nmyLocalize.strings\n// Object of key-value pairs defined by files in ``translations`` directories\n// Key is the filename (sans extension) and value is the default language\n// text. Useful for translating very large blocks of text that shouldn't really\n// exist in code.\n```\n\n## _xlocalize_ CLI Utility\n\nStarting at version 0.2.0, ``node-localize``, when installed via NPM, adds an ``xlocalize`` utility command to the _PATH_, which allows for automatic construction of ``translations.json`` files (and can be re-run in the future to update existing files without clobbering any current translations present). It's command switches are as follows:\n\n```\nxlocalize USAGE:\n\n-l\tSet the default language for the translations.json file(s) (default: en)\n-r\tSet xlocalize to generate translations.json files recursively (default)\n-R\tSet xlocalize to only generate a translations.json file for the current directory\n-e\tSet the file extensions to include for translation (default: html,js)\n-t\tSet the languages to translate to (comma separated)\n-h\tShow this help message.\n```\n\nFor example, to create a ``translations.json`` file in the current directory only that will translate from English to Spanish, Portuguese, Italian, and French for HTML and JS files:\n\n```sh\nxlocalize -R -t es,pt,it,fr\n```\n\nAnd if a new language, such as Serbian, is to be translated at a later time, you can use the command:\n```sh\nxlocalize -R -t es,pt,it,fr,sr\n```\n\n## [Express](http://expressjs.com) Integration Tips\n\nIf your website supports multiple languages (probably why you're using this library!), you'll want to translate the page content for each supported language. The following snippets of code should make it easy to use within Express.\n\n### Middleware to switch locale on request\n\n```js\napp.configure(function() {\n ...\n app.use(function(request, response, next) {\n var lang = request.session.lang || \"en\";\n localize.setLocale(lang);\n next();\n });\n ...\n});\n```\n\nI'm assuming you're storing their language preference inside of a session, but the logic can be easily tweaked for however you detect which language to show.\n\n### Export *translate*, *localDate*, and *strings* as static helpers\n\n```js\napp.helpers({\n ...\n translate: localize.translate,\n localDate: localize.localDate,\n strings: localize.strings\n});\n```\n\nYour controllers shouldn't really even be aware of any localization issues; the views should be doing that, so this ought to be enough configuration within your ``app.js`` file.\n\n### Using *translate*, *localDate*, and *strings* in your views\n\n```html\n<h1>${translate(\"My Awesome Webpage\")}</h1>\n\n<h2>${translate(\"By: $[1]\", webpageAuthor)}</h2>\n\n<h3>${translate(\"Published: $[1]\", localDate(publicationDate))}</h3>\n\n{{if translate(strings.reallyLongPost) == strings.reallyLongPost}}\n<strong>${translate(\"Warning: The following content is in English.\")}</strong>\n{{/if}}\n\n{{html translate(strings.reallyLongPost)}}\n```\n\nI'm using [jQuery Templates for Express](https://github.com/kof/node-jqtpl) here, but it should be easy to translate to whatever templating language you prefer.\n\n## Planned Features\n\n* Browser compatibility (use same functions for client-side jQuery Templates, for instance)\n* Optional Country Code support (that falls back to baseline language translation if a specific country code is missing) for regional language differences\n* Numeric localization (1,234,567.89 versus 1.234.567,89 versus 1 234 567,89 versus [Japanese Numerals](http://en.wikipedia.org/wiki/Japanese_numerals) [no idea how to handle that one at the moment])\n* Currency localization; not just representing $100.00 versus 100,00$, but perhaps hooking into currency conversion, as well.\n* Pluralization; one area gettext still beats node-localize is the ability to pluralize words correctly when given the number to pluralize against.\n\n## License (MIT)\n\nCopyright (C) 2011 by Agrosica, Inc, David Ellis, Felix Geisendörfer, Steven Levithan, Scott Trenda, Kris Kowal, Jerry Jalava, Clint Andrew Hall.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in\nall copies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n",
"readmeFilename": "README.md",
"_id": "localize@0.4.2",
"_from": "localize@*0.4.2"
}