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

Add support for multiple languages #85

Merged
merged 3 commits into from
Apr 9, 2024

Conversation

m-horky
Copy link
Contributor

@m-horky m-horky commented Aug 30, 2023

Is this a fix, improvement or something else?

This is an improvement, an updated version of #73.

This patch adds support for fallback translations. pt_BR:pt:es makes it possible to use Brazilian Portuguese, fallback to default Portuguese and to Spanish when the translation is not available.

What does this change implement/fix?

  • This patch changes the config struct, and internal implementation of functions that work with it.
  • It changes Get*() functions to iterate over loaded languages, instead of using the only one.
  • It changes IsTranslated*() functions to include new required argument of the language to be checked.
  • See more detailed changes in the respective commits.

The original PR failed because PR #80 was merged first. Since my PR changes the naming from storage to locales, I'd like to have opinion of @didrocks as well. For this version I have opted to keep their function names GetStorage and SetStorage for complete backwards compatibility. This is a bit unfortunate because the functions are called differently from the rest of the code, but we cannot change that without making a breaking change.
(I am not blaming you, the change does make sense. The naming just is not the best, as it is a bit cryptic without knowing the internals.) I can revert it all to 'storage' if consistency is preferred, that's up to @leonelquinteros to tell :)

I have ...

  • answered the 2 questions above,
  • discussed this change in an issue,
  • included tests to cover this changes.

@didrocks
Copy link
Contributor

The original PR failed because PR #80 was merged first. Since my PR changes the naming from storage to locales, I'd like to have opinion of @didrocks as well. For this version I have opted to keep their function names GetStorage and SetStorage for complete backwards compatibility. This is a bit unfortunate because the functions are called differently from the rest of the code, but we cannot change that without making a breaking change.

Oh, I completely got it that this was the system locales (I had to dig quite in the code for the next couple of PR I submitted if you saw that :p). I was puzzled by the naming too and I agree that, from an external contributor POV, a slice of locales makes more sense, but as you told, that’s up to @leonelquinteros.

On the renaming, as there has been no stable release with it, I have no issue changing my projects using those commits if the Get/Set names were changed here.

@m-horky
Copy link
Contributor Author

m-horky commented Oct 9, 2023

@leonelquinteros ping :)
Since no version has been released since Dec 22, what do you think about the storage → locale rename? Either way my PR is ready for review notes. I'd appreciate if you found some time for that. I think the package would benefit from having multi-language capability.

gotext.go Outdated
globalConfig.RLock()
lang := globalConfig.language
globalConfig.RUnlock()
return GetLanguages()[0]
Copy link

Choose a reason for hiding this comment

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

Nitpicking ; if one calls SetLocales() with an empty slice, this will panic.
Calling SetLocales() with an empty slice could default back to the globalConfig language, or checks could be made here ?

Copy link

Choose a reason for hiding this comment

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

Do note that calling SetLocales with an empty slice could be desired when writing consumer tests, to sort of reset the state of things to defaults.

@Goutte
Copy link

Goutte commented Dec 16, 2023

I really want this for cobra ( spf13/cobra#2090 ), since I want to fall back to english when a translation is not found, as well as support regional fallback (fr_CA → fr).

I reviewed this, and besides a corner-case happening when SetLocales is kind of abused by the consumer, it looks good to me. :)

gettext supports supplying multiple languages using the colon character
$ LANGUAGE=pt_BR:pt_PT:en_US foo bar
which are used as fallback: when a translation for the first one is not
available, the second language is used. If no language contains
a translation for the string `msgid` is returned.

This patch adds this support into gotext.

1/ config struct
 - 'language' was renamed to 'languages' and is a slice of strings
 - 'storage' was renamed to 'locales' and is a slice of Locale pointers

2/ loadStorage()
 - all loaded languages are iterated over

3/ GetLanguages()
 - new function returns the languages from the config
 - GetLanguage() uses the first element of it, keeping the compatibility

4/ SetLanguage(), Configure()
 - the language string is split at colon and iterated over

5/ Get*()
 - languages are iterated and the first translation for given string is
   returned

6/ IsTranslated*()
 - new optional parameter (langs) has been added

7/ Locale.GetActualLanguage()
 - it checks the filesystem and determines what the actual language code
   is: for 'cs_CZ', just 'cs' may be returned, depending on the actual
   name of the .mo/.po file.

8/ GetLocales/GetStorage, SetLocales/SetStorage
 - Following recent changes, created public functions to manipulate with
   global configuration's locales. The *Storage functions are renamed
   in later commit to reduce the amount of changes in one commit.
@m-horky
Copy link
Contributor Author

m-horky commented Dec 19, 2023

Thanks for catching that @Goutte. Fixed.

@Goutte
Copy link

Goutte commented Dec 19, 2023

Thank you, @m-horky ! I'm eager to try this out 🥳

Copy link

@Goutte Goutte left a comment

Choose a reason for hiding this comment

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

LGTM

@leonelquinteros
Copy link
Owner

Hey guys, I'm very sorry for the delay on this. I'm glad you've advanced with this PR so far and cross-reviewed it.
I'm reviewing it now and will merge soon.

About renaming... As long as the public interface isn't changed, I'm OK with renaming internals as long as they make sense and don't add even more confusion to the matter.
The thing about the public API is that to follow Golang guidelines, if we change anything there we need to move to a v2 structure which I'm trying to avoid because of maintainability cost. That said, I'm OK to add new methods that "replace" or "replicate" functionality from others that may have confusing names, but we still need to support the old API.

Copy link
Owner

@leonelquinteros leonelquinteros left a comment

Choose a reason for hiding this comment

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

Added 2 small comments to review, everything else looks good to merge.

gotext.go Outdated
func GetLocale() *Locale {
locales := GetLocales()
if len(locales) > 0 {
return GetLocales()[0]
Copy link
Owner

Choose a reason for hiding this comment

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

Shouldn't we return locales[0] here to avoid the double function call?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Of course, this was my oversight. Fixed.

gotext.go Show resolved Hide resolved
As the package matured, it makes sense to use unified names everywhere.
Since the config holds Locale objects, the variable is called 'locales'.

This patch finishes the work and updates the 'loadStorage' function
to be called 'localLocales' with argument 'rebuildCache' instead of
'force'.
@leonelquinteros leonelquinteros merged commit c7c2135 into leonelquinteros:master Apr 9, 2024
1 check passed
nono referenced this pull request in cozy/cozy-stack Apr 15, 2024
…4376)

[![Mend
Renovate](https://app.renovatebot.com/images/banner.svg)](https://renovatebot.com)

This PR contains the following updates:

| Package | Change | Age | Adoption | Passing | Confidence |
|---|---|---|---|---|---|
|
[github.com/leonelquinteros/gotext](https://togithub.com/leonelquinteros/gotext)
| `v1.5.2` -> `v1.6.0` |
[![age](https://developer.mend.io/api/mc/badges/age/go/github.com%2fleonelquinteros%2fgotext/v1.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![adoption](https://developer.mend.io/api/mc/badges/adoption/go/github.com%2fleonelquinteros%2fgotext/v1.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![passing](https://developer.mend.io/api/mc/badges/compatibility/go/github.com%2fleonelquinteros%2fgotext/v1.5.2/v1.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|
[![confidence](https://developer.mend.io/api/mc/badges/confidence/go/github.com%2fleonelquinteros%2fgotext/v1.5.2/v1.6.0?slim=true)](https://docs.renovatebot.com/merge-confidence/)
|

---

### Release Notes

<details>
<summary>leonelquinteros/gotext
(github.com/leonelquinteros/gotext)</summary>

###
[`v1.6.0`](https://togithub.com/leonelquinteros/gotext/releases/tag/v1.6.0)

[Compare
Source](https://togithub.com/leonelquinteros/gotext/compare/v1.5.2...v1.6.0)

#### What's Changed

- Allow locale to use a `fs.FS` by
[@&#8203;kobergj](https://togithub.com/kobergj) in
[https://github.com/leonelquinteros/gotext/pull/68](https://togithub.com/leonelquinteros/gotext/pull/68)
- Runtime translation detection by
[@&#8203;m-horky](https://togithub.com/m-horky) in
[https://github.com/leonelquinteros/gotext/pull/69](https://togithub.com/leonelquinteros/gotext/pull/69)
- feat: Add language getter for Locale by
[@&#8203;taozhou-glean](https://togithub.com/taozhou-glean) in
[https://github.com/leonelquinteros/gotext/pull/77](https://togithub.com/leonelquinteros/gotext/pull/77)
- Allow setting global storage by
[@&#8203;didrocks](https://togithub.com/didrocks) in
[https://github.com/leonelquinteros/gotext/pull/80](https://togithub.com/leonelquinteros/gotext/pull/80)
- Fix multiline export by
[@&#8203;didrocks](https://togithub.com/didrocks) in
[https://github.com/leonelquinteros/gotext/pull/82](https://togithub.com/leonelquinteros/gotext/pull/82)
- Order locations in ascii order by
[@&#8203;didrocks](https://togithub.com/didrocks) in
[https://github.com/leonelquinteros/gotext/pull/83](https://togithub.com/leonelquinteros/gotext/pull/83)
- Fix io/fs File leak by
[@&#8203;diamondburned](https://togithub.com/diamondburned) in
[https://github.com/leonelquinteros/gotext/pull/79](https://togithub.com/leonelquinteros/gotext/pull/79)
- Add support for multiple languages by
[@&#8203;m-horky](https://togithub.com/m-horky) in
[https://github.com/leonelquinteros/gotext/pull/73](https://togithub.com/leonelquinteros/gotext/pull/73)
- Revert "Add support for multiple languages" by
[@&#8203;leonelquinteros](https://togithub.com/leonelquinteros) in
[https://github.com/leonelquinteros/gotext/pull/84](https://togithub.com/leonelquinteros/gotext/pull/84)
- Remove unused dependency by
[@&#8203;der-lyse](https://togithub.com/der-lyse) in
[https://github.com/leonelquinteros/gotext/pull/86](https://togithub.com/leonelquinteros/gotext/pull/86)
- Fix typo in documentation by
[@&#8203;der-lyse](https://togithub.com/der-lyse) in
[https://github.com/leonelquinteros/gotext/pull/87](https://togithub.com/leonelquinteros/gotext/pull/87)
- Add support for multiple languages by
[@&#8203;m-horky](https://togithub.com/m-horky) in
[https://github.com/leonelquinteros/gotext/pull/85](https://togithub.com/leonelquinteros/gotext/pull/85)

#### New Contributors

- [@&#8203;kobergj](https://togithub.com/kobergj) made their first
contribution in
[https://github.com/leonelquinteros/gotext/pull/68](https://togithub.com/leonelquinteros/gotext/pull/68)
- [@&#8203;m-horky](https://togithub.com/m-horky) made their first
contribution in
[https://github.com/leonelquinteros/gotext/pull/69](https://togithub.com/leonelquinteros/gotext/pull/69)
- [@&#8203;taozhou-glean](https://togithub.com/taozhou-glean) made their
first contribution in
[https://github.com/leonelquinteros/gotext/pull/77](https://togithub.com/leonelquinteros/gotext/pull/77)
- [@&#8203;didrocks](https://togithub.com/didrocks) made their first
contribution in
[https://github.com/leonelquinteros/gotext/pull/80](https://togithub.com/leonelquinteros/gotext/pull/80)
- [@&#8203;diamondburned](https://togithub.com/diamondburned) made their
first contribution in
[https://github.com/leonelquinteros/gotext/pull/79](https://togithub.com/leonelquinteros/gotext/pull/79)
- [@&#8203;der-lyse](https://togithub.com/der-lyse) made their first
contribution in
[https://github.com/leonelquinteros/gotext/pull/86](https://togithub.com/leonelquinteros/gotext/pull/86)

**Full Changelog**:
leonelquinteros/gotext@v1.5.2...v1.6.0

</details>

---

### Configuration

📅 **Schedule**: Branch creation - "before 6am on Monday" in timezone
Europe/Paris, Automerge - At any time (no schedule defined).

🚦 **Automerge**: Disabled by config. Please merge this manually once you
are satisfied.

♻ **Rebasing**: Whenever PR becomes conflicted, or you tick the
rebase/retry checkbox.

🔕 **Ignore**: Close this PR and you won't be reminded about this update
again.

---

- [ ] <!-- rebase-check -->If you want to rebase/retry this PR, check
this box

---

This PR has been generated by [Mend
Renovate](https://www.mend.io/free-developer-tools/renovate/). View
repository job log
[here](https://developer.mend.io/github/cozy/cozy-stack).

<!--renovate-debug:eyJjcmVhdGVkSW5WZXIiOiIzNy4yOTMuMCIsInVwZGF0ZWRJblZlciI6IjM3LjI5My4wIiwidGFyZ2V0QnJhbmNoIjoibWFzdGVyIiwibGFiZWxzIjpbXX0=-->
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants