smhg / gettext-parser

Parse and compile gettext po and mo files, nothing more, nothing less
MIT License
158 stars 43 forks source link

Backwards compatibility (es6) #50

Closed sontek closed 5 years ago

sontek commented 5 years ago

Hey, I just wanted to comment to start a discussion on backwards compatibility and what the best approach would be. We recently upgraded to the version that was refactored to ES6 and this broke Internet Explorer because they obviously don't work with it.

Do you think you could ship a compiled version of your library in npm, or do you prefer we compile it on our end? For now we've special cased it:

           include: [
                path.resolve(__dirname, 'static/js'),
                path.resolve(__dirname, 'node_modules/gettext-parser'),
            ],

but I think its more common to ship a web ready version that doesn't require processing

smhg commented 5 years ago

Thank you for bringing this up. I didn't expect the need for an ES5 version as I (erroneously) assumed there wouldn't be much browser usage for this library. I'll add a build step and release 4.1.0 soon.

sontek commented 5 years ago

I might be the only one using it in the browser :p

smhg commented 5 years ago

Are you able to share how you use it (in the browser)?

sontek commented 5 years ago

I have a translation system using Jed but our users have the ability to provide custom text and that also needs to be translatable. So we just give them to po file, let them modify it, and upload it back to us. Then I just read that file they upload to translate their dynamic content:

import * as api from "../api/forms";
import gettextParser from "gettext-parser";

const isEmptyMessage = (msg) => {
    for (let i = 0; i < msg.msgstr.length; i++) {
        if (msg.msgstr[i] === "" || msg.msgstr[i] === null) {
            return true;
        }
    }
    return false;
};

export const gettextToJed = (domain, source) => {
    const catalog = gettextParser.po.parse(source);
    const rv = {};
    Object.keys(catalog.translations[""]).map((msgid) => {
        if (msgid !== "") {
            const msg = catalog.translations[""][msgid];

            if (!isEmptyMessage(msg)) {
                rv[msgid] = msg.msgstr;
            }
        }
    });

    rv[""] = {
        domain: domain || "messages",
        plural_forms: catalog.headers["plural-forms"],
        lang: catalog.headers["language"],
    };

    return rv;
};

export const formsTranslationLoader = (user, form_id) => (language) => {
    return api
        .getTranslations(user.token, language, form_id)
        .then((result) => {
            if (result.success) {
                const jsonTranslations = gettextToJed("eventray", result.data);
                return jsonTranslations;
            } else {
                /* Return english if we crash */
                return {
                    "": {
                        domain: "eventray",
                        lang: language,
                        plural_forms: "nplurals=2; plural=(n != 1);",
                    },
                };
            }
        });
};
smhg commented 5 years ago

I'm going to return on my initial answer. An ES5 version is probably not worth the (small) maintenance burden. IE usage is likely insignificant. And you have a rather ok solution with compiling it yourself. Additionally, you can also pin to version 3.x as version 4 (currently) doesn't really offer anything new.

Feel free to disagree though (now or in the future). Always open for discussion.