Giter VIP home page Giter VIP logo

xgettext's Introduction

xgettext-template Node.js CI

Extracts translatable strings from source. Identical to xgettext(1) but for template languages.

Template language support

React's JSX and Pug are todos (PRs are much appreciated).

Installation

$ npm install -g xgettext-template

Usage

$ xgettext-template [OPTION] [INPUTFILE]...

Options

Input file location:
  -f, --files-from  get list of input files from FILE
  -D, --directory   add DIRECTORY to list for input files search[default: ["."]]

Output file location:
  -o, --output  write output to specified file          [default: "messages.po"]

Choice of input file language:
  -L, --language  recognise the specified language
                  (Handlebars, Swig, Volt, EJS, Nunjucks)

Input file interpretation:
  --from-code  encoding of input files                        [default: "ascii"]

Operation mode:
  -j, --join-existing  join messages with existing file         [default: false]

Language specific options:
  -k, --keyword  look for WORD as an additional keyword

Output details:
  --force-po     write PO file even if empty                    [default: false]
  --no-location  do not write '#: filename:line' lines          [default: false]
  -s, --sort-output  generate sorted output                     [default: false]

Informative output:
  -h, --help     display this help and exit                            [boolean]
  -V, --version  output version information and exit                   [boolean]

More information about each option can be found in the xgettext manual.

In Poedit

Go to File - Preferences... in Poedit and add a new parser in the Parsers tab:

Poedit parser configuration

Please note that in this Windows example you have to use xgettext-template.cmd. The .cmd extension should not be there on *nix platforms.

General workflow

In the following Handlebars example translatable content is passed to helpers (_ and ngettext):

<button>{{_ "Sign in"}}</button>

<p>{{count}} {{ngettext "country" "countries" count}}</p>

With Handlebars, this requires helpers being registered:

Handlebars.registerHelper('_', function(msgid) {
  return i18n.gettext(msgid);
});

Handlebars.registerHelper('ngettext', function(msgid, plural, count) {
  return i18n.ngettext(msgid, plural, count);
});

What this i18n object refers to is up to you. Some (client/server) options are:

xgettext-template parses the strings above out of your templates into gettext's PO files. These PO files are then translated and compiled to binary MO files using applications like Poedit. The MO files are passed as input the i18n library (above).

Development

  • Clone repository and run npm install.
  • Have your editor run eslint or run npm run lint to lint.
  • Run npm test to run tests.

Note

xgettext-template initial development was founded by Dijiwan.

xgettext's People

Contributors

dependabot[bot] avatar eldarc avatar gmarty avatar gregmac avatar hermanschaaf avatar olivierkamers avatar sebastianhoitz avatar smhg avatar tkallevik avatar x-cray avatar

Stargazers

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

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

xgettext's Issues

use xgettext input and output parameters

This would break things.

I think it is nice to be consistent with xgettext(1). The goal of this would be to use handlebars-xgettext inside poEdit with the same parameters as existing xgettext(1).

Since this breaks things, this will mean a 1.0.0 version.
From the xgetext(1) manpage:

xgettext [OPTION] [INPUTFILE]...

INPUTFILE ...
input files
-D, --directory=DIRECTORY
add DIRECTORY to list for input files search

-o, --output=FILE
write output to specified file

--force-po
write PO file even if empty

Not working through Poedit

Hi there,

Thanks for your work!

I'm facing a problem, maybe related to my environment, but I perfectly run the command in my terminal (and it is working) but it throws me an error when ran through Poedit :( Did you already experienced this problem?

I'm running Poedit 1.6.10 (2957)

And my error is :

Unable to run the program : xgettext-template --force-po -o "/var/folders/wt/5t32_hfj4f3fnsgc5q8svcsw0000gp/T/poeditZGIuaE/0extracted.pot" -k "_t" -k "_n:1,2" "../app/templates/application.hbs" "../app/templates/catch-all.hbs" "../app/templates/components/content-editable.hbs" "../app/templates/components/editable-item.hbs" "../app/templates/components/google-connect-button.hbs" "../app/templates/components/sync-button.hbs" "../app/templates/components/ui-button.hbs" "../app/templates/components/ui-icon.hbs" "../app/templates/components/ui-meter.hbs" "../app/templates/components/vertical-navigation.hbs" "../app/templates/flash.hbs" "../app/templates/google-connect.hbs" "../app/templates/index.hbs" "../app/templates/loading.hbs" "../app/templates/login.hbs" "../app/templates/meeting/agenda/notes.hbs"

My question is: is it a permission-related problem with my global install of xgettext-template or is it a problem with Poedit?

Thanks

Remove parser dependencies

It sounds like a good idea to no longer list parsers as dependencies as it lowers maintenance updates.

Requirements:

  • Take a look at approach of eslint/babel/...
  • Less focus on Poedit in Readme, more on npm/gulp/grunt/... integration.
  • Validate parser at runtime.

use library for po creation

issue for own reference

If possible, it sounds sane to use an existing library for PO creation.

I have compared the scarce GitHub results and node-gettext seems to be a good option at first glance.

Add charset to Content-Type header of PO output

I'm now having issue with non-ascii chars.

I have JS files parsed by poedit normally having äö chars and they work.

But as soon as I add "äö" chars in EJS files, and try to use Update from Sources it won't work:

10.6.2016 7.32.23: C:\...\msgcat.exe: input file 'C:\...\POEDIT~1\poe89D9.tmp\13extracted.pot' doesn't contain a header entry with a charset specification
10.6.2016 7.32.23: Failed command: msgcat --force-po -o "C:\...\POEDIT~1\poe89D9.tmp\15merged.pot"  "C:\...\POEDIT~1\poe89D9.tmp\13extracted.pot" "C:\...\POEDIT~1\poe89D9.tmp\14extracted.pot"
10.6.2016 7.32.23: Failed to merge gettext catalogues.

I've checked the EJS template is UTF-8, the Catalogue Properties says UTF-8 and my settings are following

image

Having --force-po in there also doesn't seem to make a difference. If I remove ‪--from-code=%c it works but the äö characters are not recgonized correctly.

New release is out

@smhg A lot of time has passed since I worked on improvements. And the dependency update for Nunjucks was getting really required. So I decided to make a release. It does seem stable, but please if you have any suspicions that something could be broken let me know.

Orphaned messages when using `--join-existing`

Suppose source files contain following two messages:
_('First message')
_('Second message')

Those will be added to the .po file. Translators can translate them and translations will be saved and not overwritten when using --join-existing.

However, if the developer changed a message, for example _('Second message') to _('Third message') and _('Second message') has now 0 occurrences in all source files, it should be removed from the .po file.

Currently, the deepMerge method merges all messages from the existing .po file. Before doing the merge, orphaned messages should be marked and ignored when merging or a direct check should be performed while merging.

Plural form extraction is not working for me

Here is the handlebar markup.

singular: {{_t "hb_msg"}}
<br>
plural: {{_n "hb_msg" "hb_msgs" n}}

I have POedit setup the same as in the documentation.

Here are the keywords:

_t
_n:1,2

Your plural example is strange to me since I've never seen a default _ function that is setup as plural.

<!-- and a simple plural example: -->
<p>{{count}} {{_ "country" "countries" count}}</p>

It just doesn't seem to figure out the plural form but it can figure out the singular form.

Add Parser to module.export

There should be public method to parse already loaded templates.

At the moment one can parse templates with handlebars-xgettext.parse(files, options, callback) but it reads a file from the fs. In the case the content of the file is already loaded there is no way to parse it using public API.

xgettext clone vs parsers

@gmarty, I need your help.

I would like to turn this project into a general xgettext clone (in JavaScript). For the most part, it is already (support for most used options is available).

The parser, the only part which is specific to Handlebars, would be split off into a separate project.
Other projects could then take on other formats (Jade, EJS,...) without the need to re-create the xgettext clone. Each will be triggered by the -l|--language parameter, just like the "real" xgettext.
These have been requested in previous issues and also the stand-alone use of the parser would open up new possibilities (e.g. gulp/stream integration).

If you agree, I would suggest to rename this repo to xgettext.
As for the npm name, I will look at the options (xgettext will create conflicts and xgettext-js is in use) and the best way to make the transition as smooth as possible.

Thanks!

Make `--files-from` work like in gettext

Currently the file list supplied via --files-from is split at each line feed \n:

xgettext/index.js

Lines 195 to 201 in 2a23cf5

if (options['files-from']) {
input = fs.readFileSync(options['files-from'], options['from-code'])
.split('\n')
.filter(function (line) {
return line.trim().length > 0;
});
}

This leads to problems with lists generated by programs that produce "Windows linebreaks" (CR LF, \r\n).

This is why I suggest changing the current behaviour and making line splitting work like in GNU gettext: https://git.savannah.gnu.org/cgit/gettext.git/tree/gettext-tools/src/file-list.c?id=b26729c67cffb2403d8a20b44606f5a08cb901b5#n68

What is done is basically this:

  1. Get next line from the file.
  2. Remove trailing new line \n
  3. Remove any of: Tab \t, space (I'm not sure this is actually a good idea) and \r from the end of the string.

add project to Travis

It would be nice to have the project in Travis.
I think only you (@gmarty) can do this?

Markdown to add at top of Readme.md for the badge:

[![build status](https://secure.travis-ci.org/gmarty/handlebars-xgettext.png)](http://travis-ci.org/gmarty/handlebars-xgettext)

No idea if the tests are Travis-ready, but I will change the setup accordingly afterwards.

Default keyword spec not parser specific.

When there are no custom keywords, only _, gettext, ngettext are parsed.

Wouldn't it be better to load default parser specific keywordSpec?

So, something like this:

In index.js:
spec = options.keyword.length > 0 ? Keywordspec(options.keyword) : [],

In bin/xgettext-template
'keyword': [],

Additional options

It seems like a good idea to have this discussion here as it can be useful to others.

@eldarc wrote:

I also wanted to ask you about some feature additions for xgettext-template. I would love to have the cleanup of strings that are not anymore in the source files. If I were to code this as a new parameter (for example --cleanup) would it have a chance to be merged?

I would love this feature because I'm using this with Gulp. I have it setup for live watching. Every time there is a change in the template files, gulp will automatically call xgettext-template and extract strings. It would be great for the developer not to worry about temporary strings in the .po files. When the extraction is done, a new gulp task will use all those strings and translations to render static pages for every language.

Also, is it possible to add a parameter --write-sync to make sure files are written synchronously? It's a bit of a problem to control it in gulp. It moves on to the next task, and that task could require files which should be written in the previous task.

Also, it would be great to make an export to be used with gulp (or any other node app). For example, a function which will take an object with options and run xgettext-template. This could be also explained in the README.

Does anyone want to work on getting gettext-volt to understand contexts?

Hello I am the creator and maintainer of gettext-volt. At the time that I created gettext-volt the umbrella xgettext-template project didn't support "contexts" and so I didn't add it. Admittedly, I don't exactly understand what they are used for but others have asked for them and apparently they must be useful or necessary.

So if anyone would like to help out we have been accumulating some donation funds over at https://opencollective.com/phalcon and at the moment we have thousands of dollars its going up at a consistent rate. I don't control those funds but I created the original Patreon effort and I can help to push for someone getting paid to improve this, if money is a motivating factor. Just submit the pay funding request and we can take it from there. Its not necessary to even run Phalcon or Volt but just to parse out the templates and there are already some tests there.

Thanks.

Add support for -j (--join-existing) flag

When you run the command, the output replace the original .po contents.
An update would be must appreciated.
For example, basic use-case would be added a new template with new words to translate.
Then you run the command but all the translations already done before are erased in the new .po generated.

Change GitHub description

@gmarty, could you please change the repo's description to:
Extracts translatable strings from source. Identical to xgettext but for template languages.

It's no longer Handlebars-only.

Thanks!

[NFR] Swig template parser

Here is my plea.

I'm making a open source framework to merge Phalcon PHP and Nodejs Webpack tech. Its working out pretty well but I'd much prefer to use Swig templates to match the Volt templates on the server but I decided to use Handlebars one because your xgettext parser was the only functioning thing that I found anywhere - for anything actually. An island of sanity if you will.

If adding this is just some simple thing for you guys then feel free to rock the code.


I need a template parser for yanking out gettext strings from both Volt and Swig [Django family] templates.

In my Phalcon based Webird system I'm using Volt for server templates and Handlebars for front templates. The reason that I'm using Handlebars templates is that it is very difficult to find an xgettext template parser that is capable of pulling out strings in plural form and the Handlebars ecosystem is more mature in this way.

So I think that it would be amazing to be able to write templates in the same syntax for both the server and front end and Swig is much more modern than Handlebars in regards to its packaging.

Here is a good starting point if someone would like to do it with nodejs;

The generalized wrapper: xgettext-template

The Handlebars implementation: xgettext-handlebars

So you can see that it is very little code in the Handlebars wrapper since the heavy liftiing is being done by the parser. I'd do it myself but its not my forte.

Well my head is pretty full with this project and I can't write all of the tools myself. My idea about this is to combine the superior Nodejs (with webpack) front end environment with the superior Phalcon back end environment. The localization strings are already well shared between the browser and server and the idea is that you can create tech with PHP and JS and have it integrate well. Perhaps you would want to use Volt views for a more Admin type interface to save R&D time and your app uses some fancy JS tech that takes 20x longer to develop. So then the templates would be the same and I'm trying to standardize constants and helpers in as much as possible so that they are mostly compatible between both environments.

Additionally, one kind of current bummer is that the Volt templates must be compiled into PHP before the strings can be extracted with xgettext. Its not terrible, but could be better.

So that is my plan and if you are capable of writing a Swig/Volt xgettext implementation in less time than it takes to read my long (mostly irrelevant) words then please get on top of that.

Did't work with Handlebars

Hi,

I don't know where the problem, at this package or at the https://github.com/smhg/gettext-handlebars, but after update at 3.0 version working with .hbs files I see nothing at output

root@6ece96c0ff1c:/app# npm list -g xgettext-template
npm info it worked if it ends with ok
npm info using [email protected]
npm info using [email protected]
/usr/local/lib
└── [email protected] 

npm info ok 
root@6ece96c0ff1c:/app# xgettext-template -k t client-pos/pos_app/modules/layout/templates/layout.hbs 
root@6ece96c0ff1c:/app# npm i -g [email protected] >/dev/null 2>/dev/null 
root@6ece96c0ff1c:/app# xgettext-template -k t client-pos/pos_app/modules/layout/templates/layout.hbs 
msgid ""
msgstr "Content-Type: text/plain; charset=ascii\n"

#: client-pos/pos_app/modules/layout/templates/layout.hbs:19
msgid "POS"
msgstr ""

#: client-pos/pos_app/modules/layout/templates/layout.hbs:26
msgid "Salon desk"
msgstr ""

#: client-pos/pos_app/modules/layout/templates/layout.hbs:33
msgid "Salon page"
msgstr ""

#: client-pos/pos_app/modules/layout/templates/layout.hbs:71
msgid "Settings"
msgstr "" 

Understanding the directory option

In version 2.6.1 the following command worked just fine. It found all the files inside the folder templates and its subfolders. Now we are just getting 'no input file given'. What are we doing wrong.

I see that version 3 introduced breaking changes, but I am not sure how to use the new options.

Command

xgettext-template --force-po --directory templates -L Handlebars --output i18n/handlebars.pot

Output:

xgettext-template: no input file given

Try 'xgettext-template --help' for more information.

using {{n_ "text" "texts" count}} doesn't extract the data

Hey, I've been doing experiments and trying the plural form of words. I'm having difficulties to extract text using the n_ shorthand suggested in the gettext-handlebars while ngettext works as expected.

Result from ngettext
screen shot 2016-07-13 at 10 59 32 am

On a side note, would it be possible to run the xgettext-template cmd using different helpers name? for example, I would like to use {{l10n "text"}} instead of {{_ "text"}}?

Thanks.

Additional maintainer

@gmarty, would you be willing to add @eldarc as a maintainer both here and npm?
He made quite a few contributions and my lack of time is currently keeping him from publishing those.

Thanks!

I've forked and published some competing and complementary packages

github

npm

  • xgettext-template-dschissler [Use github for all]

The npm package xgettext-template-dschissler links to the github commits for the gettext-volt and gettext-swig packages.

I'll admit that my gettext-volt regexs are not super great but they do handle a variety of Volt uses that the xgettext-swig one doesn't consider. I forked these since these uses are not valid for Swig and Nunjuck.

Here is my test Volt template to demonstrate the different types of uses. My code is working against my larger code base.

{{ t('Single Quote.')}}
{{t("Double Quote.") }}

{{n("Singular.", "Plural", n) }}

{{ link_to('features/angular', this.translate.gettext('Angular'), 'class':'btn btn-primary') }}

{{ submit_button(t('Change Password'), "class": "btn btn-primary") }}

{{ link_to('signin', t('Signin')) }}

{{ link_to("admin/users/create", "<i class='glyphicon glyphicon-plus-sign'></i> " ~ t('Create User'), "class": "btn btn-primary pull-right") }}

Duplicate entries when using contexts.

If contexts are used for messages, and at the same time the --join-existing parameter is used, duplicate entries will be added to the .po file.

This happens when saving to an already existing .po file.

How to parse multiple files?

Hi

Thanks for this tool! I'm trying to get it to parse all of my files. I can't get it to work with poedit but I'd prefer to use it from the cli anyway. I am able to parse one file like so:

xgettext-template -o locale/en/LC_MESSAGES/test.po -L Vue -D resources/js components/ProjectLookup.vue

But how can I parse the entire directory? Is that left to poedit?

Thanks.

Ignore additional parameters

Modify pattern to ignore additional parameter:

Example:

<tag id='test' placeholder='{{_ "Hello World %s" param1="bla"}}'></tag>

At the moment handlbars-xgettext ignore the complete line because of param1="bla"

I change parser.js pattern:

// old
this.pattern = new RegExp('\\{\\{(?:' + keywords.join('|') + ') "((?:\\\\.|[^"\\\\])*)" ?\\}\\}', 'gm');
// new
this.pattern = new RegExp('\\{\\{(?:' + keywords.join('|') + ') "((?:\\\\.|[^"\\\\])*)".*?\\}\\}', 'gm');
                                                                                       ++

status check

I would just like to check if you are interested in extending this?
Of course I want to offer to try to contribute.
If you have completely abandoned this component for some reason however it could prevent some wasted time ;)

New method pgettext() not recognizing by Poedit

I've implemented method pgettext() in my gettext adapter to handle context and I would like to Poedit recognize pgettext() in .volt files. I've added this keyword in Catalogoue->Properties->Keywords, it works for *.php file only, it doesn't work for *.volt.

Should I add something extra to extractor's settings or somewhere else?

Support single quoted msg IDs

Currently it appears that only hbs templates of the form {{_ "foo"}} are recognized. It should also recognize {{_ 'foo'}} (single quotes).

Functions starting with "$" are not accepted

pcardune/handlebars-loader#9

I'm having an issue with the combination of this package and another. In the webpack handlebars-loader package the helper functions are prefixed with $ but handlebars-xgettext does not seem to recognize functions that start with this character.

I'd prefer that the other project changes this since it doesn't make a lot of sense for other reasons but also I think that this code here should be able to parse it unless it is impossible or a really bad idea for some reason.

Unable to execute handlebars-xgettext from Poedit

On Mac OSX 10.9 / Poedit v1.5.7, I installed handlebars-xgetttext globally via npm and configured the parser in Poedit as instructed in the readme, however when I run an update on my catalog, I get the following error:

20:43:32: Cannot execute program: handlebars-xgettext --force-po -o "/var/folders/kr/t4b6rm9x14b_qccxmvklplc80000gn/T/poeditzpgIds/5extracted.pot" --from-code=UTF-8 -k_ -kgettext -kgettext_noop "client/templates/application.hbs"
20:43:32: Entries in the catalog are probably incorrect.
20:43:32: Updating the catalog failed. Click on 'Details >>' for details."

Attached is a screenshot of my parser settings for handlebars.
screen shot 2013-11-24 at 8 50 18 pm

And the contents of the template file (it just a test file) that is listed in the error message is:

<h1>{{someText}}</h1>
<button class="btn btn-primary">{{_ 'Save'}}</button>
<button class="btn btn-danger">{{_ 'Delete'}}</button>
<button class="btn btn-default">{{_ 'Cancel'}}</button>
{{outlet}}

Any ideas on what would be causing this error?

handle ngettext

ngettext formatted strings:

{{_ "singular" "plural" count}}

Any pull requests are greatly appreciated!

[Bug] Plural forms is broken for Russian

I see that English plural form is working correctly (and probably other languages with two forms) but Russian has three forms and it doesn't work correctly.

I'd imagine that this is something that you could easily fix with just several lines of code.

Error: Lexical error on line 1. Unrecognized text.

Working on Mac when creating folders it also creates a bunch of extra invisible files such as .DS_Store, these files then gets included by the xgettext package and obviously throws an error because they are invalid handlebars files.

Could the -D parameter references and parse only .hbs or .handlebars files?

Had to clear extra files using the commands described inside mikeal/tako#4 but then as soon as something is modified, the file gets created again

// Of course create an extention-language mapping array for the other supported languages: Swig, Volt and EJS
if (options.directory) {
  readdirp({root: options.directory, fileFilter: ['*.hbs', '*.handlebars']}, function(err, res) {
    if (err) {
      throw err;
    }

    parseFiles(res.files.map(function (file) {
      return file.fullPath;
    }), output);
  });
} else {

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.