{"id":15013482,"url":"https://github.com/gadicc/meteor-messageformat","last_synced_at":"2025-04-12T04:44:25.763Z","repository":{"id":9087431,"uuid":"10863295","full_name":"gadicc/meteor-messageformat","owner":"gadicc","description":"MessageFormat i18n support for Meteor, with reactive templates","archived":false,"fork":false,"pushed_at":"2021-01-27T15:17:41.000Z","size":951,"stargazers_count":53,"open_issues_count":88,"forks_count":22,"subscribers_count":10,"default_branch":"v2","last_synced_at":"2025-04-10T10:13:42.132Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/gadicc.png","metadata":{"files":{"readme":"README.md","changelog":"History.md","contributing":"Contributing.md","funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-06-22T10:40:48.000Z","updated_at":"2025-03-04T10:50:47.000Z","dependencies_parsed_at":"2022-09-01T20:25:01.832Z","dependency_job_id":null,"html_url":"https://github.com/gadicc/meteor-messageformat","commit_stats":null,"previous_names":[],"tags_count":41,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadicc%2Fmeteor-messageformat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadicc%2Fmeteor-messageformat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadicc%2Fmeteor-messageformat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/gadicc%2Fmeteor-messageformat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/gadicc","download_url":"https://codeload.github.com/gadicc/meteor-messageformat/tar.gz/refs/heads/v2","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248519471,"owners_count":21117757,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-09-24T19:44:20.509Z","updated_at":"2025-04-12T04:44:25.736Z","avatar_url":"https://github.com/gadicc.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Notice: Not in active development\n\nThis project is not currently being actively developed.  The released v1\nstill works (to my knowledge) but reached end of life in 2016.  I am not\nworking on any multi-language projects at this time, but may resume work\non this when I do.  v2 would be a pure-npm (non-Meteor specific) package.\nThank you everyone everyone for all your many years of support!\n\n# meteor-messageformat (v2) [![Build Status](https://api.travis-ci.org/gadicc/meteor-messageformat.svg?branch=v2)](https://travis-ci.org/gadicc/meteor-messageformat)\n\nMessageFormat i18n support, the Meteor way.\n\nEasy reactive use of complicated strings (gender, plural, etc) with insanely\neasy translation into other languages (through a web UI).\n\n## Features\n\n* Super powerful language use via the industry gold standard, MessageFormat\n* Super easy translation via automatic string extraction and translation UI\n* Super easy integration via automatic locale set on moment, parsley, etc\n* Super fast loading, caching, etc.  Works with BrowserPolicy, appcache, etc.\n* Offline support (including changing of languages while offline)\n* Integrates with autoform, momentjs, parsleyvalidator, cmather:handlebars-server\n\nFor full info, docs and examples, see the\n[Meteor MessageFormat home page](http://messageformat.meteorapp.com/)\n(or install/clone the smart package and run `meteor` in its `website` directory).\nFor this pre-release, some info on the site is out of date, and all info in the\nREADMEs will supercede info on the site (for now).\n\n**See the end of this README for a showcase of sites built with\nmeteor-messageformat!**\n\n## Support for Meteor \u003c= 1.2.1 (End of Life)\n\nAt some point later this year (2016), support for Meteor versions below 1.3 will be dropped.  You will continue to be able to use your last installed version of msgfmt - indefinitely - but later updates will rely - in a non-backwards-compatible manner - on featuers provided by Meteor 1.3.  This co-incides with MDG's roadmap to deprecate Atmosphere and move all core Meteor packages to npm.\n\nNew versions will still be on Atmosphere for some time to come, since we are heavily coupled to the Meteor build system for a lot of our \"magic\".  But we'd like to start using ES6+ features and gradually prepare the code for a possible generic npm release in the long term.\n\n## v2 pre-release\n\n**THIS IS AN IN-DEVELOPMENT RELEASE.  YOU SHOULD NOT BE USING IT UNLESS YOU KNOW\nWHAT YOU'RE DOING.  SEE THE VERY END OF THIS DOCUMENT FOR SOME MORE HELP**.\n\nCurrent versions of each package (requires manual, explicit updates until\nthe stable release; consider backing up your database before upgrading):\n\n```\nmeteor add msgfmt:core@2.0.0-preview.23         # 2016-09-05\n\n# released packages\nmeteor add msgfmt:extract                       # 2016-04-01 (v2.0.0)\nmeteor add msgfmt:ui                            # 2016-06-22 (v2.0.0)\n\n# use on of these depending\nmeteor add msgfmt:react                         # 2016-03-14 (v2.0.0) - Meteor 1.3+\nmeteor add msgfmt:react@2.0.0-meteor12          # 2016-03-14 (v2.0.0) - Meteor 1.2\n```\n\nIf you don't want the UI translator on production (i.e. no crowd translation),\ninstead of adding msgfmt:ui, add `msgfmt:ui-dev-only` (no need to specify\nversion).\n\nSubpackage READMEs:\n[msgfmt:core](https://github.com/gadicc/meteor-messageformat/tree/v2/packages/core#readme)\n|\n[msgfmt:extract](https://github.com/gadicc/meteor-messageformat/tree/v2/packages/extract#readme)\n|\n[msgfmt:ui](https://github.com/gadicc/meteor-messageformat/tree/v2/packages/ui#readme)\n|\n[msgfmt:react](https://github.com/gadicc/meteor-messageformat/tree/v2/packages/react#readme)\n\n## Quick Start\n\nThe most common configuration involves:\n\n```bash\n$ meteor add msgfmt:core msgfmt:extract msgfmt:ui\n```\n\nIn your common code (for client + server), add:\n\n```js\nmsgfmt.init('en');\n```\n\nwhere `en` should be your \"native\" language, i.e. the language all your\nstrings are in before any translation occurs.  You can supply an optional\nsecond argument with a key-value dictionary of configuration values, see\nthe [docs](http://messageformat.meteorapp.com/docs) for more.\n\nSetup your strings like this:\n\n```handlebars\n\u003ch1\u003e{{mf 'heading_welcome' 'Welcome to my Site'}}\u003c/h1\u003e\n\u003cp\u003e{{mf 'welcome_name' 'Welcome, {NAME}' NAME=getUserName}}\u003c/p\u003e\n```\n\nFor more complicated examples, see the\n[examples page](http://messageformat.meteorapp.com//examples).\nFor more information about different options, see the\n[docs](http://messageformat.meteorapp.com/docs).\n\nTo translate your strings, go to `/translate` in your app, available by default\nto any registered user.  See the [docs](http://messageformat.meteorapp.com/docs)\nabout custom security policies.\n\n## More info\n\n### Testing\n\nMsgfmt requires Meteor's \"full application\" test mode to work properly with\ntests, i.e. `meteor test --full-app`.  Particularly, if you're calling\n`msgfmt.init('en')` in, say, `lib/config.js` - it's important to understand\nthat Meteor completely ignores this file in 'regular' test mode.  For more\ninformation, please see [issue #242](https://github.com/gadicc/meteor-messageformat/issues/242#issuecomment-298094711).\n\n### Optional Settings\n\nDefaults are shown below.\n\n```js\nmsgfmt.init('en', {\n  // Send translations for all languages or current language\n  sendPolicy: \"current\",\n\n  // Don't invalidate msgfmt.locale() until new language is fully loaded\n  waitOnLoaded: true,\n  // Automatically adjust \u003cbody dir=\"rtl\"\u003e according to the language used\n  setBodyDir: true,\n\n  // Save setLocale() in Meteor.user().locale, sync to multiple clients\n  storeUserLocale: true,\n\n  // Use client's localStorage to avoid reloading unchanged translations\n  useLocalStorage: true // unless sendCompiled: true,\n  // Send translations to the client pre-compiled\n  sendCompiled: false // unless browserPolicy disallowUnsafeEval is set\n});\n```\n\n## Cordova\n\nThere's an issue with the inject-initial package under Cordova which causes information to not be properly hooked to the client. To counter this, you may define the locales of the application in the settings file, under the public element.\n```json\n{\n  \"public\": {\n    ...,\n    \"msgfmt\": {\n      \"native\": \"en\",\n      \"locales\": [\"en\", \"fr\"]\n    }\n  }\n}\n```\n\n### Debug logging\n\nBefore init:\n\n```js\nmsgfmt.init('en', {\n  logLevel: 'debug'   // or 'trace'\n})\n```\n\nAt runtime:\n\n```js\nPackage['jag:pince'].Logger.setLevel('msgfmt', 'debug'); // or 'trace'\n````\n\n### Events\n\n```js\nmsgfmt.on('localeChange', function(locale) {\n  doSomethingWith(locale);\n});\n```\n\nor\n\n```\nTracker.autorun(function() {\n  doSomethingWith(msgfmt.locale());\n});\n```\n\n### Integrating with other packages\n\nThe following calls are done automatically if the package exists:\n\n* `moment.locale()`\n* `ParsleyValidator.setLocale()`\n\n### Reactivity\n\nAll `{{mf ...}}` strings are reactive and depend on the locale.  When\nchanging locales, all strings on the currently viewed page will update,\nwithout any further action or reloading.\n\n* `msgfmt.locale()` is a reactive dependency on the current locale.  When\ncalling `setLocale()`, the value might only change when language data is\nready, depending on the value of `msgfmt.waitOnLoaded`.\n\n* `msgfmt.lang()` is a reactive dependency on the current language.  This\nis only the language component of the locale, not the dialect / cultural /\nregional settings.  e.g. locale `en_US` has a lang of `en`.\n\n* `msgfmt.dir()` is a reactive dependency on the writing direction of the\ncurrent language, either `ltr` or `rtl`.  By default,\n`msgfmt.setBodyDir = true` and we'll change set the `dir` attribute on\nyour page's `body` tag (which you can leverage with appropriate CSS rules).\n\n* `msgfmt.loading()` is a reactive dependency which returns the currently\nloading locale if `msgfmt.waitOnLoaded = true`, or returns `false` when\neverything is loaded.  Useful for UI hints to the user.\n\n### Differences from v0\n\n* The main package is now `msgfmt:core`.\n\n* The translation UI is now a separate package, `msgfmt:ui`.  By default,\nit's deployed to production too.  If you want translation in your dev\nenvironment only, use `msgfmt:ui-dev-only` *instead* (not both).\n\n* `mf_extract` is no more.  Install `msgfmt:extract` and forget about it,\neverything is automatic.\n\n* The main package namespace is now `msgfmt` and not `mfPkg`.  However,\n`mfPkg` still exists as an alias so no need to change existing code.\n\n* Use `msgfmt.setLocale(locale)` to set the locale.\n\n* We now store the client's locale on the server per-connection.  This\nmeans that calling `mf()` from inside a `method` or `publish` will\nautomatically and correctly output the correct language.\n\n* During initial page load, language data is loaded in parallel with a 2nd\nhttp request.  This is cached in localStorage if `msgfmt.useLocalStorage =\ntrue`.  On subsequent visits, only new/changed strings are downloaded.\n\n* Offline support is now official.  In the future, we'll bundle the languages\ninto the client package as part of the Cordova built process, for 100% offline\nsupport without ever needing to connect once.\n\n* disallowUnsafeEval is now supported.\n\n* If `msgfmt.storeUserLocale = true` (default), `setLocale()` will also\nstore the locale in Meteor.user().locale and sync across multiple instances.\n\n### Pre release usage\n\n* Backup your database!  (Particularly your mf* collections)\n* Save your most recent `mfAll.js` translations\n* Delete mfExtract.js and the mf* collections, e.g. `meteor shell` and then:\n```\n\u003e mfPkg.mfStrings.remove({});\n337\n\u003e mfPkg.mfMeta.remove({});\n23\n\u003e mfPkg.mfRevisions.remove({});\n707\n```\n* Stop meteor.  Remove gadicohen:messageformat, add\n  * msgfmt:core\n  * msgfmt:ui\n  * msgfmt:extract\n* Run Meteor and check that everything is working.\n\n## Underlying Library Change\n\nIn v0 we used @SlexAxton's [MessageFormat.js](https://github.com/SlexAxton/messageformat.js/),\nbut switched in v2 to the [FormatJS](http://formatjs.io/) project.  MessageFormat.js is\nmore focused as a server side library with precompilation.  We initially offered the\nprecompilation feature as an option (which also solved a longstanding issue with\nBrowserPolicy's disallowUnsafeEval), but resulted in much more data needing to be sent\nto the client (i.e. slower loading times), and needing to maintain code to handle both\ntypes of sending in different situations.  FormatJS was created using some common code\nfor similar reasons, and\n[is now collaborating](https://github.com/yahoo/intl-messageformat/issues/72) with\nAlex for shared code on both projects (particularly message parsing).  So ultimately,\nno change is needed on user strings and FormatJS was a better bit for this type of\nproject and what we want to offer our users.\n\n## Integrations\n\n### autoform\n\nUse Blaze subexpressions or see Wiki.\n\n### cmather:handlebars-server\n\n**example.handlebars**\n\n```handlebars\n  {{mf 'hello' 'Hello there, {NAME}' NAME=NAME LOCALE=LOCALE}}\n```\n\n**example.js**\n\n```js\n  var out = Handlebars.templates['example']({\n    NAME: 'Chris',\n    LOCALE: 'en_US'\n  });\n```\n\n### momentjs\n\nTransparent integration.  Calls `moment.locale()` on locale change.\n\n### Parsley Validator\n\nTransparent integration.  Calls `ParsleyValidator.setLocale()` on locale change.\n\n## Sites built with Meteor-MessageFormat\n\n* [Openki.net](https://sandbox.openki.net/) - Crowd-sourced Education (there's a [sandbox](https://sandbox.openki.net/) too!) - @1u and @sbalmer\n* [White Rabbit Express](https://www.whiterabbitexpress.com) - Buy from Japan - @Maxhodges\n\nA huge thank you to the above sites and authors for your continued faith and\nsupport in meteor-messageformat over the years, all the way from our early days!\nYour bug hunting, PRs and vocal support have been critical to this project and\nmy motivation in maintaining it.  Thank you so much!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgadicc%2Fmeteor-messageformat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgadicc%2Fmeteor-messageformat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgadicc%2Fmeteor-messageformat/lists"}