From 59f18e1fd2f10b93ac318d2a839aef4ec2d75326 Mon Sep 17 00:00:00 2001 From: Moritz Date: Fri, 4 Jul 2025 00:48:15 +0200 Subject: [PATCH] WIP feat:translation --- Justfile | 4 + config/config.exs | 9 +- lib/mv_web/components/core_components.ex | 33 ++- lib/mv_web/plugs/set_locale.ex | 72 +++++++ lib/mv_web/router.ex | 1 + priv/gettext/backpex.pot | 252 ++++++++++++++++++++++ priv/gettext/de/LC_MESSAGES/backpex.po | 264 +++++++++++++++++++++++ priv/gettext/de/LC_MESSAGES/default.po | 104 +++++++++ priv/gettext/de/LC_MESSAGES/errors.po | 102 +++++++++ priv/gettext/default.pot | 38 ++++ priv/gettext/en/LC_MESSAGES/backpex.po | 252 ++++++++++++++++++++++ priv/gettext/en/LC_MESSAGES/default.po | 38 ++++ 12 files changed, 1163 insertions(+), 6 deletions(-) create mode 100644 lib/mv_web/plugs/set_locale.ex create mode 100644 priv/gettext/backpex.pot create mode 100644 priv/gettext/de/LC_MESSAGES/backpex.po create mode 100644 priv/gettext/de/LC_MESSAGES/default.po create mode 100644 priv/gettext/de/LC_MESSAGES/errors.po create mode 100644 priv/gettext/default.pot create mode 100644 priv/gettext/en/LC_MESSAGES/backpex.po create mode 100644 priv/gettext/en/LC_MESSAGES/default.po diff --git a/Justfile b/Justfile index 8df5e69..1427a99 100644 --- a/Justfile +++ b/Justfile @@ -21,6 +21,10 @@ start-database: build-tailwind: mix tailwind mv +gettext: + mix gettext.extract + mix gettext.merge priv/gettext + ci-dev: lint audit test lint: diff --git a/config/config.exs b/config/config.exs index 3f13773..8276013 100644 --- a/config/config.exs +++ b/config/config.exs @@ -12,7 +12,10 @@ config :mv, generators: [timestamp_type: :utc_datetime] # Backpex configuration -config :backpex, :pubsub_server, Mv.PubSub +config :backpex, + pubsub_server: Mv.PubSub, + translator_function: {MvWeb.CoreComponents, :translate_backpex}, + error_translator_function: {MvWeb.CoreComponents, :translate_error} # Configures the endpoint config :mv, MvWeb.Endpoint, @@ -25,6 +28,10 @@ config :mv, MvWeb.Endpoint, pubsub_server: Mv.PubSub, live_view: [signing_salt: "76NHxpwt"] +# Configures translation +config :gettext, :locales, ["en", "de"] +config :gettext, :default_locale, "de" + # Configures the mailer # # By default it uses the "Local" adapter which stores the emails diff --git a/lib/mv_web/components/core_components.ex b/lib/mv_web/components/core_components.ex index 8a13a2a..893e20f 100644 --- a/lib/mv_web/components/core_components.ex +++ b/lib/mv_web/components/core_components.ex @@ -443,6 +443,7 @@ defmodule MvWeb.CoreComponents do Translates an error message using gettext. """ def translate_error({msg, opts}) do + IO.puts("DEBUG: translate_error called with msg: #{inspect(msg)}, opts: #{inspect(opts)}") # When using gettext, we typically pass the strings we want # to translate as a static argument: # @@ -453,11 +454,15 @@ defmodule MvWeb.CoreComponents do # dynamically, so we need to translate them by calling Gettext # with our gettext backend as first argument. Translations are # available in the errors.po file (as we use the "errors" domain). - if count = opts[:count] do - Gettext.dngettext(MvWeb.Gettext, "errors", msg, msg, count, opts) - else - Gettext.dgettext(MvWeb.Gettext, "errors", msg, opts) - end + result = + if count = opts[:count] do + Gettext.dngettext(MvWeb.Gettext, "errors", msg, msg, count, opts) + else + Gettext.dgettext(MvWeb.Gettext, "errors", msg, opts) + end + + IO.puts("DEBUG: translate_error result: #{inspect(result)}") + result end @doc """ @@ -466,4 +471,22 @@ defmodule MvWeb.CoreComponents do def translate_errors(errors, field) when is_list(errors) do for {^field, {msg, opts}} <- errors, do: translate_error({msg, opts}) end + + @doc """ + Translates Backpex strings using gettext. + """ + def translate_backpex({msg, opts}) do + IO.puts("DEBUG: translate_backpex called with msg: #{inspect(msg)}, opts: #{inspect(opts)}") + + # Use our custom translation module + result = + if count = opts[:count] do + Gettext.dngettext(MvWeb.Gettext, "backpex", msg, msg, count, opts) + else + Gettext.dgettext(MvWeb.Gettext, "backpex", msg, opts) + end + + IO.puts("DEBUG: translate_backpex result: #{inspect(result)}") + result + end end diff --git a/lib/mv_web/plugs/set_locale.ex b/lib/mv_web/plugs/set_locale.ex new file mode 100644 index 0000000..362a528 --- /dev/null +++ b/lib/mv_web/plugs/set_locale.ex @@ -0,0 +1,72 @@ +defmodule MvWeb.Plugs.SetLocale do + @moduledoc """ + Plug to set the locale for the application. + Defaults to German if no locale is specified. + """ + import Plug.Conn + + @supported_locales ["de", "en"] + @default_locale "de" + + def init(_), do: nil + + def call(conn, _) do + case fetch_locale(conn) do + nil -> + # Set default locale if none found + Gettext.put_locale(MvWeb.Gettext, @default_locale) + persist(@default_locale, conn) + + locale -> + # Set and persist locale + IO.inspect(locale, label: "locale") + + Gettext.put_locale(MvWeb.Gettext, locale) + |> persist(conn) + end + end + + defp fetch_locale(conn) do + conn.params["locale"] || + get_session(conn, :locale) || + parse_accept_language(conn) || + @default_locale + end + + defp parse_accept_language(conn) do + case get_req_header(conn, "accept-language") do + [accept_language | _] -> + parse_accept_language_header(accept_language) + + _ -> + nil + end + end + + defp parse_accept_language_header(accept_language) do + accept_language + |> String.split(",") + |> Enum.map(&parse_language_tag/1) + |> Enum.find(&(&1 in @supported_locales)) + end + + defp parse_language_tag(tag) do + tag + |> String.trim() + |> String.split(";") + |> List.first() + |> String.split("-") + |> List.first() + |> String.downcase() + end + + defp persist(locale, conn) do + IO.inspect(locale, label: "persist_locale") + + # Ensure locale is a string before setting cookie + locale_string = to_string(locale) + + put_session(conn, :locale, locale_string) + |> put_resp_cookie("locale", locale_string) + end +end diff --git a/lib/mv_web/router.ex b/lib/mv_web/router.ex index 2cb3b3b..5e80aef 100644 --- a/lib/mv_web/router.ex +++ b/lib/mv_web/router.ex @@ -10,6 +10,7 @@ defmodule MvWeb.Router do plug :protect_from_forgery plug :put_secure_browser_headers plug Backpex.ThemeSelectorPlug + plug MvWeb.Plugs.SetLocale end pipeline :api do diff --git a/priv/gettext/backpex.pot b/priv/gettext/backpex.pot new file mode 100644 index 0000000..d19b663 --- /dev/null +++ b/priv/gettext/backpex.pot @@ -0,0 +1,252 @@ +## This file is a PO Template file. +## +## "msgid"s here are often extracted from source code. +## Add new messages manually only if they're dynamic +## messages that can't be statically extracted. +## +## Run "mix gettext.extract" to bring this file up to +## date. Leave "msgstr"s empty as changing them here has no +## effect: edit them in PO (.po) files instead. +# +msgid "" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "%{count} %{resources} have been deleted successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "%{resource} has been deleted successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "%{resource} has been edited successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "(%{count} total)" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Add entry" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "An error occurred while deleting %{count} %{resources}!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "An error occurred while deleting the %{resource}!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Apply" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete %{count} items?" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete the item?" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Attach %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Choose %{resource} ..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "clear" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Clear %{name} filter" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Close modal" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Delete" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Deselect all" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Detach relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Error in relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Filters" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "From" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Hang in there while we get back on track..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Items %{from} to %{to}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "New %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "New %{resource} has been created successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Next Page" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "No %{resources} found" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "No options found" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "or drag and drop" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Previous Page" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Save" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Save & Continue editing" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Search" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select all" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select all items" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select item with id: %{id}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select options..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "selected" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Show" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Show more" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Something went wrong!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "The item is used elsewhere." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "The items are used elsewhere." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "There are errors in the form." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "To" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Toggle columns" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Toggle metrics" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "too large" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "too many files" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Try a different filter setting or clear all filters." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Try a different search term." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "unacceptable file type" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Unselect %{label}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Upload a file" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "We can't find the internet!" +msgstr "" diff --git a/priv/gettext/de/LC_MESSAGES/backpex.po b/priv/gettext/de/LC_MESSAGES/backpex.po new file mode 100644 index 0000000..e963712 --- /dev/null +++ b/priv/gettext/de/LC_MESSAGES/backpex.po @@ -0,0 +1,264 @@ +# German translations for backpex package. +# +msgid "" +msgstr "" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "%{count} %{resources} have been deleted successfully." +msgstr "%{count} %{resources} wurden erfolgreich gelöscht." + +msgid "%{resource} has been deleted successfully." +msgstr "%{resource} wurde erfolgreich gelöscht." + +msgid "%{resource} has been edited successfully." +msgstr "%{resource} wurde erfolgreich bearbeitet." + +msgid "(%{count} total)" +msgstr "(%{count} gesamt)" + +msgid "Add entry" +msgstr "Eintrag hinzufügen" + +msgid "An error occurred while deleting %{count} %{resources}!" +msgstr "Beim Löschen von %{count} %{resources} ist ein Fehler aufgetreten!" + +msgid "An error occurred while deleting the %{resource}!" +msgstr "Beim Löschen von %{resource} ist ein Fehler aufgetreten!" + +msgid "Apply" +msgstr "Anwenden" + +msgid "Are you sure you want to delete %{count} items?" +msgstr "Sind Sie sicher, dass Sie %{count} Elemente löschen möchten?" + +msgid "Are you sure you want to delete the item?" +msgstr "Sind Sie sicher, dass Sie das Element löschen möchten?" + +msgid "Attach %{resource}" +msgstr "%{resource} anhängen" + +msgid "Attempting to reconnect..." +msgstr "Versuche erneut zu verbinden..." + +msgid "Cancel" +msgstr "Abbrechen" + +msgid "Choose %{resource} ..." +msgstr "%{resource} auswählen ..." + +msgid "clear" +msgstr "löschen" + +msgid "Clear %{name} filter" +msgstr "%{name} Filter löschen" + +msgid "Close modal" +msgstr "Modal schließen" + +msgid "Delete" +msgstr "Löschen" + +msgid "Deselect all" +msgstr "Alle abwählen" + +msgid "Detach relation with index %{index}" +msgstr "Beziehung mit Index %{index} trennen" + +msgid "Edit" +msgstr "Bearbeiten" + +msgid "Edit %{resource}" +msgstr "%{resource} bearbeiten" + +msgid "Edit relation with index %{index}" +msgstr "Beziehung mit Index %{index} bearbeiten" + +msgid "Error in relation with index %{index}" +msgstr "Fehler in Beziehung mit Index %{index}" + +msgid "Filters" +msgstr "Filter" + +msgid "From" +msgstr "Von" + +msgid "Hang in there while we get back on track..." +msgstr "Bleiben Sie dran, während wir wieder auf Kurs kommen..." + +msgid "Items %{from} to %{to}" +msgstr "Elemente %{from} bis %{to}" + +msgid "New %{resource}" +msgstr "Neuer %{resource}" + +msgid "New %{resource} has been created successfully." +msgstr "Neuer %{resource} wurde erfolgreich erstellt." + +msgid "Next Page" +msgstr "Nächste Seite" + +msgid "No %{resources} found" +msgstr "Keine %{resources} gefunden" + +msgid "No options found" +msgstr "Keine Optionen gefunden" + +msgid "or drag and drop" +msgstr "oder ziehen und ablegen" + +msgid "Previous Page" +msgstr "Vorherige Seite" + +msgid "Save" +msgstr "Speichern" + +msgid "Save & Continue editing" +msgstr "Speichern & Weiter bearbeiten" + +msgid "Search" +msgstr "Suchen" + +msgid "Select all" +msgstr "Alle auswählen" + +msgid "Select all items" +msgstr "Alle Elemente auswählen" + +msgid "Select item with id: %{id}" +msgstr "Element mit ID auswählen: %{id}" + +msgid "Select options..." +msgstr "Optionen auswählen..." + +msgid "selected" +msgstr "ausgewählt" + +msgid "Show" +msgstr "Anzeigen" + +msgid "Show more" +msgstr "Mehr anzeigen" + +msgid "Something went wrong!" +msgstr "Etwas ist schiefgelaufen!" + +msgid "The item is used elsewhere." +msgstr "Das Element wird an anderer Stelle verwendet." + +msgid "The items are used elsewhere." +msgstr "Die Elemente werden an anderer Stelle verwendet." + +msgid "There are errors in the form." +msgstr "Es gibt Fehler im Formular." + +msgid "To" +msgstr "Bis" + +msgid "Toggle columns" +msgstr "Spalten umschalten" + +msgid "Toggle metrics" +msgstr "Metriken umschalten" + +msgid "too large" +msgstr "zu groß" + +msgid "too many files" +msgstr "zu viele Dateien" + +msgid "Try a different filter setting or clear all filters." +msgstr "Versuchen Sie eine andere Filtereinstellung oder löschen Sie alle Filter." + +msgid "Try a different search term." +msgstr "Versuchen Sie einen anderen Suchbegriff." + +msgid "unacceptable file type" +msgstr "nicht akzeptierter Dateityp" + +msgid "Unselect %{label}" +msgstr "%{label} abwählen" + +msgid "Upload a file" +msgstr "Datei hochladen" + +msgid "We can't find the internet!" +msgstr "Wir können das Internet nicht finden!" + +msgid "First Name" +msgstr "Vorname" + +msgid "Last Name" +msgstr "Nachname" + +msgid "Email" +msgstr "E-Mail" + +msgid "Phone Number" +msgstr "Telefonnummer" + +msgid "Birth Date" +msgstr "Geburtsdatum" + +msgid "Join Date" +msgstr "Beitrittsdatum" + +msgid "Exit Date" +msgstr "Austrittsdatum" + +msgid "Paid" +msgstr "Bezahlt" + +msgid "Street" +msgstr "Straße" + +msgid "House Number" +msgstr "Hausnummer" + +msgid "Postal Code" +msgstr "Postleitzahl" + +msgid "City" +msgstr "Stadt" + +msgid "Notes" +msgstr "Notizen" + +msgid "Member" +msgstr "Mitglied" + +msgid "Members" +msgstr "Mitglieder" + +msgid "Actions" +msgstr "Aktionen" + +msgid "Loading..." +msgstr "Lädt..." + +msgid "Error" +msgstr "Fehler" + +msgid "Success" +msgstr "Erfolg" + +msgid "Warning" +msgstr "Warnung" + +msgid "Info" +msgstr "Info" + +msgid "Yes" +msgstr "Ja" + +msgid "No" +msgstr "Nein" + +msgid "Are you sure?" +msgstr "Sind Sie sicher?" + +msgid "No results found" +msgstr "Keine Ergebnisse gefunden" + +msgid "Clear" +msgstr "Löschen" diff --git a/priv/gettext/de/LC_MESSAGES/default.po b/priv/gettext/de/LC_MESSAGES/default.po new file mode 100644 index 0000000..a2d8fc2 --- /dev/null +++ b/priv/gettext/de/LC_MESSAGES/default.po @@ -0,0 +1,104 @@ +## "msgid"s in this file come from POT (.pot) files. +### +### Do not add, change, or remove "msgid"s manually here as +### they're tied to the ones in the corresponding POT file +### (with the same domain). +### +### Use "mix gettext.extract --merge" or "mix gettext.merge" +### to merge POT files into PO files. +msgid "" +msgstr "" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/mv_web/components/core_components.ex:339 +#, elixir-autogen, elixir-format +msgid "Actions" +msgstr "Aktionen" + +#: lib/mv_web/components/layouts.ex:84 +#: lib/mv_web/components/layouts.ex:96 +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect" +msgstr "Versuche erneut zu verbinden" + +#: lib/mv_web/components/layouts.ex:91 +#, elixir-autogen, elixir-format +msgid "Something went wrong!" +msgstr "Etwas ist schiefgelaufen!" + +#: lib/mv_web/components/layouts.ex:79 +#, elixir-autogen, elixir-format +msgid "We can't find the internet" +msgstr "Wir können das Internet nicht finden" + +#: lib/mv_web/components/core_components.ex:74 +#, elixir-autogen, elixir-format +msgid "close" +msgstr "schließen" + +#: lib/mv_web/components/layouts.ex:85 +#: lib/mv_web/components/layouts.ex:97 +#, elixir-autogen, elixir-format +msgid "Hang in there while we get back on track" +msgstr "Bleiben Sie dran, während wir wieder auf Kurs kommen" + +#: lib/mv_web/components/layouts.ex:82 +#: lib/mv_web/components/layouts.ex:94 +#, elixir-autogen, elixir-format +msgid "Loading" +msgstr "Lädt" + +#: lib/mv_web/components/layouts.ex:83 +#: lib/mv_web/components/layouts.ex:95 +#, elixir-autogen, elixir-format +msgid "Loading..." +msgstr "Lädt..." + +#: lib/mv_web/components/layouts.ex:80 +#: lib/mv_web/components/layouts.ex:92 +#, elixir-autogen, elixir-format +msgid "Something went wrong" +msgstr "Etwas ist schiefgelaufen" + +#: lib/mv_web/components/layouts.ex:81 +#: lib/mv_web/components/layouts.ex:93 +#, elixir-autogen, elixir-format +msgid "We can't find the internet!" +msgstr "Wir können das Internet nicht finden!" + +#: lib/mv_web/components/layouts.ex:86 +#: lib/mv_web/components/layouts.ex:98 +#, elixir-autogen, elixir-format +msgid "Hang in there while we get back on track..." +msgstr "Bleiben Sie dran, während wir wieder auf Kurs kommen..." + +#: lib/mv_web/components/layouts.ex:87 +#: lib/mv_web/components/layouts.ex:99 +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect..." +msgstr "Versuche erneut zu verbinden..." + +#: lib/mv_web/components/layouts.ex:88 +#: lib/mv_web/components/layouts.ex:100 +#, elixir-autogen, elixir-format +msgid "Error" +msgstr "Fehler" + +#: lib/mv_web/components/layouts.ex:89 +#: lib/mv_web/components/layouts.ex:101 +#, elixir-autogen, elixir-format +msgid "Success" +msgstr "Erfolg" + +#: lib/mv_web/components/layouts.ex:90 +#: lib/mv_web/components/layouts.ex:102 +#, elixir-autogen, elixir-format +msgid "Warning" +msgstr "Warnung" + +#: lib/mv_web/components/layouts.ex:91 +#: lib/mv_web/components/layouts.ex:103 +#, elixir-autogen, elixir-format +msgid "Info" +msgstr "Info" diff --git a/priv/gettext/de/LC_MESSAGES/errors.po b/priv/gettext/de/LC_MESSAGES/errors.po new file mode 100644 index 0000000..c667b49 --- /dev/null +++ b/priv/gettext/de/LC_MESSAGES/errors.po @@ -0,0 +1,102 @@ +## "msgid"s in this file come from POT (.pot) files. +### +### Do not add, change, or remove "msgid"s manually here as +### they're tied to the ones in the corresponding POT file +### (with the same domain). +### +### Use "mix gettext.extract --merge" or "mix gettext.merge" +### to merge POT files into PO files. +msgid "" +msgstr "" +"Language: de\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +msgid "can't be blank" +msgstr "darf nicht leer sein" + +msgid "has already been taken" +msgstr "ist bereits vergeben" + +msgid "is invalid" +msgstr "ist ungültig" + +msgid "must be accepted" +msgstr "muss akzeptiert werden" + +msgid "has invalid format" +msgstr "hat ein ungültiges Format" + +msgid "has an invalid entry" +msgstr "hat einen ungültigen Eintrag" + +msgid "is reserved" +msgstr "ist reserviert" + +msgid "does not match confirmation" +msgstr "stimmt nicht mit der Bestätigung überein" + +msgid "is still associated with this entry" +msgstr "ist noch mit diesem Eintrag verknüpft" + +msgid "are still associated with this entry" +msgstr "sind noch mit diesem Eintrag verknüpft" + +msgid "should have %{count} item(s)" +msgid_plural "should have %{count} item(s)" +msgstr[0] "sollte %{count} Element haben" +msgstr[1] "sollte %{count} Elemente haben" + +msgid "should be %{count} character(s)" +msgid_plural "should be %{count} character(s)" +msgstr[0] "sollte %{count} Zeichen lang sein" +msgstr[1] "sollte %{count} Zeichen lang sein" + +msgid "should be %{count} byte(s)" +msgid_plural "should be %{count} byte(s)" +msgstr[0] "sollte %{count} Byte haben" +msgstr[1] "sollte %{count} Bytes haben" + +msgid "should have at least %{count} item(s)" +msgid_plural "should have at least %{count} item(s)" +msgstr[0] "sollte mindestens %{count} Element haben" +msgstr[1] "sollte mindestens %{count} Elemente haben" + +msgid "should be at least %{count} character(s)" +msgid_plural "should be at least %{count} character(s)" +msgstr[0] "sollte mindestens %{count} Zeichen lang sein" +msgstr[1] "sollte mindestens %{count} Zeichen lang sein" + +msgid "should be at least %{count} byte(s)" +msgid_plural "should be at least %{count} byte(s)" +msgstr[0] "sollte mindestens %{count} Byte haben" +msgstr[1] "sollte mindestens %{count} Bytes haben" + +msgid "should have at most %{count} item(s)" +msgid_plural "should have at most %{count} item(s)" +msgstr[0] "sollte höchstens %{count} Element haben" +msgstr[1] "sollte höchstens %{count} Elemente haben" + +msgid "should be at most %{count} character(s)" +msgid_plural "should be at most %{count} character(s)" +msgstr[0] "sollte höchstens %{count} Zeichen lang sein" +msgstr[1] "sollte höchstens %{count} Zeichen lang sein" + +msgid "should be at most %{count} byte(s)" +msgid_plural "should be at most %{count} byte(s)" +msgstr[0] "sollte höchstens %{count} Byte haben" +msgstr[1] "sollte höchstens %{count} Bytes haben" + +msgid "must be less than %{number}" +msgstr "muss kleiner als %{number} sein" + +msgid "must be greater than %{number}" +msgstr "muss größer als %{number} sein" + +msgid "must be less than or equal to %{number}" +msgstr "muss kleiner oder gleich %{number} sein" + +msgid "must be greater than or equal to %{number}" +msgstr "muss größer oder gleich %{number} sein" + +msgid "must be equal to %{number}" +msgstr "muss gleich %{number} sein" diff --git a/priv/gettext/default.pot b/priv/gettext/default.pot new file mode 100644 index 0000000..e65fc19 --- /dev/null +++ b/priv/gettext/default.pot @@ -0,0 +1,38 @@ +## This file is a PO Template file. +## +## "msgid"s here are often extracted from source code. +## Add new messages manually only if they're dynamic +## messages that can't be statically extracted. +## +## Run "mix gettext.extract" to bring this file up to +## date. Leave "msgstr"s empty as changing them here has no +## effect: edit them in PO (.po) files instead. +# +msgid "" +msgstr "" + +#: lib/mv_web/components/core_components.ex:339 +#, elixir-autogen, elixir-format +msgid "Actions" +msgstr "" + +#: lib/mv_web/components/layouts.ex:84 +#: lib/mv_web/components/layouts.ex:96 +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect" +msgstr "" + +#: lib/mv_web/components/layouts.ex:91 +#, elixir-autogen, elixir-format +msgid "Something went wrong!" +msgstr "" + +#: lib/mv_web/components/layouts.ex:79 +#, elixir-autogen, elixir-format +msgid "We can't find the internet" +msgstr "" + +#: lib/mv_web/components/core_components.ex:74 +#, elixir-autogen, elixir-format +msgid "close" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/backpex.po b/priv/gettext/en/LC_MESSAGES/backpex.po new file mode 100644 index 0000000..621b43f --- /dev/null +++ b/priv/gettext/en/LC_MESSAGES/backpex.po @@ -0,0 +1,252 @@ +## "msgid"s in this file come from POT (.pot) files. +### +### Do not add, change, or remove "msgid"s manually here as +### they're tied to the ones in the corresponding POT file +### (with the same domain). +### +### Use "mix gettext.extract --merge" or "mix gettext.merge" +### to merge POT files into PO files. +msgid "" +msgstr "" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#, elixir-autogen, elixir-format +msgid "%{count} %{resources} have been deleted successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "%{resource} has been deleted successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "%{resource} has been edited successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "(%{count} total)" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Add entry" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "An error occurred while deleting %{count} %{resources}!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "An error occurred while deleting the %{resource}!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Apply" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete %{count} items?" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Are you sure you want to delete the item?" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Attach %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Cancel" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Choose %{resource} ..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "clear" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Clear %{name} filter" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Close modal" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Delete" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Deselect all" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Detach relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Edit relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Error in relation with index %{index}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Filters" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "From" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Hang in there while we get back on track..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Items %{from} to %{to}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "New %{resource}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "New %{resource} has been created successfully." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Next Page" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "No %{resources} found" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "No options found" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "or drag and drop" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Previous Page" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Save" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Save & Continue editing" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Search" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select all" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select all items" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select item with id: %{id}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Select options..." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "selected" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Show" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Show more" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Something went wrong!" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "The item is used elsewhere." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "The items are used elsewhere." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "There are errors in the form." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "To" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Toggle columns" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Toggle metrics" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "too large" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "too many files" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Try a different filter setting or clear all filters." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Try a different search term." +msgstr "" + +#, elixir-autogen, elixir-format +msgid "unacceptable file type" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Unselect %{label}" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "Upload a file" +msgstr "" + +#, elixir-autogen, elixir-format +msgid "We can't find the internet!" +msgstr "" diff --git a/priv/gettext/en/LC_MESSAGES/default.po b/priv/gettext/en/LC_MESSAGES/default.po new file mode 100644 index 0000000..2b15401 --- /dev/null +++ b/priv/gettext/en/LC_MESSAGES/default.po @@ -0,0 +1,38 @@ +## "msgid"s in this file come from POT (.pot) files. +### +### Do not add, change, or remove "msgid"s manually here as +### they're tied to the ones in the corresponding POT file +### (with the same domain). +### +### Use "mix gettext.extract --merge" or "mix gettext.merge" +### to merge POT files into PO files. +msgid "" +msgstr "" +"Language: en\n" +"Plural-Forms: nplurals=2; plural=(n != 1);\n" + +#: lib/mv_web/components/core_components.ex:339 +#, elixir-autogen, elixir-format +msgid "Actions" +msgstr "" + +#: lib/mv_web/components/layouts.ex:84 +#: lib/mv_web/components/layouts.ex:96 +#, elixir-autogen, elixir-format +msgid "Attempting to reconnect" +msgstr "" + +#: lib/mv_web/components/layouts.ex:91 +#, elixir-autogen, elixir-format +msgid "Something went wrong!" +msgstr "" + +#: lib/mv_web/components/layouts.ex:79 +#, elixir-autogen, elixir-format +msgid "We can't find the internet" +msgstr "" + +#: lib/mv_web/components/core_components.ex:74 +#, elixir-autogen, elixir-format +msgid "close" +msgstr ""