Skip to content

Cldr.AcceptLanguage.best_match not returning nearest locale #263

@hugomorg

Description

@hugomorg

Hi @kipcole9. First of all, thanks for the great lib!

We are using cldr for matching "accept-language" headers to locales which we support, so that we can translate content properly (via gettext), specifically, the best match function.

The issue we are facing is that some locales which we do not support, are not falling back to nearest locales. For example, given that we support "es_ES", "en_US", "zh_CN", "zh_HK":

gettext_locale_name = fn locale ->
  {:ok, tag} = MyApp.Cldr.AcceptLanguage.best_match(locale)
  tag.gettext_locale_name
end

iex> gettext_locale_name.("es-ES")
"es_ES"

iex> gettext_locale_name.("es-US")
nil # should be "es_ES"

iex> gettext_locale_name.("en-AU")
"en" # should be "en_US"

iex> gettext_locale_name.("zh-Hans")
"zh_CN"

iex> gettext_locale_name.("zh-Hant")
nil # should be "zh_HK"

I couldn't find a function in cldr which improves on this.

A workaround is stripping off the variant suffix and going through the function again with the top level language, e.g. "es". Alternatively for Chinese variants we can look at the script. But wondering if there is a less manual way to do this.

In case we misconfigured something, our config is:

defmodule MyApp.Cldr do
  use Cldr,
    otp_app: :my_app,
    gettext: MyApp.Gettext,
    providers: [],
    locales:
      MyApp.Gettext
      |> Gettext.known_locales()
      |> Enum.map(&String.replace(&1, "_", "-"))
end

Tagging my colleague @andreyuhai

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions