Git Product home page Git Product logo

jed's Introduction

Build Status

Jed

Gettext Style i18n for Modern JavaScript Apps

For more info, please visit the docs site at http://messageformat.github.io/Jed.

You sure you don't want something more modern?

Jed is feature complete in my opinion. I am happy to fix bugs, but generally am not interested in adding more to the library.

I also maintain messageformat.js. If you don't specifically need a gettext implementation, I might suggest using MessageFormat instead, as it has better support for plurals/gender and has built-in locale data.

Parsing Gettext Files

Jed doesn't include a Gettext file parser, but several third-party parsers exist that can have their output adapted for Jed.

Node

Just search the npm repository, there are several PO and MO file parsers available.

Browser

Jed Gettext Parser is the only known browser MO file parser, and it also works in Node, and outputs Jed-compatible data directly.

gettext.js and Pomo.js both include browser-compatible PO file parsers.

Todo

  • Build time generation of plural form functions
  • Web interface for building translation sets
  • Code introspection for default values

License

Jed is a member project of the JavaScript Foundation

You may use this software under the MIT License.

Contributor License Agreement

We require all contributions to be covered under the JS Foundation's Contributor License Agreement. This can be done electronically and essentially ensures that you are making it clear that your contributions are your contributions, you have the legal right to contribute and you are transferring the copyright of your works to the JS Foundation.

If you are an unfamiliar contributor to the committer assessing your pull request, it is best to make it clear how you are covered by a CLA in the notes of the pull request. The committer will verify your status.

If your GitHub user id you are submitting your pull request from differs from the e-mail address which you have signed your CLA under, you should specifically note what you have your CLA filed under (and for CCLA that you are listed under your company's authorised contributors).

Author

Credits

A good chunk of sanity checking was done against the gettext.js tests. That was written by:

  • Joshua I. Miller

The sprintf implementation is from:

  • Alexandru Marasteanu <alexaholic [at) gmail (dot] com>

The name

The name jed.js is an homage to Jed Schmidt (https://github.com/jed) the JavaScript community member who is a japanese translator by day, and a "hobbyist" JavaScript programmer by night. Give your kids three character names and they'll probably get software named after them too.

jed's People

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  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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

jed's Issues

Typo fallack / fallback?

I suppose there is a typo in jed.js:

$ egrep -n "fallb?ack" jed.js

227:      var fallack;
236:        fallback = new Jed();
237:        return fallback.dcnpgettext.call( fallback, undefined, undefined, singular_key, plural_key, val );

I'd say that line 227 should read var fallback;

BTW: awesome library, thank you - I'll use it in my next projects.

And another question regarding documentation:

Is there a parser which extracts gettext keys and values from source code and creates .po files?
And if yes, is it working with the Chain-API?
Sorry, if I missed something...

Error: domain is not defined

See https://github.com/SlexAxton/Jed/blob/master/jed.js#L97

    if ( options.domain && ! this.options.locale_data[ this.options.domain ] ) {
      throw new Error('Text domain set to non-existent domain: `' + domain + '`');
    }

must be:

    if ( this.options.domain && ! this.options.locale_data[ this.options.domain ] ) {
      throw new Error('Text domain set to non-existent domain: `' + this.options.domain + '`');
    }

Otherwise, the error "domain is undefined" is thrown when Jed attempts to throw a custom error.

Readme says that Jed ignores the first element of the translated array, but that's no longer the case.

In commit 8cc3736, it looks like the expected format of locale_data changed so that the first element of the translated data array is no longer supposed to be a null. That's at odds with what's on the doc site http://slexaxton.github.io/Jed/ and a lot of the examples on the web. po2json, which I was using to parse my po files, doesn't output the right format anymore. Please update the doc and examples.

Use in a web-app

I find JED an excellent improvement to gettext. I can't wait to start using it, but I'm a bit lost.
So I'm asking here, for posterity. Thanks in advance!

To make things simple, consider this situation:
I want an Express app that returns Hello World! to every request,
translated to the browser's language.

var express = require('express')
  , app = express();

app.use( /** some amazing middleware **/ );
app.use(function(req, res) {
  // the browser's locale is in req.locale
  res.send("Hello World!\n");
}

How would you do this with JED?
How many instances would be needed?
How many domains? ...

gettext not retrieving full value

I'm using JED but when I call the translate/gettext method on a key, I'm only getting the first character!

So if I have a key like: "Hello" that should get the transalation for german: "Hallo", instead I just get H. See here, which shows the JED object, and then the output for i18n.translate('Hello').fetch():

7bzhf

Cannot add missing key callback function

I am unable to add the callback to the JSON file. I tried

  "missing_key_callback" : function(key) {
    // Do something with the missing key
    // e.g. send key to web service or
    console.error(key)
  },

to no avail

0-index null

Hi, this has been bugging me for a while

// Note: by convention, the 0-index location of the translations
// is never accessed. It's just a thing, I guess.

what does this mean, convention by whom ? I look at my po files and all of them have all useful data.

They don't have any useless translation that is never accessed, so where is this convention coming from.
For kicks I've been going through the source code and deleting all ' + 1' there and there, and with an ugly

val_list = _.compact(val_list);

It just works, but there's no waste of an empty index in an array. Why would I parse an mo file to generate empty data ?

Add "trigger plural on boolean" and "trigger plural with variables on boolean" methods

I wrote a small implementation of the gettext concept recently and wanted to provide two new methods to the community. I was writing these in React Native, as shown below, and would be happy to incorporate the pure JS equivalents into this project for Hacktoberfest! 🎃🎃🎃

In short, the first method pboolgettext returns the plural form if a boolean is true or the singular form if the boolean is false. This is a case when no variables need to be inserted.

The second, pvboolgettext, does the same, but formats the plural message with variables.

/*
    * Returns the singular form of the message if a given boolean condition is true, otherwise the plural form.
    *
    * usage : pgettext(singularMessageId: string, pluralMessageId: string, b: boolean)
    *
    * @param singularMessageId <string> : the message ID to be used if the number of elements specified is zero
    * @param pluralMessageId <string> : the message ID to be sued if the number of elements specified is greater than zero
    * @param b <boolean> : a condition indicating if the singular message form should be displayed or not
     */
    pboolgettext(singularMessageId: string, pluralMessageId: string, b: boolean) {
        if (typeof singularMessageId === "undefined" || typeof singularMessageId === "undefined" || typeof b === "undefined") {
            throw "pboolgettext: Invalid arguments";
        }
        return b ? this.translations[singularMessageId] : this.translations[pluralMessageId];
    }

    /*
    * Returns the singular form of the message if a given boolean condition is true, otherwise the plural form formatted with variables.
    *
    * usage : pgettext(singularMessageId: string, pluralMessageId: string, b: boolean, value: any)
    * usage : pgettext(singularMessageId: string, pluralMessageId: string, b: boolean, values: [any, ... ,any])
    *
    * Note : variables can be mixed string and number.
    *
    * @param singularMessageId <string> : the message ID to be used if the number of elements specified is zero
    * @param pluralMessageId <string> : the message ID to be sued if the number of elements specified is greater than zero
    * @param b <boolean> : a condition indicating if the singular message form should be displayed or not
    * @param v <any> : the variable or variables to insert into the plural string
     */
    pvboolgettext(singularMessageId: string, pluralMessageId: string, b: boolean, ...values) {
        if (typeof singularMessageId === "undefined" || typeof singularMessageId === "undefined" || typeof b === "undefined" || typeof values === "undefined") {
            throw "pvboolgettext: Invalid arguments";
        }
        if (b) {
            return this.translations[singularMessageId];
        }
        return this.vngettext(pluralMessageId, ...values);
    }

Update Version at the top of jed.js

Hi,

just noticed when downloading 0.5.4 that the jed.js header comment still says it is 0.5.0. Would be nice to have that reflecting the actual version (in upcoming versions).

Thanks!

New feature: Notify server when key is not found

Hi,

I've noticed that Jed currently doesn't have support for notifying a web service when a key is not found like i18next does.

I would like to add a callback to Jed which is called when a key is not found, making it possible to notify a web service or send an email from the callback.

What do you think of this?

Josh

Plurals and xgettext

Hi,

I'm trying to get my messages.po from Javascript files using Jed. I'm using xgettext and this command:

  xgettext --keyword=translate --from-code utf-8 -L Perl `find . -iname "*.js"`

It seems to work fine, but the problem comes when xgettext finds plurals like the next ones:

i18n.translate("Pass through %1$s %2$s").fetch(var1, var2);

Because it doesn't recognizes $ as a valid character. Is there any work around using xgettext, or otherwise, any other way to use a different numbering method xgettext-compatible?

Thanks.

Manifest repo url is blocked by firefox

The repository url in the package.json contains a username, which causes problems in some browsers.

"url": "https://[email protected]/SlexAxton/Jed.git"

By opening this link in firefox the browser attempts to login to github with the SlexAxton username and shows the following error:

You are about to log in to the site “github.com” with the username “SlexAxton”, but the website does not require authentication. This may be an attempt to trick you.

The right way to dynamically load JSON-translation?

In the documentation I see only one way to load translation - when the init Jed.
ok! what if I use require.js for dynamically loading some Views and with it I want upload additional translations for Jed?
Here example with using "extend" (underscore.js). Can you propose another way?
I mean a legal (native) way with the context of the library.

var i18n = new Jed(options);
 require(['json2', 'text!/test/translation/fr/app.json'], _.bind( function(JSON, appjson) { 
  _.extend(i18n.options.locale_data.messages, JSON.parse(appjson) );
 }, this)  );

Thanks!

po2json for new Jed format

Hey Jed folks! A couple of us were having a discussion about the new Jed format downstream at mikeedwards/po2json#32 . We're trying to figure out what the best output for something like this:

msgid "one product"
msgid_plural "%d products"
msgstr[0] "jeden produkt"
msgstr[1] "%d produkty"
msgstr[2] "%d produktów"

We were outputting (correctly or not):

         "one product": [
            "%d products",
            "jeden produkt",
            "%d produkty",
            "%d produktów"
         ],

Would it be like this now that the zeroth element is being lopped off?

         "one product": [
            "jeden produkt"
         ],
         "%d products": [
            "jeden produkt",
            "%d produkty",
            "%d produktów"
         ]

generate .po's

Thanks for Jed!

I'm looking into generating the .po files from my source. I wondered how you do/did that?

I started working on contributions to an existing package (handelbars-xgettext), but there must be something already out there?

Bind methods

Currently one cannot do:

const {gettext} = i18n
gettext('Hello, World.')

As this would return:

TypeError: Cannot read property 'call' of undefined

However it seem fairly important to be able to shorten notations for views/renders with a lot of strings and for clarity of context.

Would it make sense to add a property accessor that would return an object listing those method as bound vs. call? This would also allow destructuring to get the needed methods.

Docs might note that when using po2json format setting 'jed1.x' is needed

My translations weren't working, and I had to search through the source code of po2json to discover that I needed to use the 'jed1.x' setting rather than just 'jed'. Might be worth noting this in the documentation.

So just to be clear, I needed to run

jedInitJson = po2json.parse(window.PRELOAD.TRANSLATIONS, {format: 'jed1.x'})

instead of

jedInitJson = po2json.parse(window.PRELOAD.TRANSLATIONS, {format: 'jed'})

Thanks for the great library!

Translations extraction

Hi,

How does one generate .pot from the source code using Jed? I assume that gettext won't be able to parse the calls to Jed since the syntax is too complex. If that's so, what are the alternatives?

Cheers,
Andrej

Load string from different locale

It seems to be impossible to load string from different locale.

You might need it, for example, for generating of list of available languages, within which each language should be displayed in it's on language:

* English
* Украинский
* Deutsche

Are there any chances to see such functionality?

Thanks in advance!

Creating a Jed instance

I'm trying use jed.js as a solution for i18n in my project.

I'm having trouble understanding the options passed to the Jed constructor.

Docs say that I should pass in a domain and locale_data object. However, in the locale_data, there is another key with the domain value. And again, under that, there is an empty key (i.e. "") which has another domain key and the domain as the value.

Here's an excerpt from the docs:

var i18n = new Jed({
    // You can choose to set the domain at instantiation time
    // If you don't, then "messages" will be used by default
    "domain" : "the_domain",
    // This is the translation data, which is often generated by
    // a po2json converter. You would ideally have one per locale
    // and only pull in the locale_data that you need.
    "locale_data" : {
        // This is the domain key
        "the_domain" : {
            // The empty string key is used as the configuration
            // block for each domain
            "" : {
                // Domain name
                "domain" : "the_domain"
            }
        }
    }
});
  1. What is the meaning of the domain, and why is it repeated so many times?
  2. Do I need a new Jed instance for every domain?
  3. How does the domain relate to the language?

string extraction from JS for po/pot files

Hi,

I'm currently using xgettext in Python mode, but there are quite a few edge cases where it doesn't work correctly. How do you extract gettext keys from your JS files?

thanks,
Florian

Way to detect language

Is there a way to detect the device language and act accordingly or do you need to tell it which translation data to use based off the language. Or, if I have a spanish domain but not english, it won't throw an error but will default to the id -- return the key or msgid if there is no domain

Confusing plural examples

There are two examples of plural forms on this page

  1. "%d key" : [ "%d key", "%d keys" ],
  2. "test singular": ["test plural", "test_1 singular", "test_1 plural"],

These appear to be different structures. Using Gettext terminology they look like:

  1. msgid: [ msgstr1, msgstr2 ]
  2. msgid: [ msgid_plural, msgstr1, msgstr2 ]

Can you please clarify how this structure should be used and whether it has changed at some point?

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.