View Source MyApp.Cldr.AcceptLanguage (Cldr v2.40.0)

Parses HTTP Accept-Language header values as defined in rfc2616.

The Accept-Language request-header field is similar to Accept, but restricts the set of natural languages that are preferred as a response to the request. Language tags function are provided in Cldr.LanguageTag.

The format of an Accept-Language header is as follows in ABNF format:

   Accept-Language = "Accept-Language" ":"
                     1#( language-range [ ";" "q" "=" qvalue ] )
   language-range  = ( ( 1*8ALPHA *( "-" 1*8ALPHA ) ) | "*" )

Each language-range MAY be given an associated quality value which represents an estimate of the user's preference for the languages specified by that range. The quality value defaults to "q=1". For example,

   Accept-Language: da, en-gb;q=0.8, en;q=0.7

would mean: "I prefer Danish, but will accept British English and other types of English."

Summary

Functions

Parse an Accept-Language string and return the best match for a configured Cldr locale.

Parses an Accept-Language header value in its string or tokenized form to return a tuple of the form {:ok, [{quality, %Cldr.LanguageTag{}}, ...]} sorted by quality.

Parses an Accept-Language header value in its string or tokenized form to produce a list of tuples of the form [{quality, %Cldr.LanguageTag{}}, ...] sorted by quality in descending order.

Functions

Link to this function

best_match(accept_language)

View Source
@spec best_match(String.t()) ::
  {:ok, Cldr.LanguageTag.t()}
  | {:error, {Cldr.AcceptLanguageError | Cldr.NoMatchingLocale, String.t()}}

Parse an Accept-Language string and return the best match for a configured Cldr locale.

Arguments

  • accept_language is a string representing an accept language header

Returns

  • {:ok, language_tag} or

  • {:error, reason}

Examples

iex> MyApp.Cldr.AcceptLanguage.best_match("da;q=0.1,zh-TW;q=0.3", TestBackend.Cldr)
{:ok,
 %Cldr.LanguageTag{
   backend: TestBackend.Cldr,
   canonical_locale_name: "zh-TW",
   cldr_locale_name: :"zh-Hant",
   language_subtags: [],
   extensions: %{},
   gettext_locale_name: nil,
   language: "zh",
   locale: %{},
   private_use: [],
   rbnf_locale_name: :"zh-Hant",
   requested_locale_name: "zh-TW",
   script: :Hant,
   territory: :TW,
   transform: %{},
   language_variants: []
 }}

iex> MyApp.Cldr.AcceptLanguage.best_match("da;q=0.1,zh-TW;q=0.3", TestBackend.Cldr)
{:ok,
 %Cldr.LanguageTag{
   backend: TestBackend.Cldr,
   canonical_locale_name: "zh-TW",
   cldr_locale_name: :"zh-Hant",
   language_subtags: [],
   extensions: %{},
   gettext_locale_name: nil,
   language: "zh",
   locale: %{},
   private_use: [],
   rbnf_locale_name: :"zh-Hant",
   requested_locale_name: "zh-TW",
   script: :Hant,
   territory: :TW,
   transform: %{},
   language_variants: []
 }}

iex> MyApp.Cldr.AcceptLanguage.best_match("xx,yy;q=0.3")
{:error,
 {Cldr.NoMatchingLocale,
  "No configured locale could be matched to \"xx,yy;q=0.3\""}}

iex> MyApp.Cldr.AcceptLanguage.best_match("invalid_tag")
{:error, {Cldr.LanguageTag.ParseError,
  "Expected a BCP47 language tag. Could not parse the remaining \"g\" starting at position 11"}}
Link to this function

parse(tokens_or_string)

View Source (since 2.30.0)
@spec parse([{float(), String.t()}, ...] | String.t()) ::
  {:ok,
   [
     {float(), Cldr.LanguageTag.t()}
     | {:error, {Cldr.InvalidLanguageTag, String.t()}},
     ...
   ]}
  | {:error, {Cldr.AcceptLanguageError, String.t()}}

Parses an Accept-Language header value in its string or tokenized form to return a tuple of the form {:ok, [{quality, %Cldr.LanguageTag{}}, ...]} sorted by quality.

Arguments

  • accept-language is any string in the format defined by rfc2616

  • backend is any module that includes use Cldr and therefore is a Cldr backend module

Returns

  • {:ok, [{quality, language_tag}, ...]} or

  • {:error, {Cldr.AcceptLanguageError, String.t}}

If at least one valid language tag is found but errors are also detected on one more more tags, an {ok, list} tuple is returned with an error tuple for each invalid tag added at the end of the list.

Example

iex> Cldr.AcceptLanguage.parse("da,zh-TW;q=0.3", TestBackend.Cldr)
{:ok,
 [
   {1.0,
    %Cldr.LanguageTag{
      backend: TestBackend.Cldr,
      canonical_locale_name: "da",
      cldr_locale_name: :da,
      language_subtags: [],
      extensions: %{},
      gettext_locale_name: nil,
      language: "da",
      locale: %{},
      private_use: [],
      rbnf_locale_name: :da,
      requested_locale_name: "da",
      script: :Latn,
      territory: :DK,
      transform: %{},
      language_variants: []
    }},
   {0.3,
    %Cldr.LanguageTag{
      backend: TestBackend.Cldr,
      canonical_locale_name: "zh-TW",
      cldr_locale_name: :"zh-Hant",
      language_subtags: [],
      extensions: %{},
      gettext_locale_name: nil,
      language: "zh",
      locale: %{},
      private_use: [],
      rbnf_locale_name: :"zh-Hant",
      requested_locale_name: "zh-TW",
      script: :Hant,
      territory: :TW,
      transform: %{},
      language_variants: []
    }}
 ]}

iex> MyApp.Cldr.AcceptLanguage.parse("invalid_tag")
{:error,
 {Cldr.LanguageTag.ParseError,
  "Expected a BCP47 language tag. Could not parse the remaining \"g\" starting at position 11"}}

iex> MyApp.Cldr.AcceptLanguage.parse("da,zh-TW;q=0.3,invalid_tag")
{:ok,
 [
   {1.0,
    %Cldr.LanguageTag{
      backend: TestBackend.Cldr,
      canonical_locale_name: "da",
      cldr_locale_name: :da,
      language_subtags: [],
      extensions: %{},
      gettext_locale_name: nil,
      language: "da",
      locale: %{},
      private_use: [],
      rbnf_locale_name: :da,
      requested_locale_name: "da",
      script: :Latn,
      territory: :DK,
      transform: %{},
      language_variants: []
    }},
   {0.3,
    %Cldr.LanguageTag{
      backend: TestBackend.Cldr,
      canonical_locale_name: "zh-TW",
      cldr_locale_name: :"zh-Hant",
      language_subtags: [],
      extensions: %{},
      gettext_locale_name: nil,
      language: "zh",
      locale: %{},
      private_use: [],
      rbnf_locale_name: :"zh-Hant",
      requested_locale_name: "zh-TW",
      script: :Hant,
      territory: :TW,
      transform: %{},
      language_variants: []
    }},
   {:error,
    {Cldr.LanguageTag.ParseError,
     "Expected a BCP47 language tag. Could not parse the remaining \"g\" starting at position 11"}}
 ]}

Parses an Accept-Language header value in its string or tokenized form to produce a list of tuples of the form [{quality, %Cldr.LanguageTag{}}, ...] sorted by quality in descending order.

Arguments

  • accept-language is any string in the format defined by rfc2616

Returns

If at least one valid language tag is found but errors are also detected on one more more tags, an {ok, list} tuple is returned with an error tuple for each invalid tag added at the end of the list.

Example

iex> MyApp.Cldr.AcceptLanguage.parse!("da,zh-TW;q=0.3")
[
  {1.0,
   %Cldr.LanguageTag{
     backend: TestBackend.Cldr,
     canonical_locale_name: "da",
     cldr_locale_name: :da,
     language_subtags: [],
     extensions: %{},
     gettext_locale_name: nil,
     language: "da",
     locale: %{},
     private_use: [],
     rbnf_locale_name: :da,
     requested_locale_name: "da",
     script: :Latn,
     territory: :DK,
     transform: %{},
     language_variants: []
   }},
  {0.3,
   %Cldr.LanguageTag{
     backend: TestBackend.Cldr,
     canonical_locale_name: "zh-TW",
     cldr_locale_name: :"zh-Hant",
     language_subtags: [],
     extensions: %{},
     gettext_locale_name: nil,
     language: "zh",
     locale: %{},
     private_use: [],
     rbnf_locale_name: :"zh-Hant",
     requested_locale_name: "zh-TW",
     script: :Hant,
     territory: :TW,
     transform: %{},
     language_variants: []
   }}
]

MyApp.Cldr.AcceptLanguage.parse! "invalid_tag"
** (Cldr.AcceptLanguageError) "Expected a BCP47 language tag. Could not parse the remaining "g" starting at position 11
    (ex_cldr) lib/cldr/accept_language.ex:304: Cldr.AcceptLanguage.parse!/1

iex> MyApp.Cldr.AcceptLanguage.parse!("da,zh-TW;q=0.3,invalid_tag")
[
  {1.0,
   %Cldr.LanguageTag{
     backend: TestBackend.Cldr,
     canonical_locale_name: "da",
     cldr_locale_name: :da,
     language_subtags: [],
     extensions: %{},
     gettext_locale_name: nil,
     language: "da",
     locale: %{},
     private_use: [],
     rbnf_locale_name: :da,
     requested_locale_name: "da",
     script: :Latn,
     territory: :DK,
     transform: %{},
     language_variants: []
   }},
  {0.3,
   %Cldr.LanguageTag{
     backend: TestBackend.Cldr,
     canonical_locale_name: "zh-TW",
     cldr_locale_name: :"zh-Hant",
     language_subtags: [],
     extensions: %{},
     gettext_locale_name: nil,
     language: "zh",
     locale: %{},
     private_use: [],
     rbnf_locale_name: :"zh-Hant",
     requested_locale_name: "zh-TW",
     script: :Hant,
     territory: :TW,
     transform: %{},
     language_variants: []
   }},
  {:error,
   {Cldr.LanguageTag.ParseError,
    "Expected a BCP47 language tag. Could not parse the remaining \"g\" starting at position 11"}}
]