biesbjerg / ngx-translate-extract Goto Github PK
View Code? Open in Web Editor NEWExtract translatable (using ngx-translate) strings and save as a JSON or Gettext pot file
License: MIT License
Extract translatable (using ngx-translate) strings and save as a JSON or Gettext pot file
License: MIT License
When I try to extract translations which are within an element which uses a directive, the translation keys are not parsed properly.
<button [style.background]="'lime'">{{'SomeKey_NotWorking' | translate}}</button>
results in
"lime'\">{{'SomeKey_NotWorking": ""
<button>{{'SomeKey_Working' | translate}}</button>
results in
"SomeKey_Working": ""
ng2-translate-extract: 0.4.0
Let me know when you need additional information.
Philipp
When extracting strings from TypeScript files, the TranslateService.stream('key') call is ignored, TranslateService.get('key') works fine
We are using nested JSON to organize the translation keys in a better way. But ng2-translate-extract is not supporting nested JSON. Following is an example from html and nested JSON.
What I want that this tool should produce JSON like this
{
PAGES: {
SHARED: {
"MeetingNotFound": "MeetingNotFound"
}
}
Is this possible?
I have a component whose attributes must always be translated:
<form-control label="Subject" help="A short description of your issue">
I'd like a way to tell ngx-translate-extract that these two properties always contain translated texts, so it can extract them.
I know I could move translation outside the component:
<form-control label="{{'Subject' | translate}}" help="{{'A short description of your issue' | translate}}">
but the nested brackets are cumbersome to get right, and the redundancy clearly harms readability.
I am using version 0.6.0
The sorting was working at first but when the file got bigger it started moving the keys out of order.
Note: I tried both "json" and "namespaced-json"
This is what my command looks like (from package.json):
"extract-en": "ng2-translate-extract --dir ./src/app --sort --output ./src/i18n/en-US.json --format=json"
Gives the following unsorted output (I only included the beginning of the output):
{
"SYSTEM.DETAILS.LICENSES_TITLE": "",
"SYSTEM.LIST.TITLE": "",
"OPERATOR.LIST.COLUMN_EMAIL": "",
"COMMON.ERROR.FAILED_TO_LOAD_LIST": "",
"SYSTEM.DETAILS.LICENSES_COLUMN_MODULE_NAME": "",
"COMMON.ERROR.FIELD_IS_MANDATORY": "",
"INSTANCE.LIST.COLUMN_NAME": "",
"SYSTEM.DETAILS.FORM_TITLE": "",
"LICENSE.DIALOG.CHOOSE_MODULE": "",
...
Hi biesbjerg!
I'm trying to extract and save to multiple files with the following code:
"extract": "ngx-translate-extract --input ./src/app/ --output ./src/assets/i18n/{en,es,fr}.json --clean --sort --format namespaced-json"
And also tried:
"extract": "ngx-translate-extract --input ./src/app/ --output ./src/assets/i18n/en.json ./src/assets/i18n/es.json ./src/assets/i18n/fr.json --clean --sort --format namespaced-json"
But doesn't work.
With a single file like ' ./src/assets/i18n/en.json' works, but not for multiple
Any idea what it might be?
I'm using npm 3.10
Many thanks in advance!
Greetings
ng2-translate-extract can not extract the following text properly.
console.log(this.translate.instant('some_text'), this.translate.instant('some_other'));
Hi,
is it possible to output nested JSON? I use nesting like this
{
"general": {
"welcome": "Hello {{value}}",
"switch-language": "Switch language"
}
}
ng2-translate-extract outputs it flat though:
{
"general.welcome": "",
"general.switch-language": ""
}
Thanks!
Currently working on a project where we use this tool to help us extract keys in a large application and we use code styles to enforce some rules on our files. One is that we use spaces instead of tabs so it would be nice if we could pass in an option for the tool to use spaces instead of tabs.
Basically this line
return JSON.stringify(values, null, '\t');
would become something like
return JSON.stringify(values, null, this.spacer);
I'd like to extract my strings to en.json and fr.json instead of just template.json.
Do you think it could be possible to change the name of the extracted file?
The best would be to be able to extract to multiple files at the same time, but I'd be ok with just one at a time (and I could make a command on npm for each lang).
PS: I can make a PR if you want
When I run extract command I need always to manually add strings defined using instant service method since it's not auto-extracted by the tool :
Example from template:
<button [tooltip]="translate.instant('Edit')"
placement="top"
(click)="edit()" >
<i class="fa fa-pencil"></i>
</button>
Steps to reproduce:
1.0.0
)2.2.2
)import { _ } from '@biesbjerg/ngx-translate-extract';
_('Extract me');
ng serve
-> App crashes
utils.js:8 Uncaught Error: Cannot find module "."
at webpackMissingModule (utils.js:8) [<root>]
at Object.<anonymous> (utils.js:8) [<root>]
at __webpack_require__ (bootstrap e15c424…:52) [<root>]
at Object.<anonymous> (index.js:10) [<root>]
at __webpack_require__ (bootstrap e15c424…:52) [<root>]
at Object.module.exports.res (index.js:4) [<root>]
at __webpack_require__ (bootstrap e15c424…:52) [<root>]
at Object.<anonymous> (usage.js:3) [<root>]
at Object.module.exports.self (usage.js:314) [<root>]
at __webpack_require__ (bootstrap e15c424…:52) [<root>]
at Object.<anonymous> (index.js:5) [<root>]
at Object.<anonymous> (index.js:504) [<root>]
at __webpack_require__ (bootstrap e15c424…:52) [<root>]
at Object.<anonymous> (cli.js:10) [<root>]
client?42d7:98 ./~/source-map-support/source-map-support.js
Module not found: Error: Can't resolve 'module' in '/Projects/my-project/node_modules/source-map-support'
@ ./~/source-map-support/source-map-support.js 473:15-32
@ ./~/typescript/lib/typescript.js
@ ./~/@biesbjerg/ngx-translate-extract/dist/parsers/abstract-ast.parser.js
@ ./~/@biesbjerg/ngx-translate-extract/dist/index.js
@ ./src/app/app.component.ts
@ ./src/app/app.module.ts
@ ./src/main.ts
@ multi webpack-dev-server/client?http://localhost:4201 ./src/main.ts
I would very much like a feature that sorts translations in the json file by key. What do you think about a feature like this?
{ "FirstName": "名", "LastName": "姓氏"", "Address": "地址" }
would become
{ "Address": "地址", "FirstName": "名", "LastName": "姓氏"" }
the following does not get extracted correctly, surrounding html gets extracted:
{{ 'Messages will be sent to {{email}}.' | translate: {email: email} }}
{{ 'Messages will be sent to %%email%%.' | translate: {email: email} }}
This gets extracted correctly.
{{ 'Messages will be sent to email.' | translate: {email: email} }}
Also having issues with
All your known fingerprints will be supported.
'All your' and 'will be supported' get extracted as seperate keys.I am pretty sure this is a regex issue. The one used in pipe.parser.js seems to work for the first issue. So i think the issue might be in abstract-template.parser.js method _extractInlineTemplate. But i am just guessing here.
var parameterType = parameter.type.typeName;
This cannot be resolved when parameter.type is undefined. I resolved it with an "if (!parameter.type) return false;", but I'm asuming something went wrong earlier.
Output + Error + Stacktrace:
> ngx-translate-extract -i ./src/app/ -o ./src/i18n/en.json --clean --sort --format namespaced-json
Extracting strings...
- src/app/api.service.ts
**\node_modules\@biesbjerg\ngx-translate-extract\dist\parsers\service.parser.js:51
var parameterType = parameter.type.typeName;
TypeError: Cannot read property 'typeName' of undefined
at **\node_modules\@biesbjerg\ngx-translate-extract\dist\parsers\service.parser.js:51:47
at Array.find (native)
at ServiceParser._getInstancePropertyName (**\node_modules\@biesbjerg\ngx-translate-extract\dist\parsers\service.parser.js:47:49)
at ServiceParser.extract (**\node_modules\@biesbjerg\ngx-translate-extract\dist\parsers\service.parser.js:28:43)
at **\frontend\node_modules\@biesbjerg\ngx-translate-extract\dist\cli\tasks\extract.task.js:50:58
at Array.forEach (native)
at **\node_modules\@biesbjerg\ngx-translate-extract\dist\cli\tasks\extract.task.js:49:32
at Array.forEach (native)
at **\frontend\node_modules\@biesbjerg\ngx-translate-extract\dist\cli\tasks\extract.task.js:46:58
at Array.forEach (native)`
Before the crash parameter contained this:
NodeObject {
pos: 339,
end: 352,
flags: 0,
transformFlags: undefined,
parent: undefined,
kind: 145,
decorators: undefined,
modifiers:
[ TokenObject { pos: 339, end: 347, flags: 0, parent: undefined, kind: 111 },
pos: 339,
end: 347 ],
dotDotDotToken: undefined,
name: IdentifierObject { pos: 347, end: 352, flags: 0, parent: undefined, text: 'path' },
questionToken: undefined,
type: undefined,
initializer: undefined,
_children:
[ NodeObject {
pos: 339,
end: 347,
flags: 0,
transformFlags: undefined,
parent: [Circular],
kind: 295,
_children: [Object] },
IdentifierObject { pos: 347, end: 352, flags: 0, parent: undefined, text: 'path' } ] }`
Here is a link to the file it was trying to parse:
Hi,
I am new to this library (v2.2.4). Works well.
One small issue I faced:
// --- unable to extract
this.translationService.get('hello.world').subscribe(val => {
console.log(val);
});
// --- extract successful
import { _ as markI18nKey } from '@biesbjerg/ngx-translate-extract';
markI18nKey('hello.moon');
// --- run this command to extract
ngx-translate-extract --input ./src --output ./src/assets/i18n/{en,fr,es}.json --clean --sort --marker markI18nKey --format json
I am rather new to ngx-translate, so not sure if this is a bug or not. Any idea why?
--marker is Unknown option, please fix your Docs
Hello,
Thanks for the great tool, I'm missing an important use case though: how to extract arbitrary strings for translations, that does not go through the TranslateService direction but through an indirection?
I explain:
I would like to define strings to be translated, let's say in a constant file and then translate them later:
var toBeTranslated = "Hello World"; // <-- how to mark this for extraction?
// ... later on
var translated = translateService.instant(toBeTranslated); // or .get...
In other translation tools, for example Angular-gettext which I used extensively with angular 1, it is possible tu use a "dummy" noop function to mark strings for extraction (in occurence, the gettext()
function has this role).
If it's not already implemented, could you add support for this, either through a command-line option of directly included within ng2-translate
?
ServiceParser regexp extract params on same line.
Run extract
this._translateService.get('You are expected at {{time}}', {time: moment.format('H:mm')}).subscribe();
Expected:
You are expected at {{time}}
Actual result:
You are expected at {{time}}', {time: moment.format('H:mm
Any regexp experts want to help with this?
https://regex101.com/r/NeEU3q/1
tested on v2.2.2
I'm not sure if it's intended but the following was extracted for a string 'test...':
"test": {
"0": {
"0": {
"0": ""
}
}
}
Hello, it would be easier to follow what's changed in the npm release if you added a tag with the matching version number, what do you think?
Thanks for this awesome repo.
Unfortunately, I could not get it running?
> ng2-translate-extract --dir ./src/client/app/components/frontpage --output ./ --format=json
/Users/andy/workspace/HazuApp/node_modules/@biesbjerg/ng2-translate-extract/dist/utils/translation.collection.js:4
constructor(values = {}) {
^
SyntaxError: Unexpected token =
at exports.runInThisContext (vm.js:53:16)
at Module._compile (module.js:387:25)
at Object.Module._extensions..js (module.js:422:10)
at Module.load (module.js:357:32)
at Function.Module._load (module.js:314:12)
at Module.require (module.js:367:17)
at require (internal/module.js:16:19)
at Object.<anonymous> (/Users/andy/workspace/HazuApp/node_modules/@biesbjerg/ng2-translate-extract/dist/utils/extractor.js:2:34)
at Module._compile (module.js:413:34)
at Object.Module._extensions..js (module.js:422:10)
I'm using npm version is 4.0.3 and node version v5.6.0. Are there specific versions required by your script? Thanks a lot!
Newlines piped into translate
are being incorrectly escaped.
Add {{ 'Line 1\nLine2' | translate }}
to a HTML being parsed.
Run ngx-translate-extract --input ./src --output template.pot --clean --sort --format pot
msgid ""
"Line 1\\n"
"Line 2"
msgstr ""
msgid "Line 1\nLine 2"
msgstr ""
If I have a sentence for translation in html like -
"There are currently no students in this class. The good news is, adding students is really easy! Just use the options at the top." represented in multiline because of linting condition then the translation key becomes
"There are currentlyno students in this class. The good news is, adding "
"students is really easy! Just use the options at the top."
It should not break the keys unless a
is mentioned in the html.
Any work around for this issue?
Hello,
Would you please help me with this error? It happens when I mark a string for extraction. Thanks a lot.
/home/bbv/BBV/Client/node_modules/@biesbjerg/ngx-translate-extract/dist/cli/cli.d.ts (1,1): Cannot find type definition file for 'yargs'.
If you try to set the format indentation on a windows machine, the given arguments will be misunderstood. By trying the examples from documentation you'll get malformed json files.
ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation $'\t'
outputs the following content:
{
$'"COUNTER": "",
$'"ENGLISH": "",
$'"HOME": "",
$'"HOME_FEATURE_LIST_TITLE": "",
$'"HOME_ISSUES_TITLE": "",
$'"NORWEGIAN": "",
$'"SWITCH_LANGUAGE": ""
}
ngx-translate-extract -i ./src -o ./src/i18n/en.json --format-indentation ' '
outputs the following content:
{
'"COUNTER": "",
'"ENGLISH": "",
'"HOME": "",
'"HOME_FEATURE_LIST_TITLE": "",
'"HOME_ISSUES_TITLE": "",
'"NORWEGIAN": "",
'"SWITCH_LANGUAGE": ""
}
It seems, that the command line arguments will be split at each whitespace character and the indentation parameter gets the characters right before the whitespace character that should be taken for indentation (in first case $'
, in second case '
).
This happens if I add the above examples to my package.json within the scripts section. If I'm going to call your tool directly from command line
.\node_modules\.bin\ngx-translate-extract -i ./src -o ./src/i18n/en.json --clean --sort --format namespaced-json --format-indentation ' '
it works correctly.
So it seems to be more a problem of npm (I'm using 3.10.10 from node 6.10.2) and/or windows (Win10). But maybe you have an idea on how to fix it or whom to blame.
Hi,
Should I be able to output to multiple files, even when using the pot-format? Currently, when doing:
ngx-translate-extract --input ./src --output ./src/assets/i18n/{sv,nb,fi,da}.pot --clean --sort --format pot
I get one output file named {sv,nb,fi,da}.pot
.
this.translate.instant('option.0');
This line cause the extractor to fail and I list of null instead the 0
as the key
Hello,
I started using your tool, and it seems to work mostly flawless with HTML, but I don't see any strings coming from JavaScript.
I'm using it in the simple way of for example this.translate.get('Getting your location...')
where this.translate
is public translate: TranslateService
Am I missing something?
Fallbacks for ngx-translate don't consider an empty string as undefined (rightfully so, imo). I prose changing empty strings to export as null
rather than ""
.
The following template, in French, contains a backslash that should be ignored during the extraction:
[title]=" 'C\'est ok' | translate"
Actual extraction:
msgid "C\\'est ok"
Expected:
msgid "C'est ok"
I'm trying to use marker function in my code, using aliasing to avoid conflicts:
import { _ as extract } from '@biesbjerg/ngx-translate-extract';
...
But it seems that aliasing or not, Karma does not like the fact that I there's a _
function used here:
Error: Error encountered resolving symbol values statically. Calling function '_', function calls are not supported. Consider replacing the function or lambda with a reference to an exported function,
Maybe you should consider using a more explicit default marker function name, such as extract
for example? This also cause issues when using popular libraries such as lodash
or underscore
in the project.
Hello,
when I want to use AST Service Parser it looks like this:
Jablicko:frontend jenik$ ngx-translate-extract -e -f pot -o src/assets/i18n/template.pot
INFO: Extracting strings from '....'
ERROR: TypeError: Cannot read property 'text' of undefined
It would be nice to have the possibility to mark some keys to tell the script to not clean them if they are no longer found on the project.
For example:
{
"Hello": "Bonjour",
"Bye": "Au revoir",
"Eat": "Manger",
"Omelette with cheese": "Omelette au fromage" #clean_ignore
}
If I run the script, if "Omelette with cheese"
is not found on the project, it will not remove it because of the #clean_ignore
annotation.
It can be usefull for dynamic content translation.
Here's the sequence of events to simulate this bug.
# generate as json format
--clean --sort --format json --format-indentation ' '
# enter values (just edit the file with values)
# generate as namespaced-json
--clean --sort --format namespaced-json --format-indentation ' '
# observed that entered values are preserved
# generate as json
--clean --sort --format json --format-indentation ' '
# observed that entered values are gone (bug)
```
I am ok to provide a PR if you think this is a small issue and provide some pointers on where to look. :-)
Hello,
I encountered an issue while using the extraction for strings containing html, for instance :
<div translate>This is my <b>string</b> to translate</div>
I would expect translating This is my <b>string</b> to translate
and just put the tags back in the translations as well, which is what I used to do before switching to Angular 2.
But it now gives me 2 strings : This is my
and to translate
, which is not really convenient when translating sentences.
Is there another solution for doing something like this?
Thanks.
I think that how browser use the pattern en-US / pt-BR instead en / br, should be easier use so...
Extract and save to multiple files Dose not work
ngx-translate-extract -i ./src -o ./src/i18n/{da,en,fr}.json
or
ngx-translate-extract -i ./src -o ./src/i18n/da.json ./src/i18n/en.json ./src/i18n/fr.json
Fail extraction from constructor if object not using this
"@ngx-translate/core": "^6.0.1",
"@ngx-translate/http-loader": "0.0.3",
"@biesbjerg/ngx-translate-extract": "^2.3.1",
On example below extraction for key 'test1' not working
import {TranslateService} from '@ngx-translate/core';
constructor(public translate: TranslateService) {
// Translation working but Extraction Fail
translate.get('test1').subscribe(value => {
console.log(value);
});
// extraction working fine
this.translate.get('test2').subscribe(value => {
console.log(value);
});
}
A really helpful feature of gettext is seeing exactly where translations are used.
Thank you for a nice package 😃 👍 Certainly saved us a ton of time!
When parsing this HTML (source code):
<input class="form-control material-input" id="phone" name="phone" type="text" (focus)="serverValidationErrors.phone = ''" placeholder="{{'user.settings.form.phone.placeholder' | translate}}" [formControl]="settingsForm.controls['phone']">
this JSON gets returned:
{
"'\" placeholder=\"{{'user.settings.form.phone.placeholder": "",
}
node
version: 6.7.0
ng2-translate-extract
version: 0.6.0
npm
version: 3.10.8
Reproduce:
$ git clone [email protected]/justarrived/just-match-web.git
$ cd just-match-web
$ npm run extract-translations
$ cat used_i18n.json # File with invalid keys
Maybe this is whats need to be updated, https://github.com/biesbjerg/ng2-translate-extract/blob/master/src/parsers/directive.parser.ts#L51-L53.
I'm sorry that I can't provide any more details than the above. Please let me know if there are any else I can do.
Thanks!
Hi, is it already possible to have some kind of default value for all extracted keys? Some kind of placeholder so that I spot values in the template that are missing.
The service parser ends up parsing:
this.translate.get('Welcome to %s').map((translation: string) => {return translation.replace('%s', this.title); });
with a match on 'Welcome to %s').map((translation: string) => {return translation.replace('%s'
when everything the above statement is written as one line.
I update 0.5.1 to 0.6.0 and Type Script files Extracton doesn't work
dose not extract:
translate.get('blah1').
translate.instant('blah2').
The currently published package v2.2.2 contains the old regex in pipe.parser.js:
var regExp = /(['"`])([^>\1\r\n]*?)\1\s*\|\s*translate/g;
It should be var regExp = /(['"`])((?:(?!\1).|\\\1)+)\1\s*\|\s*translate/g;
Hello,
Do you have plans to implement java .properties
files as a format? There are some nice tools (like IntelliJ IDEA's properties bundle editing) for editing properties file for i18n.
I wouldn't mind implementing it myself, though I'm not familiar enough yet with npm to set it all up. I would just fork in github, but then what?
Regards
Wouter
I'd like to use the following code to add multiple paragraphs to a page:
<p *ngFor="let line of ('multi-paragraph' | translate)">
{{line}}
</p>
ngx-translate-extract finds the 'multi-paragraph' and adds it to the json files. So far it's ok.
I now edit the file using an array:
{
"multi-paragraph": [
"paragraph1",
"paragraph2",
"paragraph3"
]
}
The app works as expected and displays all paragraphs...
Running npm extract
changes the content of the json files to
{
"multi-paragraph": {
"0": "paragraph1",
"1": "paragraph2",
"2": "paragraph3"
}
}
The result is a json object which can't be processed by ngFor.
It would really be great if ngx-translate-extract would not change the arrays into objects...
Hi,
I'm currently trying out ngx-translate-extract by doing:
ngx-translate-extract --input ./src --output ./src/assets/i18n/se.pot --clean --sort --format pot
If I first have three strings in a .ts-file, and run the extractor, I see the three strings in my se.pot-file. So it all seems to be working fine. If I then remove one of the strings from my application and run the extractor again, is it supposed to remove the now not used string from the .pot-file, since it is no longer in use?
I got that impression from reading the documentation about --clean
:
Remove obsolete strings when merging
Thanks!
If a file contains multiple exports, only the strings in the first one get extracted.
Example:
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
export class Stuff {
thing: string;
constructor(thing: string) {
this.thing = thing;
}
}
@Injectable()
export class AuthService {
constructor(public translate: TranslateService) {
console.log(this.translate.instant("Hello!"));
}
}
Hello!
Doesn't get extracted.
After removing the Stuff class it will.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.