cedaro / grunt-wp-i18n

Internationalize WordPress themes and plugins with Grunt.
MIT License
160 stars 25 forks source link

keyword "msgctxt" unknown #51

Closed vpratfr closed 9 years ago

vpratfr commented 9 years ago

After running the makepot task, I get the following errors:

(null):D:\Dev\wordpress\bxslider-integration\languages\bxsg.pot:88: keyword "msgctxt" unknown
[...]
(null): found 6 fatal errors

Those are my options for the task:

exclude: [
    "node_modules/.*",
    "libs/.*",
    "grunt/.*",
    "assets/.*"
],
include: [
    "bxslider-integration.php",
    "src/php/.*"
],

And these are the lines I think are guilty in the generated POT (only an exerpt, if needed I can paste all of them too):

#: node_modules/grunt-checktextdomain/test/expected/incorrect-domain-autocorrect.php:4
[...]
#: node_modules/grunt-checktextdomain/test/fixtures/variable-domain-autocorrect.php:17
msgctxt "verb"
msgid "Post"
msgstr ""

I have the latest i18n tools from WP's SVN, also installed the latest GNU Gettext utils for Windows.

I even wrote a function to get rid of them but that does not seem to remove them before writing to the POT:

processPot: function (pot) {
    for (var translation in pot.translations['']) {
        var tr = pot.translations[''][translation];

        if ("" == translation.trim()) {
            grunt.log.writeln("Removed empty string");
            delete pot.translations[''][translation];
            continue;
        }

        if (( 'undefined' !== typeof tr.comments.reference )
            && (tr.comments.reference.indexOf("node_modules") >= 0)) {
            grunt.log.writeln("Removed node_modules string: " + translation);
            delete pot.translations[''][translation];
            continue;
        }
    }
    return pot;
},
vpratfr commented 9 years ago

So basically this asks 3 questions (for potential bugs):

bradyvercher commented 9 years ago

Hi @vpratfr, you wouldn't happen to be using the i18nToolsPath to specify a custom path for the default i18n tools, would you? If so, remove that option and give it another shot.

This module bundles a forked version of the tools, which allows for the exclude option to be accepted, among a few other things, so all the features aren't available using the default tools.

vpratfr commented 9 years ago

That worked. You should make it clear in the docs that it is optionnal and potentially harmful to specify a custom path to i18nTools. Thanks a lot for that tool !

tlartaud commented 9 years ago

@vpratfr @bradyvercher

Hi, This should be re-opened.

I keep getting the keyword "msgctxt" unknown. Also had a merge ERROR thrown before that. The headers are not generated correctly. See below the only configuration that work for me.

module.exports = function (grunt, options) {

    var path = require('path');

    var poInclude = [
        '/*.php',
        path.join(options.vars.paths.app, ".*").replace("\\", "/")
    ];

    var poExclude = [
        path.join(options.vars.paths.app, "config/example/*.php").replace("\\", "/"),
        path.join(options.vars.paths.nodes, ".*").replace("\\", "/"),
        path.join(options.vars.paths.vendor, ".*").replace("\\", "/"),
        path.join(options.vars.paths.tools, ".*").replace("\\", "/"),
        path.join(options.vars.paths.assets, ".*").replace("\\", "/")
    ];

    var processPot = function (pot) {
        pot.headers["report-msgid-bugs-to"] = options.pkg.bugs.url + "\n";
        pot.headers["last-translator"] = options.pkg.author.name + " <" + options.pkg.author.email + ">\n";
        pot.headers["language-team"] = options.pkg.author.url + "\n";
        pot.headers["language"] = "en_US";
        pot.headers["X-Poedit-WPHeader"] = "style.css";
        pot.headers['x-poedit-keywordslist'] = [ '__', '_e', '_n:1,2', '_x:1,2c', '_ex:1,2c', '_nx:4c,1,2', 'esc_attr__', 'esc_attr_e', 'esc_attr_x:1,2c', 'esc_html__', 'esc_html_e', 'esc_html_x:1,2c', '_n_noop:1,2', '_nx_noop:3c,1,2', '__ngettext_noop:1,2'].join(';') + "\n";

        for (var i = 0; i < poInclude.length; i++) {
            pot.headers['X-Poedit-SearchPath-' + i] = poInclude[i] + "\n";
        }

        for (var j = 0; j < poExclude.length; j++) {
            pot.headers['X-Poedit-SearchPathExcluded-' + j] = poExclude[j] + "\n";
        }

        var excluded_meta = [
            "Plugin Name of the plugin/theme",
            "Plugin URI of the plugin/theme",
            "Author of the plugin/theme",
            "Author URI of the plugin/theme"
        ];
        for (var translation in pot.translations[""]) {
            if ("undefined" !== typeof pot.translations[""][translation].comments.extracted) {
                if (excluded_meta.indexOf(pot.translations[""][translation].comments.extracted) >= 0) {
                    console.log("Excluded meta: " + pot.translations[""][translation].comments.extracted);
                    delete pot.translations[""][translation];
                }
            }
        }
        return pot;
    };

    return {

        theme: {
            options: {
                cwd: process.cwd(),
                domainPath: options.vars.paths.languages,
                mainFile: "style.css",
                potFilename: options.pkg.name + ".pot",
                processPot: processPot,
                include: poInclude,
                exclude: poExclude,
                potComments: "(c) " + options.pkg.author.name + " {{year}}",
                potHeaders: {
                    poedit: true,
                    "x-poedit-keywordslist": true
                },
                type: "wp-theme",
                updateTimestamp: false,
                updatePoFiles: true
            }
        }

    };

};
[12:20 ]-[vagrant@vm]-[/var/www/public/app/themes/custom-theme]-[git master]
$ grunt makepot

Running "makepot:theme" (makepot) task
Excluded meta: Author of the plugin/theme
Excluded meta: Author URI of the plugin/theme
>> POT file saved to languages/project-name.pot
>> POT file merged into languages/fr_FR.po

Done, without errors.

Execution Time (2015-10-07 12:28:33 UTC)
loading tasks  512ms  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 34%
makepot:theme     1s  ▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇▇ 66%
Total 1.5s
bradyvercher commented 9 years ago

Hi @tlartaud, the original issue was related to using an external copy of the core WP i18n tools. Is that what you were having problems with?

Or are there any particular steps I can take to reproduce the issue you were running into?

tlartaud commented 9 years ago

Hi @bradyvercher

I didn't change any setting about WPi18n to make it work. The important part here are X-Poedit-WPHeader X-poedit-keywordslist, and the include / exclude.

Any step to reproduce ? Yep, you need to try to compile a PHP code using thoses functions : _x or _nx etc ... I updated the keywords list.

tlartaud commented 9 years ago

@bradyvercher The error is to my mind related to .po file merging from .pot

I always been able to generate the .pot without any error being thrown. The message started displaying when i changed the value updatePoFiles to true.

To fix that, i've added x-Poedit headers manually.

bradyvercher commented 9 years ago

The updatePoFiles option requires the gettext utilities to be installed and available in your system path for that option to work. There's a note about that in the documentation here.

If you don't have those tools available, then it would make sense that you're receiving an error and changing the headers shouldn't really affect anything.

I hadn't run across the X-Poedit-WPHeader before. I'll open a new issue to add support for that.