Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handling of variants for singular and plural should be possible #193

Closed
softwarerero opened this issue May 4, 2019 · 12 comments
Closed

Comments

@softwarerero
Copy link
Owner

Currently variable replacement has no logic attached. Let's say we have a variable photoCount, if its values is 0 we would like to render "hasn't added any photos yet",
if its values is 1 we would like to render "added a new photo",
otherwise we would like to render "added $photoCount new photos". We would have to define 3 differnt translation keys to be able to do that.

Recently Mozilla release the Fluent project which has a feature called selctors that allow to specify variants for key replacement.

In the spirit of selectors we could define a translation key like

T9n.map 'de', 
    'sharedPhotos': '''@{userName} @{photoCount -> 
        [0] hasn\'t added any photos yet
        [1] added a new photo
        [*] added $photoCount new photos
    }, @{sex -> 
        [male] he
        [female] she
        [*] that user
    } also liked a comment on a post'''

The translation key has two selectors photoCount and sex. We could request a translation like

T9n.get('sharedPhotos', true, {userName: 'Anne', photoCount: 0}, sex: 'female')
-> Anne hasn't added any photos yet, she also liked a comment on a post

T9n.get('sharedPhotos', true, {userName: 'Brian', Jeff: 1, sex: 'male'})
-> Jeff added a new photo, he also liked a comment on a post

T9n.get('sharedPhotos', true, {userName: 'Brian', photoCount: 3})
-> Brian added 3 new photos, that user also liked a comment on a post

There are three small differences with Fluent selectos, first the varaible name is surrounded by @{ and } and second, if the variable should be replaced with the given value within a replacment string, we have to prepend $, see $photoCount in the example above. Lastly the default value is marked with [*] instead of *[other].

@softwarerero
Copy link
Owner Author

This is implemented with version 2.4.0.

The code complicated now and this should be refactored to use regular expressions.

@softwarerero
Copy link
Owner Author

softwarerero commented May 4, 2019

The syntax for selectors has changed in version 2.5.0. To identify a variant we use a regular expression now instead of a simple string comparison. Let's revisit the example above:

T9n.map 'de', 
    'sharedPhotos': '''@{userName} @{photoCount -> 
        [0] hasn\'t added any photos yet
        1 added a new photo
        [2-4] added few photos
        .* added $photoCount new photos
    }, @{sex -> 
        female she
        male he
        .* that user
    } also liked a comment on a post. $userName was the subject.'''

T9n.get 'sharedPhotos', true, {userName: 'Anne', photoCount: 0, sex: 'female'}
-> Anne hasn't added any photos yet, she also liked a comment on a post. Anne was the subject.

T9n.get 'sharedPhotos', true, {userName: 'Jeff', photoCount: 1, sex: 'male'}
-> Jeff added a new photo, he also liked a comment on a post. Jeff was the subject.

T9n.get 'sharedPhotos', true, {userName: 'Rachel', photoCount: 2, sex: 'female'}
-> Rachel added few photos, she also liked a comment on a post. Rachel was the subject.

T9n.get 'sharedPhotos', true, {userName: 'John', photoCount: 3, sex: 'male'}
-> John added few photos, he also liked a comment on a post. John was the subject.

T9n.get 'sharedPhotos', true, {userName: 'Carol', photoCount: 4, sex: 'female'}
-> Carol added few photos, she also liked a comment on a post. Carol was the subject.

T9n.get 'sharedPhotos', true, {userName: 'Brian', photoCount: 5}
-> Brian added 5 new photos, that user also liked a comment on a post. Brian was the subject.

If a variable needs to be replaced within or after a selector, we need to use $variable instead of @variable, this makes parsing a lot easier. PRs are welcome to make the syntax more consistent.

@jadus
Copy link

jadus commented Nov 25, 2019

Hi, does this work in javascript ? How ?
Thanks !

@softwarerero
Copy link
Owner Author

Did you run into an error with the code above? Can you tell me what you did an what worked and what not, to find out if there is any issue?

@jadus
Copy link

jadus commented Nov 25, 2019

Thanks for your help. I just don't know how to write the multilines syntax in my js translation file.

@jadus
Copy link

jadus commented Nov 25, 2019

Of course this does not work :

const enTranslations = {
    'sharedPhotos': '@{userName} @{photoCount -> 
        [0] hasn\'t added any photos yet
        [1] added a new photo
        [*] added $photoCount new photos
    }, @{sex -> 
        [male] he
        [female] she
        [*] that user
    } also liked a comment on a post'
}

@softwarerero
Copy link
Owner Author

softwarerero commented Nov 25, 2019

Can you give this a try:


T9n.language = 'en'
T9n.map('en', {
    sharedPhotos: `@{userName} @{photoCount ->
        [0] hasn\'t added any photos yet
        1 added a new photo
        [2-4] added few photos
        .* added $photoCount new photos
    }, @{sex ->
        female she
        male he
        .* that user
    } also liked a comment on a post. $userName was the subject.`
})

console.log(T9n.get('sharedPhotos', true, { userName: 'Anne', photoCount: 0, sex: 'female' }))

@jadus
Copy link

jadus commented Nov 25, 2019

Works perfectly ! Thanks a lot.

@jadus
Copy link

jadus commented Dec 10, 2019

Hi, it seems like there is a bug in the logic.
For example when photoCount = 51 it falls in "added a new photo" because there is a "1" in "51"
Same thing for photoCount = 34 which falls in "added a few photos"

Can you fix this ?

@jadus
Copy link

jadus commented Dec 10, 2019

This works :

T9n.language = 'en'
T9n.map('en', {
    sharedPhotos: `@{userName} @{photoCount ->
        [5-9]|([1-9][0-9]) added $photoCount new photos
	[2-4] added few photos
	[1] added a new photo
	[0] hasn\'t added any photos yet
    }, @{sex ->
        female she
        male he
        .* that user
    } also liked a comment on a post. $userName was the subject.`
})

@softwarerero
Copy link
Owner Author

This also works:

T9n.map 'de',
    'sharedPhotos': '''@{userName} @{photoCount ->
        ^0$ hasn\'t added any photos yet
        ^1$ added a new photo
        ^[2-4]$ added few photos
        .* added $photoCount new photos
    }, @{sex ->
        female she
        male he
        .* that user
    } also liked a comment on a post. $userName was the subject.'''

I'm not sure at the moment if this needs a fix.

@jadus
Copy link

jadus commented Dec 10, 2019

Well your regex are better ;)
No need for a fix, thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants