Git Product home page Git Product logo

ttag's People

Contributors

acro5piano avatar aler9 avatar alexmost avatar dependabot[bot] avatar eckertalex avatar erickwilder avatar frenberg avatar jaredh159 avatar jorrit avatar mmso avatar mrorz avatar oleksandr-kuzmenko avatar oleksmarkh avatar orkon avatar paulrosenzweig avatar spacek33z avatar stoyanovk avatar timgates42 avatar valtzu avatar vitaly-om avatar

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

ttag's Issues

doc for jt tag

Since we have support for jt it would be nice to document it in our docs.

skip fuzzy translations

The problem:
Fuzzy translations are applied on resolve:

#: uaprom/cs/domain/cms/Product/ProductList/views/GroupDiscountPopup/utils.js:12
#: uaprom/cs/domain/cms/Product/components/DiscountPopup/utils.js:11
#, fuzzy
msgid "${ counter } день"
msgid_plural "${ counter } дня"
msgstr[0] "${ count } клієнту"
msgstr[1] "${ count } клієнту"
msgstr[2] "${ count } клієнту"

leads to this transformation:

function getDaysCounterText(counter) {
    return _tag_ngettext(counter, [count + ' \u043A\u043B\u0456\u0454\u043D\u0442\u0443', count + ' \u043A\u043B\u0456\u0454\u043D\u0442\u0443', count + ' \u043A\u043B\u0456\u0454\u043D\u0442\u0443']);
}

Solution:
Filter fuzzy translations on translations resolve

Make config format errors more readable

For now we are validating c-3po config with ajv and it has validation schema. This works well but configuration errors are ugly and unreadable.

The task is to make them more clear (like webpack has for instance).

Example:

ERROR in ./app.js
Module build failed: Error: /home/a.mostovenko/git/webpack-demo/app.js: data.resolve should have required property 'translations'
    at ConfigValidationError.Error (native)
    at new ConfigValidationError (/home/a.mostovenko/git/webpack-demo/node_modules/babel-plugin-c-3po/dist/errors.js:21:131)
    at new Config (/home/a.mostovenko/git/webpack-demo/node_modules/babel-plugin-c-3po/dist/config.js:152:19)
    at PluginPass.extractOrResolve (/home/a.mostovenko/git/webpack-demo/node_modules/babel-plugin-c-3po/dist/plugin.js:21:22)
    at newFn (/home/a.mostovenko/git/webpack-demo/node_modules/babel-traverse/lib/visitors.js:276:21)
    at NodePath._call (/home/a.mostovenko/git/webpack-demo/node_modules/babel-traverse/lib/path/context.js:76:18)
    at NodePath.call (/home/a.mostovenko/git/webpack-demo/node_modules/babel-traverse/lib/path/context.js:48:17)

Should be something like this:

Configuration error. config.data.resolve should have required property 'translations'.

CHANGELOG 0.7.0

  • contexts
  • validation for addLocale. Dropped replaceVariableNames argument for addLocale (true by default).
  • ngettext validation

extensions API

As it was mentioned here, some new features that we want to add to c-3po will require extra dependencies. I am worried about keeping the core functionality as generic as possible.

In case that is described in the link above there is a feature request for react.js library which adds react and babel-preset-react to the project dependencies.

So maybe it is reasonable to have an ability to extend c-3po library and c-3po plugin in a way that all extra dependencies will be installed only if you need them with a separate extension package.

Basic workflow for extensions:

  1. There will be a separate package c-3po-react. So you need to install it separately if you need rt tag functionality.

  2. c-3po-react package will expose functions (tags) for wrapping translations. (rt tag for instance).
    This must work without transpile step.

    import { rt } from 'c-3po-react'
    rt`Click ${<a href="">here</a>}`
  3. Aditionaly we must upgrade babel-plugin-c-3po to be extensible via configuration. This can be done in something like this way:
    .babelrc

    plugins: [['c-3po', { extensions: ['c-3po-react'] }]]

    After this config babel plugin should be able to extract, validate and resolve translations inside rt tag.

In general, extensions would be easy to implement because c-3po already uses all extractor functions as extensions. You can look at how t tag is implemented - tag-gettext src

Current rough implementation for rt tag is here - #21
Want to hear your feedback guys @Alxpy @MrOrz ? What do you think?

create-react-app integration

As you asked for suggestions here is one 😅

It would be really cool to have an app template / integration into create-react-app.

Thanks to all contributors for this great piece of software!

Contexts proposal

One of the main feature request from other people, who sees c-3po is the context feature.
Context allows us to translate the same word (the same msgid) differently, depending on the context.

For C, C++ there are separate functions for applying context to the translation: pgettext, npgettext (for single and plural forms accordingly)

pgettext(<context>, <msgid>);
pngettext(<context>, <single form>, <plural form>, <count>);

As for me I don't like the idea of having separate functions for that. As it was designed for C initially, they almost had no other option. But we can make it better, so I would like to implement succinct API for the c-3po.

Proposal 1

To introduce special c function, that will return an object with all c-3po functions with applied context. It will accept context value as a first argument.

import { c, t } from 'c-3po'
c('context').t`Hello ${ user.name }`

// maybe better to place it on a separate lines
c('context')
.t`Hello ${ user.name}`
import { ngettext, msgid, c } from 'c-3po'
c('context').ngettext(msgid`${ n } banana`, `${ n } bananas`, n);

One thing that I am worried about, is that syntax becomes a little bit overloaded. But in general, I think context is not so frequent case. And with this apporach, it is clear how to introduce some other concepts like domains by just chaining them one after another.

d('domain')
.c('context')
.t`translate me`

Proposal 2

Place context information right into the t function call;

import { t } from 'c-3po'
t('context')`Hello ${ user.name}`
import { ngettext, msgid } from 'c-3po'
ngettext('context')(msgid`${ n } banana`, `${ n } bananas`, n);

This one looks a little bit cleaner that Proposal 1, but the question is how do we extend this to have domain info? Maybe something like this will work:

t({context: 'context', domain: 'domain'})`Hello ${ user.name}`

What do you think @MrOrz @Alxpy @Suhoy95

support gettext extracted comments

Extracted comments (see --add-comments part of the gettext doc, or developer comments) can be helpful for developers to hint the translator about the translated string. It would be nice if we support such feature.

/* this is foo */
const foo =  t`pen pineapple apple pen`;

const bar = /* hello world */ngettext(/* this is bar */ msgid`${n} time clicked`, `${n} times clicked`, n);

Could extracts to something like:

#. this is foo
#: some-file
msgid "pen pineapple apple pen"
msgstr ""

#. hello world
#. this is bar
#: some-file
msgid "${ 0 } time clicked"
msgid_plural "${ 0 } times clicked"
msgstr[0] ""
msgstr[1] ""

Contexts resolve for c-3po-babel-plugin

Original issue - #65
babel plugin should resolve translations according to the context.

Source file:

import { t, c } from 'c-3po';

console.log(t`test`);
console.log(c('email').t`test`);

Example .po file:

msgid "test"
msgstr "test translate default"

msgctxt "email"
msgid "test"
msgstr "test translate email"

Result file:

import { t, c } from 'c-3po';

console.log('test translate default');
console.log('test translate email');

Dev and Prod setup configurations

The key idea for the enhancement is to have efficient dev and prod setup with c-3po.

Core differences between prod and dev setup:

Requirements for the dev setup

  • Faster builds.
  • Fast feedback (validation works).
  • Simple integrations.

Requirements for the prod setup

  • Smaller resulting assets.
  • Less HTTP requests.

Bellow I will try to explain in details on the webpack example:

webpack dev setup

  • Locales (.po) files are processed with po-gettext-loader
  • Loading translations as a separate chunk on the client (webpack code splitting by require.ensure or async import). Can be also bundled in js assets, we don't care about the bundle size in dev.
  • Only one build is needed to switch between different locales.
  • Webpack watches changes in .po files and restarts build.
  • Validation for c-3po tags and functions is working but the transformation is disabled (plain c-3po library is used).

This setup will provide us fast builds (only one is needed), and fast feedback loop. Bigger bundles size and extra HTTP requests from the browser can be ignored in dev env).

webpack prod setup

  • Separate build for each locale.
  • No extra work on the client.
  • Transformations are executed (smaller bundles size).
  • Using c-3po mock instead of the whole lib

Smaller assets, faster load, less CPU work, fewer HTTP queries.

What we need for implementing this:

The good news is that both setups can be implemented with existing versions of lib and plugin. You can check https://github.com/c-3po-org/webpack-demo/tree/translations-chunk-load (translations-chunk-load branch).

What I suggest to improve?

  1. For now, there is no validation in dev setup. babel plugin will make validation only in resolve or extract mode. Somehow we should be able to specify that we need only validation without transformations in the config.
  2. By default, babel plugin will make resolveDefault if no extract or resolve config is specified. This part is not explicit and can be confusing. I think we should also change this default behavior.

My suggestions:

  1. Babel plugin should do nothing by default without no configuration (no resolveDefault transformations).
  2. resolveDefault is executed when { resolve : { default : true }} is present.
  3. Validation is happening by default and can be disabled by this setting

@MrOrz @Alxpy

contexts feature for c-3po lib

According to this proposal #65 we should implement contexts feature.

Example:

import { c, t } from 'c-3po'
c('context').t`Hello ${ user.name }`

// maybe better to place it on a separate lines
c('context')
.t`Hello ${ user.name}`

Runtime validation for ngettext

Need to implement some arguments check for the ngettext func.

  1. Ensure that the 1 argument is tagged with msgid.
  2. Check arguments count according to the current locale.
  3. All checks must be performed only in debug mode (to avoid performance issues in the production environment).

Hello from es2015-i18n-tag

Hey there,
I'm the author of es2015-i18n-tag. I just stumbled across your implementation of a translation library based on ES6 template tags.
Just wanted to say that I'm happy this idea gets some more attention.
Especially your progress on pluralization looks interesting. How about joining forces to build a more feature rich implementation of an i18n template tag?

By the way, I like the name of your lib. It sounds much better than es2015-i18n-tag :)

Best regards
Steffen

doc generator for c-3po

Need to have some kind of doc generation for c-3po functions. (esdoc or something similar)

discover c-3po functions by require

for now c-3po functions are discovered only by imports, but it is also necessary to discover them by require to make everything work on the backend side.

babel-plugin-c-3po should be able to discover this:

const { t } = require('c-3po');

Extract variables names to placeholders in .po and .pot files

Example:

t`Hello ${ username}

For now this will be extracted to

msgid "Hello ${ 0 }"

This behaves so because we are missing variable names information while resolving translations at the runtime. (details described here).

But what if we will transform our translations object (json with translations) in form of Hello ${ username } to Hello ${ 0 } in the runtime. This operation will be not so hard to perform (traverse tree and clone). And with this solution we will have the best of 2 worlds:

  1. The translator will see the variables names (provides more context for the translator).
  2. Translations will be working without transpile because we will transform our translations obj to the format that works now.
  3. Babel plugin has information about variable names also.

@MrOrz @Alxpy

bug with ngettext while passing 0

can not resolve translation when n is 0 (runtime backend):

const m = 0;
console.log(ngettext(msgid`${m} minute`, `${m} minutes`, m));

bug with sortByMsgId

Problem

Seems like comments reference entry is not extracted properly and becomes too large when sortByMsgid is present:

version info

c-3po - 0.4.5
babel-plugin-c-3po - 0.4.0

Stack trace:

uaprom/cs/domain/purchases/Forms/SubscriptionForm/components/Info.js:14/: RegExp too big
 at RegExp.exec (native)
    at RegExp.[Symbol.match] (native)
    at String.match (native)
    at buildPotData (/home/a.gurin/workspace/zakupki/node_modules/babel-plugin-c-3po/dist/po-helpers.js:30:62)
    at PluginPass.post (/home/a.gurin/workspace/zakupki/node_modules/babel-plugin-c-3po/dist/plugin.js:32:3)
    at File.call (/home/a.gurin/workspace/zakupki/node_modules/babel-core/lib/transformation/file/index.js:1:1)
    at File.transform (/home/a.gurin/workspace/zakupki/node_modules/babel-core/lib/transformation/file/index.js:1:1)
    at /home/a.gurin/workspace/zakupki/node_modules/babel-core/lib/transformation/pipeline.js:24:12
    at File.wrap (/home/a.gurin/workspace/zakupki/node_modules/babel-core/lib/transformation/file/index.js:1:1)
    at Pipeline.transform (/home/a.gurin/workspace/zakupki/node_modules/babel-core/lib/transformation/pipeline.js:22:12)
    at transpile (/home/a.gurin/workspace/zakupki/node_modules/babel-loader/lib/index.js:22:12)
    at Object.module.exports (/home/a.gurin/workspace/zakupki/node_modules/babel-loader/lib/index.js:1:1)

typescript definitions

I think our library should support typescript as well. So it would be great to start with a type definitions for the public API.

modular API for several translator objects

case:

Project have modular structure. And each module need to self translator.
With global addLocale, useLocale functions it looks difficult.

Maybe, it should be object (like Jed).

Or as domains-gettext functionally (issue) , but i need a object with gettext methods that ensure me that i choose the appropriate domain.

contexts extract for babel-plugin

According to this proposal #65 we should implement contexts feature.

Example:

import { c, t } from 'c-3po'
c('context').t`Hello ${ user.name }`

Should be extracted to this:

msgstr: "Hello ${ user.name }"
msgctx: "context"
msgstr: ""

Multiline match problem

Doesn't matches the translation at a runtime (without babel plugin):

legal_entity_required: t`Вы воспользовались ЭЦП выданной физическому лицу. 
    Для подтверждения данных организации, код ЕГРПОУ должен содержать 
    не более 8 символов. Воспользуйтесь ЭЦП повторно.`,

translation in .po

#: uaprom/cs/domain/purchases/ECPVerification/i18n.js
msgid ""
"Вы воспользовались ЭЦП выданной физическому лицу. \n"
"Для подтверждения данных организации, код ЕГРПОУ должен содержать \n"
"не более 8 символов. Воспользуйтесь ЭЦП повторно."
msgstr ""
"Ви скористалися ЕЦП, що належить фізичній особі. "
"Для підтвердження даних організації, в коді ЄДРПОУ має міститися не більше 8 символів. Скористайтеся ЕЦП повторно."

Sort order of msgids in translations.pot

Hey,
We successfully run this tool in a project, works well. However, one thing that may be slightly inconvenient is if you version the template.pot file, the order of the strings are different from build to build even if no strings are changed. It may pose a problem in that it generates merge conflicts, could it be an idea to sort the msgids alphabetically to mitigate this?

isomorph c-3po

Provide mechanism to resolve translations on a backend (without babel).

react translations

think about how we can handle something like:

    Нажмите <a onClick={this.handleClick}>здесь</a>.

maybe this can be an option

<translate>
    Нажмите <a onClick={this.handleClick}>здесь</a>.
</translate>

extracted result

msgid "Нажмите <to>здесь<tc>"
msgstr ""

Example 2

Осталось: <span>{this.props.complainTextSymbolsLeft}</span>
                    {ungettext([' символ', ' символа', ' символов'], this.props.complainTextSymbolsLeft)}.

to - tag open
tc - tag close

defaultHeaders setup

There is defaultHeaders setup for babel-plugin. We need this in the library also.

extend API as gettext

Hello,

Are you planning to extend your API to provide gettext functionality (such as domains and contexts)?

I'm considering this lib to use in work (work with AST, validation and React solution is great). But i have several issues/questions

I hope the cooperation.

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.