npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ts-translate

v4.2.1

Published

Helps you to translate text from messages object. Allows you to format numbers, dates, interpolate text to string templates, default text as key, scoping translations, putting it to React Redux application with Provider and decorator (same pattern as Redu

Downloads

146

Readme

Translate CircleCI Dependency Status

Helps you to translate text from messages object. Allows you to format numbers, dates, interpolate text to string templates, default text as key, scoping translations, putting it to React Redux application with Provider and decorator (same pattern as Redux is using).

Also it supports connection to translation server with possibility to download translation on both server and browser side. Freeze translations with releases created in translation server. Also there is possibility of live updates of translations via Server Side Events.

yarn add ts-translate

Vanilla JS usage

import { fromJS } from 'immutable';
import { Translator } from 'ts-translate';


const translator = new Translator({
  messages: fromJS({
    en: {
      foo: 'bar',
      bar: {
        foo: 'FooBar'
        'Some Headline': 'Super Headline'
      }
    }
  }),
  locale: 'en'
});

translator.text('foo') // => 'bar'
translator.msg('foo') // => 'bar'
translator.msg('foo', { scope: 'bar' }) // => 'FooBar'
translator.msg('Some headline') // Not found will return text in first argument => 'Some headline'
translator.msg('Some headline', { scope: 'bar' }) // => 'Super Headline'

translator.hasMsg('foo') // => true'
translator.hasMsg('Some headline') //=> false

translator.msg('Not found text', { disableDefault: true })
// => Will not return default text (Not found text) instead it will return 'null'

translator.formatNumber(123456.78) // => 123,456.78
translator.formatNumber(123456.78, {precision: 1}) // => 123,456.8
translator.formatNumber(123456.78, {precision: 0}) // => 123,457
translator.formatNumber(123456.78, {delimiter: '.', separator: ','}) // => 123.456,78
translator.formatNumber(123456.78, {template: '%n %u', unit: '%'}) // => 123.456,78 %
translator.formatNumber(123456.78, {template: '%n $'}) // => 123.456,78 $

translator.formatCurrency(123456.78, {unit: '€'}) // => 123.456,78 €
translator.formatPercentage(123456.78) // => 123.456,78 %

translator.formatDate(new Date, 'M.D. YYYY') // => 28.2. 2017 -> using moment.js syntax
translator.formatDate(new Date, 'short') // => 28.2. 2017 -> using aliases (look down to Formats specification)

Msg & Cnt

msg() is returning by default React component which has set toString() set to return translated result so msg() will work correctly in <input placeholder={msg('placeholder')} />. cnt() is alias for msg() (deprecated).

if you need to return only translated result use text().

Interpolation

You can easily interpolate your translations with variables that will be evaluated during the execution of code and inserted into resulting strings.

{
  messages: fromJS({
    'This is value of %{key}: %{value}': 'Este es el valor de %{key}: %{value}',
    noninterpolatedKey: 'You have %{count} unread messages',
    deeper: {
      scopedKey: 'This is scoped and shows %{foo}',
    }
  })
}

Usage:

  msg('This is value of %{key}: %{value}', { key: 'foo', value: 'bar' })
  // => "Este es el valor de foo: bar"
  msg('noninterpolatedKey', { count: 42 })
  // => "You have 42 unread messages"
  msg('No need for translation to %{action} %{what}', { action: 'show', what: 'that' })
  // => "No need for translation to show that"
  msg('scopedKey', { scope: 'deeper', foo: 'BAR!' })
  // => "This is scoped and shows BAR!"

Formats Spefication

you can modify default formatting options by specifying:

{
  messages fromJS({
    en: {
      formats: {
        date: {
          default: { // formatDate(new Date)
            format: 'D.M.YYYY',
          },
          shortTime: { // formatDate(new Date, 'short')
            format: 'H:m'
          },
          long: { // formatDate(new Date, 'long')
            format: 'D.M.YY H:m:s'
          }
        },
        number: {
          default: {
            precision: 2
          },
          currency: { // formatNumber(123, 'percentage') === formatPercentage(123)
            unit: '€'
          },
          percentage: { // formatNumber(123, 'percentage') === formatPercentage(123)
            template: '%n %'
          },
          custom: { // formatNumber(123, 'custom')
            precision: 3
          }
        }
      }
    }
  })
}

this will enable you to use:

translator.formatNumber(123456.78) // => 123,456.78
translator.formatNumber(123456.78, 'currency') // => 123,456.78 € -> using alias
translator.formatCurrency(123456.78) // => 123.456,78 €
translator.formatPercentage(123456.78) // => 123.456,78 %

translator.formatDate(new Date, 'shortTime') // => 19:23 -> using alias
translator.formatDate(new Date, 'long') // => 28.2.2017 19:23:16 -> using alias

translator.formatNumber(123456.78, { precision: 1, separator: ',', delimiter: '' }) // => 123456,7 € -> using custom options

All number formatting options:

{
  precision: 10, // number of decimal places
  delimiter: ',', // used in 10,000,000.10
  format: defaultDateFormat,
  separator: '.', // used in 10.10
  template: '%n %u', // %n is placeholder for number, %u is for unit
  unit: '',
  trimTrailingZeros: true, // will remove exessive zeros 10.1200 -> 10.12
}

React + Redux

import { Provider as TranslateProvider, translate, reducer, changeLocale } from 'ts-translate';
import { fromJS } from 'immutable'
import { createStore, combineReducers } from 'redux';
import { Provider as ReduxProvider } from 'react-redux';

const initial = {
  messages: fromJS({
    cs: { home: { description: 'Foo', fallback: 'Fallback' } },
    en: { home: { description: 'enFoo', about: 'Bar' } }
  }),
  locale: 'cs',
  fallbackLocale: 'en'
};

// translation reducer must be added under `translate` key
const store = createStore(combineReducers({ translate: reducer }), { translate: initial});

class MyComponent extends React.Component {
  render() {
    const { msg } = this.props;
    return (<div>{msg('Something nice')}</div>);
  }
}

const TranslatedMyComponent = translate()(MyComponent);
const TranslatedScopedMyComponent = translate('home')(MyComponent);

store.dispatch(changeLocale('en')); // change locale to en

<ReduxProvider store={store} >
  <TranslateProvider>
    <TranslatedMyComponent /> // will look for key 'Something nice' in root of locale messages
    <TranslatedScopedMyComponent /> // will look for key 'Something nice' in `home` scope of locale messages
  </TranslateProvider>
</ReduxProvider>

Translation server

Enable application to send and receive translations from Translation server.

  • apiUrl - url to translation server
  • apiToken - project token is needed for enabling synchronization
  • sync - enable synchronization of translations (remembers translations, sends them to server and receives translations back)
  • liveSync - enable Server Side Events for instant refresh of translations directly after update in translation server
  • releasesDir - directory to store releases (needed for releases workflow)

Task for communicating with Translation server

Enables you to list and download releases to your project.

yarn translate-list // List all created releases
yarn translate-fetch // Download one specified release (for locale) to specified folder
yarn translate-fetch-latest-releases // Download all latest releases for all locales

Both commands supports taking apiToken and apiUrl from ENV variables (TRANSLATE_API_TOKEN, TRANSLATE_API_URL) or command line (--apiToken, --apiUrl) arguments.

Fetch commands also needs --releasesDir option for specifiyng where to save downloaded releases.

Passing config to Provider

import { Provider as TranslateProvider } from 'ts-translate';

const config = {
  apiUrl: 'https://translations.blueberry.io',
  apiToken: 'XYZ',
  sync: true,
  liveSync: true
}

<TranslateProvider config={config}>
  // ...
</TranslateProvider>

How to locate translations on different pages

You need to pass pathname or history object to TranslateProvider

<TranslateProvider config={config} pathname="/some/path">
  // ...
</TranslateProvider>
import createHistory from 'history/createBrowserHistory';
const history = createHistory();

<TranslateProvider config={config} history={history}>
  // ...
</TranslateProvider>

In App editor

Translation Editor

Just add new wrapper TranslateEditor around your code. This Editor must be under TranslateProvider context

import TranslateEditor from 'ts-translate/lib/editor';

<TranslateProvider config={config} pathname="/some/path">
  <TranslateEditor pathname="/some/path">
    // ...
  </TranslateEditor>
</TranslateProvider>

same rule for pathname and history as for TranslateProvider applies for TranslateEditor.

for disabling whole editor functionality (for example in production) set ENV variable TRANSLATE_DISABLE_EDITOR=t. When you are using webpack don't forget to add this to DefinePlugin as new webpack.DefinePlugin({ 'process.env.TRANSLATE_DISABLE_EDITOR': true }). Also if you are using minifier the whole code gets removed by death code removal. So it is pretty easy to use this editor in development and stage, but it will not increase size in production build.

On server side preload latest translations from TS

import { fetchTranslations } from 'ts-translates';

fetchTranslations(config)(dispatch);

Made with love by