Coder Social home page Coder Social logo

ember-l10n's Introduction

Ember-l10n

Ember Observer Score npm version

A GNU gettext based localization workflow for ember.

Installation

  • ember install ember-l10n

Using the string extractor requires:

Note: Addon's CLI commands will check dependencies for you and install them on demand (by executing ember l10n:install), so you don't have to do this on your own.

Compatibility

  • Ember.js v3.20 or above
  • Ember CLI v3.20 or above
  • Node.js v12 or above

Configuration

You configure ember-l10n in your config/environment.js:

ENV['ember-l10n'] = {
  // This is required to be set
  locales: ['en', 'de'],

  // These are optional (defaults listed)
  defaultLocale: 'en',
  autoInitialize: false,
  defaultPluralForm: 'nplurals=2; plural=(n != 1);',
  jsonPath: '/assets/locales'
}
  • locales: The available locales for your application.
  • defaultLocale: The default locale to use, if no other matching locale is found.
  • autoInitialize: If you set this to true, the browser locale will be detected on initialization and automatically be set.
  • defaultPluralForm: Overwrite this if your default locale has a different plural form.
  • jsonPath: The folder where the JSON files containing the translations can be found.

You should also activate fingerprinting for your translation files, to ensure they can be properly cached. To do so, you need to add this to your ember-cli-build.js:

let app = new EmberAddon(defaults, { 
  // ... other options... 
  fingerprint: {
    // We need to add json to the fingerprinted extensions
    extensions: ['js', 'css', 'png', 'jpg', 'gif', 'map', 'svg', 'json']
  }
});

Usage

There are two primary parts to ember-l10n

  1. Ember side:
    • Service: API and messages in JS files
    • Helpers: Template messages from HBS files
    • Components: For complex messages in HBS files
  2. CLI:
    • Extractor: Extracts messages from both JS and HBS files
    • Converter: Converts PO files to JSON consumed by addon
    • Synchronizer: Synchronizes message strings with ids from source code (proof reading)

ember-l10n follows the gettext convention that the message ids in your source files are the default language (usually English).

In the ember-l10n workflow, you use the t, and n helpers and l10n.t() / l10n.n() functions to define your strings in your project. Then you run the extractor script to generate pot and po files, which you send off to your translators. After receiving the translated po files for additional locales, you use the same script to convert them into json files. These json files are then loaded by ember-l10n in your application and replaced at runtime.

ember-l10n provides powerful string substitution and even component substitution for dynamic strings. See the Components section below.

Ember Side

Service

The service translates through gettext.js. There are two available methods to be used for translations message ids from JS source:

  • t(msgid, hash)
  • n(msgid, msgidPlural, count, hash)
  • pt(msgid, msgctxt, hash)
  • pn(msgid, msgidPlural, count, msgctxt, hash)
  • tVar(msgid, hash)

tVar() works exactly the same as t(), but it will be ignored by the gettext parser. This is useful if your message ids are variables, for example: l10n.t(myProperty) would create a myProperty entry in your po-file when gettext is run. So in this case, l10n.tVar(myProperty) should be used instead.

Furthermore, there's an auto initialization feature (default: false), which detects user's locale according to system preferences. If the user's locale is supported , the corresponding translations are loaded. If the user's locale is not supported, the default locale will be used instead (default: "en"). Please use the following method to change locales:

  • setLocale(locale)

The following utility methods are also available:

  • getLocale()
  • hasLocale(locale)
  • detectLocale()
  • setDetectedLocale()

Helpers

For handling your translations within your templates you can use t and n helper:

Singular translations:

The t helper provides gettext singularization for message ids. It takes singular message id as positional arguments. All placeholders can be provided through named arguments.

{{t "Your current role: {{role}}" role=someBoundProperty}}

If you have strings which are variables (e.g. enums), you can also use the t-var helper: {{t-var myProperty}}. It works the same way as the t-helper, but it will be ignored by the gettext parser.

Plural translations:

The n helper provides gettext pluralization for message ids. It takes singular and plural message ids as well as actual amount as positional arguments. All placeholders can be provided through named arguments (hash).

Short version:

{{n "{{count}} apple" "{{count}} apples" countProperty}}

Long version:

Please note: If your count placeholder has another name than "{{count}}", you have to explicitly provide it as named hashed in addition to positional parameter (as well as for all other placeholders within those message ids!).

{{n "{{customCount}} apple from shop {{shopName}}" "{{customCount}} apples from shop {{shopName}}" countProperty customCount=countProperty shopName=shopProperty}}
Contextual translations:

To support contextual translations from templates, there exist both pt and pn helpers, which accept a context as 2nd or 4th paremeter:

{{pt "user" "MY_CONTEXT"}}
{{pn "user" "users" countProperty "MY_CONTEXT"}}

Please note: Both contextual helpers also accept placeholders just as their non-contextual counterparts t and n.

Components

If you have complex message ids, which should contain "dynamic" placeholders, which can also be replaced with components (such as a link-to), you can use the get-text component.

<GetText
  @message={{t "My translation with {{dynamicLink 'optional link text'}} and {{staticLink}}."}} as |text placeholder|>
  {{!-- You can omit the if helper if you have only one placeholder --}}
  {{~#if (eq placeholder 'dynamicLink')}}
      {{~#link-to 'my-route'}}
        {{~text}} {{!-- will render 'optional link text' so that it's contained in PO file! --}}
    {{~/link-to~}}
   {{~/if~}}
   {{~#if (eq placeholder 'staticLink')}}
      <a href="http://www.google.com">Google</a>
   {{~/if~}}
</GetText>

Please note: If your message id contains HTML, you have to set @unescapeText={{true}} on the component. Be sure to use this option only in combination with safe strings and don't make use of it when dealing with user generated inputs (XSS)!

Testing

In tests, ember-l10n should work without any further work.

2. CLI

Extractor

The extractor extracts message ids from the JS and HBS files in your Ember project. It generates the corresponding PO files for translation. Later, it will convert the translated POs into JSON files to be used for client side translation within your Ember app. Please note: Make sure turning off the development server while extracting, otherwise process slows down due to livereload!

Run the following command from your Ember project root for extraction:

  • ember l10n:extract

To see all available command line options for the extractor script please run:

  • ember l10n:extract -h
ember l10n:extract <options...>
  Extract message ids from app
  --default-language (String) (Default: 'en') The default language used in message ids
    aliases: -d <value>
  --bug-address (String) (Default: '[email protected]') The email address for translation bugs (configured in config/l10n-extract.js)
    aliases: -b <value>
  --copyright (String) (Default: 'My Company') The copyright information (configured in config/l10n-extract.js)
    aliases: -c <value>
  --from-code (String) (Default: 'UTF-8') The encoding of the input files
    aliases: -e <value>
  --extract-from (Array) (Default: ['./app']) The directory from which to extract the strings
    aliases: -i <value>
  --include-patterns (Array) (Default: []) List of regex patterns to include for extraction. Defaults to all files. (configured in config/l10n-extract.js)
    aliases: -x <value>
  --skip-patterns (Array) (Default: ['mirage','fixtures','styleguide']) List of regex patterns to completely ignore from extraction
    aliases: -s <value>
  --skip-dependencies (Array) (Default: []) An array of dependency names to exclude from parsing.
    aliases: -sd <value>
  --skip-all-dependencies (Boolean) (Default: true) If this is true, do not parse the node_modules/lib folders. (configured in config/l10n-extract.js)
    aliases: -sad  
  --extract-to (String) (Default: './translations') Output directory of the PO-file
    aliases: -o <value>
  --keys (Array) (Default: ['t', 'pt:1,2c', 'n:1,2', 'pn:1,2,4c']) Function/Helper Keys to be used for lookup
    aliases: -k <value>
  --language (String) (Default: 'en') Target language of the PO-file
    aliases: -l <value>
  --pot-name (String) (Default: 'messages.pot') The name of generated POT-file (configured in config/l10n-extract.js)
    aliases: -n <value>
  --package (String) (Default: 'My App') The name of the package (configured in config/l10n-extract.js)
    aliases: -p <value>
  --generate-only (Boolean) (Default: false) If only PO-file should be created from POT without extraction
    aliases: -g
  --generate-from (String) (Default: 'messages.pot') Source POT-file to be used in conjunction with `-g` flag
    aliases: -f <value>
  --generate-to (String) (Default: null) Target PO-file to be used in conjunction with `-g` flag - CAUTION: uses `${language}.po` as default
    aliases: -t <value>
Usage hints:

Once you have extracted message ids with ember l10n:extract, which creates a domain messages.pot file, you can generate PO-files for other languages by using -g option without having to run extraction again like so:

  • ember l10n:extract -g -l de (creates german PO file from POT file)

If you have excluded some files from prior extractions with -x and want to merge them with your messages.pot you can do:

  • ember l10n:extract -g -l en (merge english PO file)
  • ember l10n:extract -g -l de (merge german PO file)

Converter

The converter will turn a given PO into a JSON file to be loaded by the service.

Run the following command from your Ember project root for conversion:

  • ember l10n:convert

To see all available command line options for the converter script please run:

  • ember l10n:convert -h
ember l10n:convert <options...>
  Convert PO files to JSON
    --convert-from (String) (Default: ./translations) Directory of PO file to convert
      aliases: -i <value>
     --convert-from-file (String) Optional full path to file to convert. Takes precedence over convert-from & language.
      aliases: -f <value>
    --convert-to (String) (Default: ./public/assets/locales) Directory to write JSON files to
      aliases: -o <value>
    --language (String) (Default: en) Target language for PO to JSON conversion
      aliases: -l <value>
    --validate-throw (String) (Default: null) For which validation level the script should abort. Can be: ERROR, WARNING, null
      aliases: -vt <value>
    --dry-run (Boolean) (Default: false) If true, only generate but do not actually write to a file
      aliases: -dr

Note that this will also validate the generated JSON file for common syntax errors. For example, it will check if e.g. This is {{description}} is wrongly translated to Das ist die {{Beschreibung}}. It will print out any found issues to the console. Alternatively, you can specify validate-throw=ERROR to force the script to abort if an error is found.

Synchronizer

The synchronizer will parse a given PO file, use message strings from each entry and uses them as new message ids accross JS and HBS files in your app. This is especially helpful if you proof read your current message ids before handing them over to translators for other languages.

Run the following command from your Ember project root for synchronization:

  • ember l10n:sync

To see all available command line options for the synchronization script please run:

  • ember l10n:sync -h
ember l10n:sync <options...>
  Synchronize message strings with message ids (proof reading)
  --sync-from (String) (Default: './translations') Directory of PO files
    aliases: -i <value>
  --sync-to (Array) (Default: ['./app']) Directory of JS/HBS files
    aliases: -o <value>
  --language (String) (Default: 'en') Language of PO file being used as base
    aliases: -l <value>
  --keys (Array) (Default: ['t', 'pt:1,2c', 'n:1,2', 'pn:1,2,4c']) Function/Helper Keys to be used for lookup
    aliases: -k <value>

Global options

If you want to set global options for any of the above commands for your project, you can do so by providing a config file under config/l10n-${command}.js. An example of global options for extract command located under config/l10n-extract.js could look like this:

module.exports = {
  "bug-address": "[email protected]",
  "copyright": "Copyright by Another Company",
  "package": "Another App",
  "exclude-patterns": [
    "\/some\/exclude\/path",
    "some-other-pattern(?!not-followed-by-this)",
  ],
  "skip-patterns": [
    "\/some\/skip\/path",
    "(?:\/another\/skip)?path",
  ]
}

Note for Upgrading

Upgrading from 4.x to 5.x

In 5.0.0, the configuration format was changed, in order to align better with the Octane world. Instead of overwriting the l10n service in your app, you now pass the configuration in config/environment.js:

ENV['ember-l10n'] = {
  // This is required to be set
  locales: ['en', 'de'],

  // These are optional (defaults listed)
  defaultLocale: 'en',
  autoInitialize: false,
  defaultPluralForm: 'nplurals=2; plural=(n != 1);',
  jsonPath: '/assets/locales'
}

Other notable changes:

  • autoInitialize defaults to false now, as you usually want to set the locale manually (e.g. in the application route's beforeModel hook).
  • If you have been overwriting some fields for tests, the recommended way to do so now is different:
class ExtendedL10nService extends L10nService {
  _loadConfig() {
    let config = {
      locales: ['de', 'en', 'ko'],
      autoInitialize: false,
      defaultLocale: 'de',
    };

    return super._loadConfig(config);
  }

  _getWindow() {
    return {};
  }
}

Unless you are doing something very special, you shouldn't need to extend ember-l10n/services/l10n anymore.

Upgrading from 3.x to 4.x

In 4.0.0, the dependency on ember-cli-ifa was dropped. If this was only used by ember-l10n, you can safely remove it and any configuration for it from your app, including generating (and fingerprinting) an assetMap.json file.

If you used to have a custom jsonPath configured in your application, please remove it from your l10n service, and instead configure it in your config/environment.js:

'ember-l10n': {
  jsonPath: 'assets/my-custom-locales-path'
}

Looking for help?

If it is a bug please open an issue on github.

Versioning

This library follows Semantic Versioning

Legal

Cropster, GmbH Β© 2020

@cropster

Licensed under the MIT license

ember-l10n's People

Contributors

arm1n avatar dependabot[bot] avatar ember-tomster avatar iamareebjamal avatar mydea avatar ramblurr avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar

ember-l10n's Issues

Implement exists() function

In order to achieve maximal compatibility with ember-i18n and make migration as easy as possible, I propose that we add a l10n.exists(key) function. Basically, this function should return true if the given key exists for the currently set locale, else false.

Concretely, this is used by https://github.com/jasonmit/ember-i18n-cp-validations/blob/master/addon/initialize.js, which I am porting over for ember-l10n. It's not super important, but I guess it would be nice and an easy addition. If that makes sense, I'll make a PR?

Question

Hello, maintainers :) I want a way for strings to be extracted but l10n.t returns translated strings, so is there is any way to modify the library that returns untranslated string but extracts it using CLI?

Ensure quotes are not changed

Currently, we often have the issues that our translators accidentally change quotes in the translations.
This especially happens with macOS and "Smart Quotes".

E.g. it changes:

<a href="https://google.com">google</a>

to

<a href=β€œhttps://google.com”>google</a>

which completely breaks the link.

We should convert these (as well as converted single quotes) back to regular quotes, to ensure nothing breaks. This can happen during ember l10n:convert.

Plural messages broken in 1.0.0

The update broke pluralization placeholders evaluating to false - so also including f.e. 0.

The following:

{{n '{{count}} apple}}' '{{count}} apples' 0}}

would result in:

{{count}}Β apples.

tVar usage?

Hi,

Can you explain a little more how tVar works?
I understand that tVar is to ignore an entry in the parsing/extracting phase however you still want a translation for that entry at some point.
So how do you provide a translation for tVar if it's not with the extract command?

Sync command doesn't seems to work

Hi,

I not 100% sure to fully understand ember l10n:sync command, so let me explain what I've try.

Using a new ember app:

  • ember-source: ~3.15.0
  • ember-l10n: ^4.3.1

Here is my template

template/application.hbs:

{{!-- The following component displays Ember's default welcome message. --}}
{{!-- Feel free to remove this! --}}

{{t "simple text"}}

{{outlet}}

I generate po files using ember l10n:extract

translations/en.po:

msgid ""
msgstr ""
"Project-Id-Version: PACKAGE VERSION\n"
"Last-Translator: Automatically generated\n"
"Language-Team: none\n"
"Language: en\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"

#: app/templates/application.hbs:4:0
msgid "simple text"
msgstr "simple text"

I change msgid "simple text" to msgid "some text" in translations/en.po

I expect ember l10n:sync to modify my template/application.hbs to

{{t "some text"}}

However it does nothing

% ember l10n:sync

========================================
PARSING SOURCE FILES
========================================

Checked ./app/app.js... unchanged βœ”
Checked ./app/controllers/application.js... unchanged βœ”
Checked ./app/router.js... unchanged βœ”
Checked ./app/services/l10n.js... unchanged βœ”
Checked ./app/templates/application.hbs... unchanged βœ”

No files updated βœ”

FINISHED βœ”

Is it expected?

Bring back TypeScript support for 3.x

After updating to version 3.0.0 running ember l10n:extract results in the following error:

Extracting app/adapters/application.ts >>> messages.pot...
Line 17: Unexpected identifier

Line 17 is where the typescript declaration sits:

declare module 'ember-data' {
  interface AdapterRegistry {
    'application': Application;
  }
}

Is there any way to make it ignore the declarations?

Introduce message contexts in l10n service

In order to use same message ids we should introduce context based messages. Short example:

#: some/source/code/file.js
msgctxt "Base units"
msgid "KG"
msgstr "kg"
⁠
#: other/source/code/file.js
msgctxt "Countries"
msgid "KG"
msgstr "Kyrgyzstan"

This will not only involve l10n service, but also new template helpers as well as extending the extractor.

Remove excluded.pot functionality

Currently, there is an in-built way to specify --exclude-patterns to get certain translations to go into a special excluded.pot file.

We should remove this functionality in favor of adding a new include-patterns option, so that people can do this manually if they want by running ember l10n:extract twice with different --include-patterns/--skip-patterns.

This will help us to further streamline the extraction process.

Placeholders are translated implicitly

Hi! Thanks for this great addon. In a project I'm working on we have noticed strange translation behaviour.

When a value passed to a placeholder is included in the translation map the passed value will implicitly be translated. This is pretty counterintuitive and unnecessary as this could also be achieved by using a subexpression in the template layer or using l10n.t explicitly from javascript.

Example:

// with a translation map that maps "world" to "welt" 
{{t "Hello {{name}} name="world"}}
// => "Hello welt"

To work around this we are currently overriding _strfmt and remove this line

I'm not sure when this behaviour would be desired but this should easily be possible to do via a subexpression:

{{t "Hello {{name}} name=(t "world")}}

I'd prefer not overriding _strfmt in the consuming app so maybe this behaviour could be made configurable. Is there a reason why this is included?

Thanks again for this great addon. Happy to submit a PR that changes this behaviour.

Hash values passed to t helper should not return the translated string

Hi guys!

Just noticed something in my company's app when using your lib. It looks like param values passed to the t helper are also being translated. So for example:

{{t "{{creator}} and {{count}} other" creator=displayName count=otherCreatorsCount}}

Now, if there's a translation entry for the creator param, the translated value gets rendered!

I discovered that this is due to the _strfmt function here. Is there a reason we can't just return the param string as-is (return value; instead of return gettext(value)?

Just wondering if this is normal behaviour, and as to why it was implemented this way?

Thanks πŸ˜„

Validation seems to be buggy

When running f.e. ember l10n:convert -l de -vt ERROR the process stops and logs the following:

errors.findBy() is not a function

@mydea Can you please look into it?

Validate translations

It happened a few times that our translators made mistakes during translations. Not translation-related mistakes, but syntax related.

The mistakes are broadly in three categories:

  1. Translating placeholders:

For example: This is {{description}} might be translated to Das ist die {{Beschreibung}}. This breaks the replacement.

  1. Changing quotes for the {{get-text}} component:

For example: Follow {{link 'the link'}} might be be changed to Follow {{link β€˜the linkβ€˜}} by translation software. This breaks, as it only recognizes single & double quotes.

  1. Not translating {{get-text}} content:

While this is not breaking, it is apparently often unclear and leads to untranslated texts. For example:
Follow {{link 'the link'}} might be translated to Folge {{link 'the link'}}. This would be more of a warning than an error.

I propose to add validation for these cases to the ember l10n:convert command. This could check the generated JSON and output issues.

Proposed functionality:

  • Print out errors and warnings to the console
  • Allow to specify a validate-throw argument, which can be set to ERROR or WARNING
    • If this is set, and at least one validation error of that level or higher is found, it should abort creation of the JSON file.
    • By default, this would be off, so the default behavior wouldn't change except for a more verbose console output (possibly)

Security: Don't implicitly mark helper outputs as htmlSafe

Current template helper functions such as t or n wrap output implicitly in Ember.String.htmlSafe() calls, which could lead to potential security lacks when using in combination with user inputs. Therefore, it should be stripped out and hand responsibility for marking output as HTML safe to addon consumer. This can be done as follows:

HBS:

{{{t "<strong>unescaped text</strong>"}}}

JS:

let trans = l10n.t("<strong>unescaped text</strong>");
let safe = Ember.String.htmlSafe(trans);

Change counter is wrong for sync command

When invoking the following command:

ember l10n:sync

The counter for changed files at the end of the process seems to be wrong. It counts actual changes instead of changed files only.

l10n:extract throws error and stops

After following the README info (installing, etc), running extract fails and generates an error.

ember install ember-l10n πŸ‘
ember g ember-l10n-initializer my-l10n-initializer πŸ‘

Used a single helper {{t 'project'}} as a first test, then ran extract

ember l10n:extract
find: no such file or directory: node_modules/make-array/addon/**/*.js 🚨

This looks like a great addon... excited to use it.

Some message ids are ignored

The following string: {{t '<No Name'}} leads to an empty string. {{t '< No Name >'}} works, though. Note that for this case, the string was not in the en.json file yet.

Investigate alternatives to eval

Currently this (great) addon uses unsafe code evaluation here, so it cannot be used on sites without specifying Content-Security-Policy script-src 'unsafe-eval' ....; This is a no go in applications with higher security requirements.

Ideally we could find a way to refactor the code to not use evaluation.

I'm sure there was a good reason to use eval in the first place, rather than static code, but I'm not sure what those are. Do you remember @mydea ?

Build problems after updating ember-l10n from 4.x to 5.x

I upgraded ember-l10n(devDependency) package from 4.x to latest version which is 5.1.0, after that ember serve doesn't work.
I tried uninstalling and reinstalling the package, but no luck.

I get the error:

Build Error (CreateEmberL10nFastBootAssetMap)

ENOENT: no such file or directory, scandir '/tmp/broccoli-7518h8A17KW9hHxR/out-1002-append_ember_auto_import_analyzer//tmp/broccoli-7518h8A17KW9hHxR/out-1002-append_ember_auto_import_analyzer'

Here's the stack trace: https://pastebin.com/qCuWzCig

Output from ember version --verbose && npm --version && yarn --version:

ember version: octane
yarn version: 1.22.11
npm version: 6.14.15

Add changes command

Sometimes, it happens that you accidentally introduce new translations in your app. E.g. by adding different versions of capitalization, e.g. "Item count" and "Item Count".

It would be nice to have a ember l10n:changes command, that basically runs an extraction & prints out all new message ids that weren't in the previous version.

When generating, create default locales dir + en.json

When installing ember-l10n on a fresh project, it creates the service which references /assets/locales and en.json, both of which probably don't exist.

It would be nice if the blueprint could create this directory and add a skeleton en.json file.

Upgrade to shelljs 0.8.4

Node.js 14 is currently considering printing a warning when a non-existent
property of module.exports is accessed while in a circular require()
dependency, in order to make it easier to catch issues with circular
dependencies.

Refs: nodejs/node#29935

v0.8.4 included a commit to prevent circular dependency warnings in Node 14.

See also: shelljs/shelljs#973

Add override option to ignore extract error

If we use a non-literal string or a variable in any of the functions or helpers like t(value) instead of t('Pending'), an error is thrown saying "You need to pass a string as argument to l10n methods"

throw new Error(
`You need to pass a string as argument to l10n methods: ${fileName}:${item.loc.start.line}:${item.loc.start.column}`
);

This is the correct behaviour to ensure best practices but sometimes we need to pass non-literal values which we receive from server or are looping over in template. For example, there are 7 possible states of an order: initializing, pending, completed, placed, canceled, refunded, expired

We have translated all them but we can't use t(order.status) because it'll throw an error while extracting. Similarly, if I have to show a filter for all these statuses in the template, I'd loop for them like:

{for each Order.status as |status|}
	<span>{{t status}}</span>
{/for}

It'll work in runtime but throw an error while extracting. So, I'm thinking of 2 possible cases:

  1. Add an option to show recoverable errors like this to warnings instead of halting errors
  2. Add an override option to ignore certain dynamic calls to the functions, and ignore errors in those. For example, <span>{{t status ignoreExtract=true}}</span>. This way, the behaviour remains opt in and people can continue receiving helpful errors elsewhere and only opt-out of extraction if there is no other way

Translations in TypeScript files are ignored

When extracting translations from an Ember project using TypeScript, all translations in *.ts files are ignored.

I fixed the bug localy by changing directories.map(dir => `${dir}/**/*.js`) to directories.map(dir => `${dir}/**/*.ts`) inside of _extractFromJS (which in turn breaks JS support).

I would like to create a pull request with a better fix, but before I do that, it would be nice to know if you prefer a new function called _extractFromTS or if I should just expand on the JS function to include *.ts files as well.

Multiline message ids not found due to whitespace characters

Assuming the following message id:

{{t 
	"I am a multiline message id.
	Thus, I need multiple lines."
}}

This fails when doing the key lookup in json files generated from PO with command ember:l10n sync. So sanitizing message ids from templates and source code is necessary.

Does not work with fastboot

Starting from 4.0.0, it does not work with fastboot

ReferenceError: document is not defined
    at Class.<anonymous> (/home/iamareebjamal/git/open-event-frontend/dist/assets/addon-tree-output/ember-l10n/services/l10n.js:184:1)

Error while extracting: duplicate message definition

While running the extract command, the messages are extracted successfully but an error occurs while generating messages.pot

Extracted 385 files βœ”

========================================
UPDATING POT FILE
========================================
        
./tmp/ember-l10n/messages.pot:495: duplicate message definition...
./tmp/ember-l10n/messages.pot:312: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:740: duplicate message definition...
./tmp/ember-l10n/messages.pot:650: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3312: duplicate message definition...
./tmp/ember-l10n/messages.pot:3043: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3411: duplicate message definition...
./tmp/ember-l10n/messages.pot:2641: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3833: duplicate message definition...
./tmp/ember-l10n/messages.pot:3308: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3936: duplicate message definition...
./tmp/ember-l10n/messages.pot:3408: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:4863: duplicate message definition...
./tmp/ember-l10n/messages.pot:3218: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:4873: duplicate message definition...
./tmp/ember-l10n/messages.pot:4007: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:6761: duplicate message definition...
./tmp/ember-l10n/messages.pot:2072: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:6842: duplicate message definition...
./tmp/ember-l10n/messages.pot:2860: ...this is the location of the first definition
msgmerge: found 10 fatal errors
ERROR: exec: ./tmp/ember-l10n/messages.pot:495: duplicate message definition...
./tmp/ember-l10n/messages.pot:312: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:740: duplicate message definition...
./tmp/ember-l10n/messages.pot:650: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3312: duplicate message definition...
./tmp/ember-l10n/messages.pot:3043: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3411: duplicate message definition...
./tmp/ember-l10n/messages.pot:2641: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3833: duplicate message definition...
./tmp/ember-l10n/messages.pot:3308: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:3936: duplicate message definition...
./tmp/ember-l10n/messages.pot:3408: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:4863: duplicate message definition...
./tmp/ember-l10n/messages.pot:3218: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:4873: duplicate message definition...
./tmp/ember-l10n/messages.pot:4007: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:6761: duplicate message definition...
./tmp/ember-l10n/messages.pot:2072: ...this is the location of the first definition
./tmp/ember-l10n/messages.pot:6842: duplicate message definition...
./tmp/ember-l10n/messages.pot:2860: ...this is the location of the first definition
msgmerge: found 10 fatal errors


Updated ./translations/messages.pot βœ”

Further, the command shows the same error in en.pot but like above command shows that the file has been updated. But no changes are made in either of the file and the tmp directory is deleted as well

Sync command misses new context keys

To be in line with ember l10n:extract, the command ember l10n:sync should consume the same keys per default: 't', 'pt:1,2c', 'n:1,2', 'pn:1,2,4c'.

Test helpers don't pass hash for placeholders

Using the test helpers doesn't pass through provided hash arguments to strfmt method, thus resulting in template markup within tests, such as {{count}} apple or {{count}}Β apples.

Allow setting of multiple json paths

This would come in handy especially for addons providing their own translations and don't make use of the auto-extraction (f.e. when not using skip-dependencies or skip-all-dependencies) within the hosting app.

Suggestion: Make jsonPath property of service an array, where the hosting app or an initializer can add new entries, which will be taken into account within _loadJSON method.

Newslines and HTML in translations

When adding newlines or HTML to my translations they seem to be ignored.
I've tried adding unescapeText=true to the helper {{t 'My \n string with <br> newlines' unescapeText=true}} but both the \n and <br> are printed out as plain text.
Trying to pass the result of t() through a helper for converting \n to <br> isn't possible either, since it is being escaped by the translation function.

Destructuring of `Ember.testing` will not work.

Ember.testing is a getter/setter in Ember, and destructuring like this will only read its value at the time the module is evaluated. In this case, Ember.testing will most likely be false when the module is evaluated, then change to true during the test. This behavior somewhat recently changed in emberjs/ember-test-helpers#227 (which is included in [email protected] / [email protected]).

I believe the fix here would be to remove the destructuring, and use Ember.testing directly inline.

const {
computed,
Service,
inject,
RSVP: { Promise },
get,
merge,
copy,
typeOf: getTypeOf,
Evented,
isNone,
Logger,
testing
} = Ember;

if (testing) {
return;
}

Remove comments from generated JSON files

The gettext-parser we use generates a nice JSON format. However, it also includes comments, which make up about half of the total JSON file. Since we don't really need this, we should probably strip this out during ember l10n:convert.

A simple regex that seems to fix this is: /"comments": \{([\s\S]*?)\},\s*/gm (replace with '').

Add fingerprinting to locale.json files

We want the locale files (e.g. en.json) to be properly cached by the browser. However, because ember-cli's fingerprinting doesn't work for this case, we need to implement this manually.

The ideal solution would be:

  • When generating a new locale.json file, generate it with a random fingerprint (e.g. en-12345.json).
  • Automatically save this fingerprint e.g. in the environment.js

E.g.:

// environment.js
var ENV = {
  // ...
  'ember-l10n': { 
    fingerprint: '12345' 
  }
}

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.