Git Product home page Git Product logo

Comments (27)

jamuhl avatar jamuhl commented on August 15, 2024 2

@dyniper PR with a fix or removing that is welcome

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024 1

No worries, I know your pain! Just ping me when you want to go for it and I'll find some time to give the feature a test πŸ˜‰

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024 1

Ouch, looks like I was a bit late πŸ˜…

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

hm...not sure if people add customFormatters per message or just add them like once as default to all messages...

in i18next we have the https://www.i18next.com/translation-function/formatting

we might just have some additional option added to icu init like:

i18next
  .use(ICU)
  .init({
    i18nFormat: {
      localeData: fr, // you also can pass in array of localeData

formatters: {
  upcase: function(v) { return v.toUpperCase(); },
  locale: function(v, lc) { return lc; },
  prop: function(v, lc, p) { return v[p] }
}

    }
  });

those get added to all compiled message functions here: https://github.com/i18next/i18next-icu/blob/master/src/index.js#L50

Sorry just take a quick look...not sure if i got it right how it should behave.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

According to the docs, IntlMessageFormat expects a map of formatters to be the third parameter. It is not passed to the constructor at the moment:

fc = new IntlMessageFormat(res, lng);

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

From the user point of view the solution could look something like:

const icu = new ICU();
icu.addLocaleData(fr);
icu.addFormatters({
  upcase: function(v) { return v.toUpperCase(); },
  locale: function(v, lc) { return lc; },
  prop: function(v, lc, p) { return v[p] }
});
i18n.use(icu);

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

we could provide both...an additional addFormatters function and passing them via options:

this.options = utils.defaults(i18nextOptions, options, this.options || {}, getDefaults());

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Yeah that'd be cool. I'll be happy to test this feature if you are fancy an experiment πŸ˜‰

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

Will see when i find time...not hard to add this...more a problem of my time management 😭

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

hm...just started with it...as i thought simplest of all the shit i got planned....oh no...not really:

https://github.com/yahoo/intl-messageformat/issues/121#issuecomment-176043615

IntlMessageFormat custom formatters are no custom formatters just some...idk what they are: https://github.com/yahoo/intl-messageformat#user-defined-formats

And currently i do not expect them to do anything in this direction. So only option i currently see would be moving to messageformat

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

πŸ˜… oh gosh that's confusing indeed! Looks like my brain mixed-up MessageFormat formatters with IntlMessageFormat user-defined formats – I really thought they were the same thing!

Although user-defined formats in IntlMessageFormat are not functions as I originally expected, injecting them via i18next-icu may still make sense. Check out the options they pass in the example you referred to:

var msg = new IntlMessageFormat('The price is: {price, number, USD}', 'en-US', {
    number: {
        USD: {
            style   : 'currency',
            currency: 'USD'
        }
    }
});

This { style: 'currency', currency: 'USD' } looks very much like what gets passed to the browser's NumberFormat or its polyfill. This means that we can do something like:

const icu = new ICU();
icu.addLocaleData(fr);
icu.addUserDefinedFormats({
  number: {
    THREE_FRACTIONAL_DIGITS: {
      minimumSignificantDigits: 3,
      maximumSignificantDigits: 3
    },
    ROUGH: {
      maximumSignificantDigits: 1
    },
    VERY_PRECISE: {
      minimumSignificantDigits: 6,
    },
  }
});
i18n.use(icu);

And then:

{
  "example1": "Our value is equal to {value, number, THREE_FRACTIONAL_DIGITS}.",
  "example2": "Our value is roughly equal to {value, number, ROUGH}, but if you like things to be precise, it is {value, number, VERY_PRECISE}.",
}

There are plenty of options NumberFormat accepts, which makes it pretty powerful. Turns out we can cover lots of formatting cases just keeping things declarative – no need to use functions!

WDYT?

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

hope tests are sufficient to get how it works: 9607f39

currently running travis...will npm publish if all green

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

[email protected]

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Outstanding πŸŽ‰ I'll test your commit soon! Just one quick note before you've released this: should the method be called addFormatters or addUserDefinedFormats as I suggest in the more recent comment? The second name slightly better reflects the origin of the feature, but I don't have a strong opinion here.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Just noticed that the third argument in IntlMessageFormat constructor is called formats, not formatters: https://github.com/yahoo/intl-messageformat/blob/master/index.d.ts#L2

It does not influence the behaviour in any way, just makes things a bit less obscure (especially given the fact that the things with IntlMessageFormat vs MessageFormat are confusing from start πŸ˜… ).

Let me give your new version a try first anyway! Given that it's unlikely that too many people will be use custom formats from day one, I'll be happy to see the methods renamed if you agree with me that this can positively influence the coherence of 18next-icu.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Custom formats work well when passed to the ICU constructor:

const icu = new ICU({
  formatters: {
    number: {
      THREE_FRACTION_DIGITS: {
        minimumFractionDigits: 3,
        maximumFractionDigits: 3,
      },
    },
  },
});

This is truly great! πŸŽ‰

However, when I try using addFormatters, the numbers format as if my custom format did not exist:

const icu = new ICU();
icu.addFormatters({
  number: {
    PRICE: {
      minimumFractionDigits: 3,
    },
  },
});

I could get as far as adding several console.log() calls to node_modules/i18next-icu/dist/commonjs/index.js and noticed something strange. When formatters are passed as options, this.formatters are defined in parse(). When calling addFormatters(), this.formatters are also defined in this method, but are undefined in the following parse() calls. Does it give any hints?


One thing worth noting in my most recent example is that I replaced minimumSignificantDigits: 3 with minimumFractionDigits: 3 β€” significant digits are both fractional and integer ones combined. I also renamed THREE_FRACTIONAL_DIGITS with THREE_FRACTION_DIGITS for naming consistency with MessageFormat.

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

changed test to use the add function -> works on my machine and travis...

could you take another look - as i can't reproduce that. Only thing i know is having formats on init and additional adding via add function will overwrite them.

also done renamings...hope you like that

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

[email protected] includes changes.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Great, thank you πŸŽ‰ πŸ‘ I'll try the changes tonight.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

Hi @jamuhl, just a quick heads up. I ran out of time this evening, so have to postpone my tests for another day. Hope this can be tomorrow – I'll let you know once I get there. Sorry for this.

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

@kachkaev no problem...if there is something breaking it will be no big deal...i think after this i will change version to v1.0.0 anyway.

from i18next-icu.

dyniper avatar dyniper commented on August 15, 2024

I did some testing with this. The formatters passed in the ctor options works, but calling addUserDefinedFormats doesn't actually add the formats.

from i18next-icu.

kachkaev avatar kachkaev commented on August 15, 2024

@dyniper this worked for me to register a custom ICU format:

import * as ICU from "i18next-icu";
const icu = new ICU({
  formats: {
    number: {
      PRICE: {
        minimumFractionDigits: 2,
        useGrouping: false,
      },
    },
  },
});

If this solution satisfies you too, let’s close this issue.

from i18next-icu.

dyniper avatar dyniper commented on August 15, 2024

Yes, this work, but if you do:

import * as ICU from "i18next-icu";
const icu = new ICU();
icu.addUserDefinedFormats({
  formats: {
    number: {
      PRICE: {
        minimumFractionDigits: 2,
        useGrouping: false,
      },
    },
  },
});

, that one doesn't work. I don't mind having to provide the formats in the ctor, but if there is a method to add them after constructing the object, it should work, otherwise, remove the method.

from i18next-icu.

dyniper avatar dyniper commented on August 15, 2024

Will put that on the pile. Really busy these days and it makes hard to do community contributions. Thanks for everything you are doing.
By the way, I'm thinking about doing a i18nFormat module based on messageformat instead (https://github.com/messageformat/messageformat) as this would provide true custom formatter.

from i18next-icu.

jamuhl avatar jamuhl commented on August 15, 2024

@dyniper sounds like a good plan πŸ‘

from i18next-icu.

developerdanwu avatar developerdanwu commented on August 15, 2024

First of all, thanks for creating such a fantastic tool and my apologies for commenting on such an old issue. However, I was trying to use the custom formatter like the code below and one of my translators appears to want a 24 hour time whereas for the rest of the locales I want 12 hour time. Is it possible to set these custom formatters based on the locale? Eg. if user is on en it would one set of configs and another locale another set. If this is not an existing feature, I am willing to contribute and open a PR for this if given some direction on what would be the best solution. Thanks!

const icu = new ICU({
  parseLngForICU: (lng) => {
    return lng === 'en' ? 'en-GB' : lng;
  },
  memoize: true,
  formats: {
    number: {},
    date: {
      long: {
        day: 'numeric',
        month: 'short',
        year: 'numeric',
        weekday: 'long',
      },
      full: {
        hour12: true,
        day: 'numeric',
        month: 'short',
        year: 'numeric',
        weekday: 'long',
        hour: '2-digit',
        minute: '2-digit',
      },
    },
    time: {
      short: {
        hour12: true,
      },
    },
  },
});

from i18next-icu.

Related Issues (20)

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.