Skip to content
This repository has been archived by the owner on Jun 26, 2020. It is now read-only.

WIP: Implemented new gettext-like functions. #321

Closed
wants to merge 8 commits into from
Closed

Conversation

phaux
Copy link

@phaux phaux commented Jan 29, 2020

Suggested merge commit message (convention)

Feature: Implemented new gettext-like functions.

Closes: ckeditor/ckeditor5#6158

@coveralls
Copy link

coveralls commented Jan 29, 2020

Coverage Status

Coverage decreased (-2.04%) to 97.964% when pulling 3c8f5a0 on intl-refactor into b148e9c on master.

src/locale.js Outdated
* @private
*/
_ctn( msgctxt = '', msgid = '', msgidPlural = '', value = 0 ) {
return this._ct( msgctxt, value == 1 ? msgid : msgidPlural, [ value ] );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Will it work? What kind of JSON structure do you expect if _ct is used like that? How translate works? Assume that the language is Polish (translation keys are in English, of course).

Also, we are giving up a possibility to use multiple placeholders, which is not ideal. How about _ctn( msgctxt = '', msgid = '', msgidPlural = '', quantity = 0, values = null ) and if values is not set, then it becomes [ quantity ]?

Example usage: ctn( 'Sent x of y files', 'file', '%0 of %1 files', 4, [ 1, 4 ] );

Copy link
Contributor

@scofalik scofalik Jan 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think that translate() function could take quantity as an additional parameter and return a proper string from the JSON language file.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plural function usually takes only one parameter. I will implement proper plural selection after I change the webpack plugin

src/locale.js Outdated
translatedString = translatedString.replace( /%(\d+)/g, ( match, index ) => {
return ( index < values.length ) ? values[ index ] : match;
} );
if ( values.some( value => typeof value == 'object' ) ) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I could argue that Boolean type can be casted to a string, however maybe we could also check if a value is a function? Maybe there would be uses for this functionallity.

src/locale.js Outdated
* editor.ct( 'Created file "x"', 'file "%0"', [ fileName ] );
*
* If at least one of the placeholder values is not a string or number,
* then an array of all the literal and dynamic parts will be returned
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

. missing at the end of the sentence.

Please expand with an example. It was difficult for me to understand what this means and how I could use it.

src/locale.js Outdated
* The strings may contain a placeholder (`%0`) for a given dynamic value.
* The value is also used for selecting the correct plural form.
*
* editor.ctn( 'Created n files', '%0 file' '%0 files' fileCount );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When you fix docs for ct please check this function docs against ct docs. Some stuff is missing here, AFAICT.

src/locale.js Outdated
*
* @method #t
* @param {String} str The string to translate.
* @param {String} msgid The string to translate.
* @param {String[]} [values] Values that should be used to interpolate the string.
Copy link
Contributor

@scofalik scofalik Jan 29, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Array.<String>

src/locale.js Outdated
_t( str, values ) {
let translatedString = translate( this.uiLanguage, str );
_t( msgid = '', values = [] ) {
return translate( this.uiLanguage, msgid )
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not have the same functionallity here and in _ct and _ctn (splitting to array?).

We could move lines 183-200 to a seprate function and use them in _t, _ct and _ctn.

@scofalik
Copy link
Contributor

scofalik commented Jan 29, 2020

Apart from what I commented:

  1. Add additional blank line before ifs and after ifs.
  2. Docs:
    1. use capital letters for types (string => String)
    2. use Array.<T> instead of T[]
  3. Tests are missing. Please do a thorough tests.

* Translates the given string to the {@link #uiLanguage}.
*
* This method allows passing the context as the first argument.
* A context is used to provide a description or example of how the translated string will be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* A context is used to provide a description or example of how the translated string will be used.
* The context is used to provide a description or example of how the translated string will be used.

*
* This method allows passing the context as the first argument.
* A context is used to provide a description or example of how the translated string will be used.
* An unique context makes the whole translation unique.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
* An unique context makes the whole translation unique.
* A unique context makes the whole translation unique.

*
* editor.t( 'Created file "%0" in %1ms.', [ fileName, timeTaken ] );
* This method allows passing the context as the first argument.
* A context is used to provide a description or example of how the translated string will be used.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above.

src/locale.js Outdated
*/
this.t = ( ...args ) => this._t( ...args );
this.ctn = ( msgctxt, msgid, msgidPlural, quantity ) => this._ctn( msgctxt, msgid, msgidPlural, quantity );
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we name this function ctq? Context-translation-quantity?

src/locale.js Outdated
* `<index>` is the index in the `values` array.
* @method #t
* @param {String} msgid The string to translate.
* @returns {Message}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it return Message or String?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it can return Message, if it is stringify-able easily. But then we need to change t() function definition.

* Get the interpolated message as string.
* This method will replace the placeholders in the message with provided values.
*
* @example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I haven't seen us using those tags before, so make sure they are correctly parsed by Umberto into API docs.

* and returns an array of the original string parts with provided values interspersed.
* The values can be of any type and won't be stringified.
*
* @example
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to see an example with non-strings here.

*/
export class Message {
/**
* @hidden
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What's the hidden tag? I'm afraid we don't use it anywhere. And I couldn't find it in https://jsdoc.app/  too.

*
* expect( msg ).to.equal( [ 'Replace ', 'foo', ' with ', 'bar' ] )
*
* @template T
Copy link
Contributor

@ma2ciek ma2ciek Feb 14, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also unsure about the generic @template tag. Currently we don't use it anywhere. I know it's a very valuable thing, though it can be unsupported currently by Uberto and our JSDoc plugins 😞

@ma2ciek
Copy link
Contributor

ma2ciek commented Apr 17, 2020

Closing in favor of #334.

@ma2ciek ma2ciek closed this Apr 17, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve Locale.t() to handle context and plurals.
4 participants