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

Overview

xgettext-template 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.

Comments
  • Unable to execute handlebars-xgettext from Poedit

    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?

    opened by billdami 28
  • Add Parser to module.export

    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.

    enhancement 
    opened by JustBlackBird 13
  • [NFR] Swig template parser

    [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.

    opened by dschissler 12
  • New method pgettext() not recognizing by Poedit

    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?

    question 
    opened by Zaszczyk 10
  • Ignore additional parameters

    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');
                                                                                           ++
    
    question 
    opened by rottmann 9
  • Not working through Poedit

    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

    opened by guillaumepotier 8
  • Error: Lexical error on line 1. Unrecognized text.

    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 https://github.com/mikeal/tako/issues/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 {
    
    question 
    opened by tombertrand 7
  • I've forked and published some competing and complementary packages

    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") }}
    
    
    question 
    opened by dschissler 7
  • Plural form extraction is not working for me

    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.

    bug duplicate 
    opened by dschissler 7
  • Adding support for CLI flags and a new option

    Adding support for CLI flags and a new option

    I need to change the prefix for the tabs on the fly to use it on a slightly different situation (parsing some metadata files), and I went ahead and added the CLI flag support that was marked as a todo using optimist. It's working perfectly generating code both from templates and metadata files into the same .po file.

    opened by trodrigues 7
  • status check

    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 ;)

    opened by smhg 6
  • Make `--files-from` work like in gettext

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

    Currently the file list supplied via --files-from is split at each line feed \n: https://github.com/gmarty/xgettext/blob/2a23cf592728bf98acda2b53f0ad1b01eae3b735/index.js#L195-L201

    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.
    bug 
    opened by sareyko 2
  • Does anyone want to work on getting gettext-volt to understand contexts?

    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.

    opened by dschissler 2
  • Remove parser dependencies

    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.
    enhancement help wanted 
    opened by smhg 0
  • Additional options

    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.

    question 
    opened by smhg 2
Releases(v4.1.0)
Owner
Guillaume C. Marty
Front-end lover, JavaScript activist, HTML5 enthusiast @twitter, ex @mozilla.
Guillaume C. Marty
List of 77 languages for Laravel Framework 4, 5, 6, 7 and 8, Laravel Jetstream , Laravel Fortify, Laravel Cashier and Laravel Nova.

Laravel Lang In this repository, you can find the lang files for the Laravel Framework 4/5/6/7/8, Laravel Jetstream , Laravel Fortify, Laravel Cashier

Laravel Lang 6.9k Dec 29, 2022
🗓 A library to help you work with dates in multiple languages, based on Carbon.

Date This date library extends Carbon with multi-language support. Methods such as format, diffForHumans, parse, createFromFormat and the new timespan

Jens Segers 1.8k Dec 30, 2022
75 languages support for Laravel 5 application based on Laravel-Lang/lang.

Laravel-lang 75 languages support for Laravel 5 application based on Laravel-Lang/lang. Features Laravel 5+ && Lumen support. Translations Publisher.

安正超 1.3k Jan 4, 2023
FBT - a internationalization framework for PHP designed to be not just powerful and flexible, but also simple and intuitive

FBT is an internationalization framework for PHP designed to be not just powerful and flexible, but also simple and intuitive. It helps with the follo

Richard Dobroň 4 Dec 23, 2022
ATOMASTIC 14 Mar 12, 2022
🌐 A minimalist languages library that made plugins support multiple languages.

libLanguages · libLanguages is a PocketMine-MP library for making plugins support multiple languages. Easy To Learn: Just declare it in onEnable() fun

thebigcrafter 1 May 1, 2022
Making multiple identical function calls has the same effect as making a single function call.

Making multiple identical function calls has the same effect as making a single function call.

李铭昕 4 Oct 16, 2021
Extracts information about web pages, like youtube videos, twitter statuses or blog articles.

Essence is a simple PHP library to extract media information from websites, like youtube videos, twitter statuses or blog articles. If you were alread

Essence 765 Dec 30, 2022
PropertyInfo extracts information about PHP class' properties using metadata of popular sources.

PropertyInfo Component The PropertyInfo component extracts information about PHP class' properties using metadata of popular sources. Resources Docume

Symfony 1.9k Jan 5, 2023
Small tool that extracts witness data from Helium miner logs.

Helium Miner Logs Analyzer Small tool that extracts witness data from Helium miner logs. It currently works for the Pisces 100 and miner version miner

Iñigo Flores 42 Dec 11, 2022
Doctrine2 behavioral extensions, Translatable, Sluggable, Tree-NestedSet, Timestampable, Loggable, Sortable

Doctrine Behavioral Extensions This package contains extensions for Doctrine ORM and MongoDB ODM that offer new functionality or tools to use Doctrine

Doctrine Extensions 3.8k Jan 5, 2023
Doctrine2 behavioral extensions, Translatable, Sluggable, Tree-NestedSet, Timestampable, Loggable, Sortable

Doctrine Behavioral Extensions This package contains extensions for Doctrine ORM and MongoDB ODM that offer new functionality or tools to use Doctrine

Doctrine Extensions 3.8k Jan 5, 2023
Making Eloquent models translatable

A trait to make Eloquent models translatable This package contains a trait to make Eloquent models translatable. Translations are stored as json. Ther

Spatie 1.9k Jan 7, 2023
This module integrates Silverstripe CMS with Google Translate API and then allows content editors to use automatic translation for every translatable field.

Autotranslate This module integrates Silverstripe CMS with Google Translate API and then allows content editors to use automatic translation for every

null 4 Jan 3, 2022
Blade Snip allows you to use parts of a blade template multiple times. Basically partials, but inline.

Blade Snip Blade Snip allows you to use parts of a blade template multiple times. Basically partials, but inline: <div class="products"> @snip('pr

Jack Sleight 18 Dec 4, 2022
PHP Template Attribute Language — template engine for XSS-proof well-formed XHTML and HTML5 pages

PHPTAL - Template Attribute Language for PHP Requirements If you want to use the builtin internationalisation system (I18N), the php-gettext extension

PHPTAL 175 Dec 13, 2022
Is an Extension of Laravel View Class which compiles String Template on the fly. It automatically detects changes on your string template and recompiles it if needed.

Laravel-fly-view Is an Extension of Laravel View Class which compiles String Template on the fly. It automatically detects changes on your string temp

John Turingan 16 Jul 17, 2022
PaaS template based on production template using platform.sh

Shopware for Platform.sh This template builds Shopware on Platform.sh using Composer. To get started on Platform.sh, please visit https://docs.platfor

Shopware 9 Oct 12, 2022
Textpattern-plugin-template - A template for building plugins for Textpattern CMS.

Plugin template for Textpattern CMS Developer documentation Refer to the Textpattern plugin development documentation, and notably the Plugin template

Textpattern CMS 17 Apr 17, 2022