1 # Pleroma: A lightweight social networking server
2 # Copyright © 2017-2021 Pleroma Authors <https://pleroma.social/>
3 # SPDX-License-Identifier: AGPL-3.0-only
5 defmodule Pleroma.Web.Gettext do
7 A module providing Internationalization with a gettext-based API.
9 By using [Gettext](https://hexdocs.pm/gettext),
10 your module gains a set of macros for translations, for example:
12 import Pleroma.Web.Gettext
15 gettext "Here is the string to translate"
18 ngettext "Here is the string to translate",
19 "Here are the strings to translate",
22 # Domain-based translation
23 dgettext "errors", "Here is the error message to translate"
25 See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage.
27 use Gettext, otp_app: :pleroma
30 # Naive implementation: HTML lang attribute uses BCP 47, which
31 # uses - as a separator.
32 # https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang
35 |> String.replace("_", "-", global: true)
38 def normalize_locale(locale) do
39 if is_binary(locale) do
40 String.replace(locale, "-", "_", global: true)
46 def supports_locale?(locale) do
48 |> Gettext.known_locales()
49 |> Enum.member?(locale)
52 def variant?(locale), do: String.contains?(locale, "_")
54 def language_for_variant(locale) do
55 Enum.at(String.split(locale, "_"), 0)
58 def ensure_fallbacks(locales) do
60 |> Enum.flat_map(fn locale ->
62 other_supported_variants_of_locale(locale)
63 |> Enum.filter(fn l -> not Enum.member?(locales, l) end)
69 def other_supported_variants_of_locale(locale) do
71 supports_locale?(locale) ->
75 lang = language_for_variant(locale)
76 if supports_locale?(lang), do: [lang], else: []
79 Gettext.known_locales(Pleroma.Web.Gettext)
80 |> Enum.filter(fn l -> String.starts_with?(l, locale <> "_") end)
85 Process.get({Pleroma.Web.Gettext, :locales}, [])
88 def is_locale_list(locales) do
89 Enum.all?(locales, &is_binary/1)
92 def put_locales(locales) do
93 if is_locale_list(locales) do
94 Process.put({Pleroma.Web.Gettext, :locales}, Enum.uniq(locales))
95 Gettext.put_locale(Enum.at(locales, 0, Gettext.get_locale()))
98 {:error, :not_locale_list}
102 def locale_or_default(locale) do
103 if supports_locale?(locale) do
110 def with_locales_func(locales, fun) do
111 prev_locales = Process.get({Pleroma.Web.Gettext, :locales})
118 put_locales(prev_locales)
120 Process.delete({Pleroma.Web.Gettext, :locales})
125 defmacro with_locales(locales, do: fun) do
127 Pleroma.Web.Gettext.with_locales_func(unquote(locales), fn ->
133 def to_locale_list(locale) when is_binary(locale) do
136 |> Enum.filter(&supports_locale?/1)
139 def to_locale_list(_), do: []
141 defmacro with_locale_or_default(locale, do: fun) do
143 Pleroma.Web.Gettext.with_locales_func(
144 Pleroma.Web.Gettext.to_locale_list(unquote(locale))
145 |> Enum.concat(Pleroma.Web.Gettext.get_locales()),