From 0fd3695b9c884cbc05f07c45249eb0e291cf6d1d Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 21 Feb 2022 17:54:18 -0500 Subject: Prefer userLanguage cookie over Accept-Language header in detecting locale https://git.pleroma.social/pleroma/pleroma-meta/-/issues/60 --- lib/pleroma/web/plugs/set_locale_plug.ex | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index d77191cff..446baf24b 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -6,6 +6,8 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do import Plug.Conn, only: [get_req_header: 2, assign: 3] + def frontend_language_cookie_name(), do: "userLanguage" + def init(_), do: nil def call(conn, _) do @@ -16,10 +18,35 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do defp get_locale_from_header(conn) do conn - |> extract_accept_language() + |> extract_preferred_language() + |> normalize_language_codes() |> Enum.find(&supported_locale?/1) end + defp normalize_language_codes(codes) do + codes + |> Enum.map(fn code -> String.replace(code, "-", "_") end) + end + + defp extract_preferred_language(conn) do + extract_frontend_language(conn) ++ extract_accept_language(conn) + end + + defp extract_frontend_language(conn) do + %{req_cookies: cookies} = + conn + |> Plug.Conn.fetch_cookies() + + case cookies[frontend_language_cookie_name()] do + nil -> + [] + + fe_lang -> + [fe_lang] + |> ensure_language_fallbacks() + end + end + defp extract_accept_language(conn) do case get_req_header(conn, "accept-language") do [value | _] -> -- cgit v1.2.3 From a8671074375842463ca2f848855db3414cd49105 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 21 Feb 2022 18:42:25 -0500 Subject: Make remote follow pages translatable --- .../web/templates/twitter_api/remote_follow/follow.html.eex | 6 +++--- .../web/templates/twitter_api/remote_follow/follow_login.html.eex | 8 ++++---- .../web/templates/twitter_api/remote_follow/follow_mfa.html.eex | 6 +++--- .../web/templates/twitter_api/remote_follow/followed.html.eex | 5 ++--- lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex | 8 ++++---- lib/pleroma/web/twitter_api/views/remote_follow_view.ex | 1 + lib/pleroma/web/twitter_api/views/util_view.ex | 1 + 7 files changed, 18 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex index a7be53091..e2d251fac 100644 --- a/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex +++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow.html.eex @@ -1,11 +1,11 @@ <%= if @error == :error do %> -

Error fetching user

+

<%= Gettext.dpgettext("static_pages", "remote follow error", "Error fetching user") %>

<% else %> -

Remote follow

+

<%= Gettext.dpgettext("static_pages", "remote follow header", "Remote follow") %>

<%= @followee.nickname %>

<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "user"], fn f -> %> <%= hidden_input f, :id, value: @followee.id %> - <%= submit "Authorize" %> + <%= submit Gettext.dpgettext("static_pages", "remote follow authorization button", "Authorize") %> <% end %> <% end %> diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex index bc5fb28e3..26340a906 100644 --- a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex +++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_login.html.eex @@ -1,14 +1,14 @@ <%= if @error do %>

<%= @error %>

<% end %> -

Log in to follow

+

<%= Gettext.dpgettext("static_pages", "remote follow header, need login", "Log in to follow") %>

<%= @followee.nickname %>

<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "authorization"], fn f -> %> -<%= text_input f, :name, placeholder: "Username", required: true, autocomplete: "username" %> +<%= text_input f, :name, placeholder: Gettext.dpgettext("static_pages", "placeholder text for username entry", "Username"), required: true, autocomplete: "username" %>
-<%= password_input f, :password, placeholder: "Password", required: true, autocomplete: "password" %> +<%= password_input f, :password, placeholder: Gettext.dpgettext("static_pages", "placeholder text for password entry", "Password"), required: true, autocomplete: "password" %>
<%= hidden_input f, :id, value: @followee.id %> -<%= submit "Authorize" %> +<%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for login", "Authorize") %> <% end %> diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex index a54ed83b5..638212c1e 100644 --- a/lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex +++ b/lib/pleroma/web/templates/twitter_api/remote_follow/follow_mfa.html.eex @@ -1,13 +1,13 @@ <%= if @error do %>

<%= @error %>

<% end %> -

Two-factor authentication

+

<%= Gettext.dpgettext("static_pages", "remote follow mfa header", "Two-factor authentication") %>

<%= @followee.nickname %>

<%= form_for @conn, Routes.remote_follow_path(@conn, :do_follow), [as: "mfa"], fn f -> %> -<%= text_input f, :code, placeholder: "Authentication code", required: true %> +<%= text_input f, :code, placeholder: Gettext.dpgettext("static_pages", "placeholder text for auth code entry", "Authentication code"), required: true %>
<%= hidden_input f, :id, value: @followee.id %> <%= hidden_input f, :token, value: @mfa_token %> -<%= submit "Authorize" %> +<%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for mfa", "Authorize") %> <% end %> diff --git a/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex index da473d502..2fb4cc5d3 100644 --- a/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex +++ b/lib/pleroma/web/templates/twitter_api/remote_follow/followed.html.eex @@ -1,6 +1,5 @@ <%= if @error do %> -

Error following account

+

<%= Gettext.dpgettext("static_pages", "remote follow error", "Error following account") %>

<% else %> -

Account followed!

+

<%= Gettext.dpgettext("static_pages", "remote follow success", "Account followed!") %>

<% end %> - diff --git a/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex b/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex index a6b313d8a..848660f26 100644 --- a/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex +++ b/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex @@ -1,10 +1,10 @@ <%= if @error do %> -

Error: <%= @error %>

+

<%= Gettext.dpgettext("static_pages", "remote follow error", "Error: %{error}", error: @error) %>

<% else %> -

Remotely follow <%= @nickname %>

+

<%= Gettext.dpgettext("static_pages", "remote follow header", "Remotely follow %{nickname}", nickname: @nickname) %>

<%= form_for @conn, Routes.util_path(@conn, :remote_subscribe), [as: "user"], fn f -> %> <%= hidden_input f, :nickname, value: @nickname %> - <%= text_input f, :profile, placeholder: "Your account ID, e.g. lain@quitter.se" %> - <%= submit "Follow" %> + <%= text_input f, :profile, placeholder: Gettext.dpgettext("static_pages", "placeholder text for account id", "Your account ID, e.g. lain@quitter.se") %> + <%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for following with a remote account", "Follow") %> <% end %> <% end %> diff --git a/lib/pleroma/web/twitter_api/views/remote_follow_view.ex b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex index ac3f15eec..618ba2ba5 100644 --- a/lib/pleroma/web/twitter_api/views/remote_follow_view.ex +++ b/lib/pleroma/web/twitter_api/views/remote_follow_view.ex @@ -5,6 +5,7 @@ defmodule Pleroma.Web.TwitterAPI.RemoteFollowView do use Pleroma.Web, :view import Phoenix.HTML.Form + alias Pleroma.Web.Gettext defdelegate avatar_url(user), to: Pleroma.User end diff --git a/lib/pleroma/web/twitter_api/views/util_view.ex b/lib/pleroma/web/twitter_api/views/util_view.ex index 87cb79dd7..a03020290 100644 --- a/lib/pleroma/web/twitter_api/views/util_view.ex +++ b/lib/pleroma/web/twitter_api/views/util_view.ex @@ -7,6 +7,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilView do import Phoenix.HTML.Form alias Pleroma.Config alias Pleroma.Web.Endpoint + alias Pleroma.Web.Gettext def status_net_config(instance) do """ -- cgit v1.2.3 From 9f4c5743e842591b78744d4effae86cde4485d31 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 21 Feb 2022 19:12:32 -0500 Subject: Make lint happy --- lib/pleroma/web/plugs/set_locale_plug.ex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index 446baf24b..a9387ba7e 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -6,7 +6,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do import Plug.Conn, only: [get_req_header: 2, assign: 3] - def frontend_language_cookie_name(), do: "userLanguage" + def frontend_language_cookie_name, do: "userLanguage" def init(_), do: nil -- cgit v1.2.3 From 1edbda39e15b3861229283806dcbbf637f9cd753 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 01:04:04 -0500 Subject: Make password reset pages translatable --- .../web/templates/twitter_api/password/invalid_token.html.eex | 2 +- lib/pleroma/web/templates/twitter_api/password/reset.html.eex | 6 +++--- .../web/templates/twitter_api/password/reset_failed.html.eex | 8 ++++++-- .../web/templates/twitter_api/password/reset_success.html.eex | 4 ++-- lib/pleroma/web/twitter_api/views/password_view.ex | 1 + 5 files changed, 13 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex b/lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex index ee84750c7..5ac0aa4e0 100644 --- a/lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex +++ b/lib/pleroma/web/templates/twitter_api/password/invalid_token.html.eex @@ -1 +1 @@ -

Invalid Token

+

<%= Gettext.dpgettext("static_pages", "password reset invalid token message", "Invalid Token") %>

diff --git a/lib/pleroma/web/templates/twitter_api/password/reset.html.eex b/lib/pleroma/web/templates/twitter_api/password/reset.html.eex index fbcacdc14..6a544af51 100644 --- a/lib/pleroma/web/templates/twitter_api/password/reset.html.eex +++ b/lib/pleroma/web/templates/twitter_api/password/reset.html.eex @@ -1,13 +1,13 @@

Password Reset for <%= @user.nickname %>

<%= form_for @conn, Routes.reset_password_path(@conn, :do_reset), [as: "data"], fn f -> %>
- <%= label f, :password, "Password" %> + <%= label f, :password, Gettext.dpgettext("static_pages", "password reset form password prompt", "Password") %> <%= password_input f, :password %>
- <%= label f, :password_confirmation, "Confirmation" %> + <%= label f, :password_confirmation, Gettext.dpgettext("static_pages", "password reset form confirm password prompt", "Confirmation") %> <%= password_input f, :password_confirmation %>
<%= hidden_input f, :token, value: @token.token %> - <%= submit "Reset" %> + <%= submit Gettext.dpgettext("static_pages", "password reset button", "Reset") %> <% end %> diff --git a/lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex b/lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex index 4ed4ac8bc..774e3462a 100644 --- a/lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex +++ b/lib/pleroma/web/templates/twitter_api/password/reset_failed.html.eex @@ -1,2 +1,6 @@ -

Password reset failed

-

Homepage

+

<%= Gettext.dpgettext("static_pages", "password reset failed message", "Password reset failed") %>

+

+ + <%= Gettext.dpgettext("static_pages", "password reset failed homepage link", "Homepage") %> + +

diff --git a/lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex b/lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex index 086d4e08b..40f6bb3fc 100644 --- a/lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex +++ b/lib/pleroma/web/templates/twitter_api/password/reset_success.html.eex @@ -1,2 +1,2 @@ -

Password changed!

-

Homepage

+

<%= Gettext.dpgettext("static_pages", "password reset successful message", "Password changed!") %>

+

<%= Gettext.dpgettext("static_pages", "password reset successful homepage link", "Homepage") %>

diff --git a/lib/pleroma/web/twitter_api/views/password_view.ex b/lib/pleroma/web/twitter_api/views/password_view.ex index a9bb95a2c..40e7fca49 100644 --- a/lib/pleroma/web/twitter_api/views/password_view.ex +++ b/lib/pleroma/web/twitter_api/views/password_view.ex @@ -5,4 +5,5 @@ defmodule Pleroma.Web.TwitterAPI.PasswordView do use Pleroma.Web, :view import Phoenix.HTML.Form + alias Pleroma.Web.Gettext end -- cgit v1.2.3 From 0cc655771642cd840e436a0622e110e69e745338 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 01:13:39 -0500 Subject: Make tag feed translatable --- lib/pleroma/web/feed/feed_view.ex | 1 + lib/pleroma/web/templates/feed/feed/tag.atom.eex | 2 +- lib/pleroma/web/templates/feed/feed/tag.rss.eex | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index c0fb35e01..d674bc26f 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -10,6 +10,7 @@ defmodule Pleroma.Web.Feed.FeedView do alias Pleroma.Object alias Pleroma.User alias Pleroma.Web.MediaProxy + alias Pleroma.Web.Gettext require Pleroma.Constants diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index de0731085..2d860f12b 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -12,7 +12,7 @@ <%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %> #<%= @tag %> - These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse. + <%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %> <%= feed_logo() %> <%= most_recent_update(@activities) %> diff --git a/lib/pleroma/web/templates/feed/feed/tag.rss.eex b/lib/pleroma/web/templates/feed/feed/tag.rss.eex index 9c3613feb..edcc3e436 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.rss.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.rss.eex @@ -4,7 +4,7 @@ #<%= @tag %> - These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse. + <%= Gettext.dpgettext("static_pages", "tag feed description", "These are public toots tagged with #%{tag}. You can interact with them if you have an account anywhere in the fediverse.", tag: @tag) %> <%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %> <%= feed_logo() %> 2b90d9 -- cgit v1.2.3 From f63d9b7835757d28860286f96d22f54196aeb46a Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 01:28:23 -0500 Subject: Use proper lang attributes in htmls --- lib/pleroma/web/gettext.ex | 9 +++++++++ lib/pleroma/web/templates/feed/feed/tag.atom.eex | 2 +- lib/pleroma/web/templates/layout/app.html.eex | 2 +- lib/pleroma/web/templates/layout/email.html.eex | 4 ++-- 4 files changed, 13 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index c0ca4d0e9..c8a739c2b 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -25,4 +25,13 @@ defmodule Pleroma.Web.Gettext do See the [Gettext Docs](https://hexdocs.pm/gettext) for detailed usage. """ use Gettext, otp_app: :pleroma + + def language_tag do + # Naive implementation: HTML lang attribute uses BCP 47, which + # uses - as a separator. + # https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/lang + + Gettext.get_locale() + |> String.replace("_", "-", global: true) + end end diff --git a/lib/pleroma/web/templates/feed/feed/tag.atom.eex b/lib/pleroma/web/templates/feed/feed/tag.atom.eex index 2d860f12b..6d497e84c 100644 --- a/lib/pleroma/web/templates/feed/feed/tag.atom.eex +++ b/lib/pleroma/web/templates/feed/feed/tag.atom.eex @@ -1,6 +1,6 @@ - - + diff --git a/lib/pleroma/web/templates/layout/email.html.eex b/lib/pleroma/web/templates/layout/email.html.eex index f6dcd7f0f..087aa4fc0 100644 --- a/lib/pleroma/web/templates/layout/email.html.eex +++ b/lib/pleroma/web/templates/layout/email.html.eex @@ -1,5 +1,5 @@ - + <%= @email.subject %> @@ -7,4 +7,4 @@ <%= render @view_module, @view_template, assigns %> - \ No newline at end of file + -- cgit v1.2.3 From 50a316cd63c4c4e9462fb64c2f452f6e645840b4 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 02:11:57 -0500 Subject: Make oauth pages translatable --- lib/pleroma/web/o_auth/o_auth_view.ex | 2 ++ .../web/templates/o_auth/o_auth/_scopes.html.eex | 2 +- .../web/templates/o_auth/o_auth/consumer.html.eex | 4 ++-- .../o_auth/o_auth/oob_authorization_created.html.eex | 4 ++-- .../o_auth/o_auth/oob_token_exists.html.eex | 4 ++-- .../web/templates/o_auth/o_auth/register.html.eex | 18 +++++++++--------- .../web/templates/o_auth/o_auth/show.html.eex | 20 +++++++++++--------- 7 files changed, 29 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/o_auth/o_auth_view.ex b/lib/pleroma/web/o_auth/o_auth_view.ex index 1419c96a2..57a315705 100644 --- a/lib/pleroma/web/o_auth/o_auth_view.ex +++ b/lib/pleroma/web/o_auth/o_auth_view.ex @@ -5,6 +5,8 @@ defmodule Pleroma.Web.OAuth.OAuthView do use Pleroma.Web, :view import Phoenix.HTML.Form + import Phoenix.HTML + alias Pleroma.Web.Gettext alias Pleroma.Web.OAuth.Token.Utils diff --git a/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex index c9ec1ecbf..73115e92a 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/_scopes.html.eex @@ -1,5 +1,5 @@
- <%= label @form, :scope, "The following permissions will be granted" %> + <%= label @form, :scope, Gettext.dpgettext("static_pages", "oauth scopes message", "The following permissions will be granted") %>
<%= for scope <- @available_scopes do %> <%# Note: using hidden input with `unchecked_value` in order to distinguish user's empty selection from `scope` param being omitted %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex index dc4521a62..8b894cd58 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/consumer.html.eex @@ -1,4 +1,4 @@ -

Sign in with external provider

+

<%= Gettext.dpgettext("static_pages", "oauth external provider page title", "Sign in with external provider") %>

<%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
@@ -10,6 +10,6 @@ <%= hidden_input f, :state, value: @state %> <%= for strategy <- Pleroma.Config.oauth_consumer_strategies() do %> - <%= submit "Sign in with #{String.capitalize(strategy)}", name: "provider", value: strategy %> + <%= submit Gettext.dpgettext("static_pages", "oauth external provider sign in button", "Sign in with %{strategy}", strategy: String.capitalize(strategy)), name: "provider", value: strategy %> <% end %> <% end %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex index ffabe29a6..aaa38513a 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex @@ -1,2 +1,2 @@ -

Successfully authorized

-

Token code is
<%= @auth.token %>

+

<%= Gettext.dpgettext("static_pages", "oauth authorized page title", "Successfully authorized") %>

+

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: html_escape(@auth.token)) %>

diff --git a/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex index 82785c4b9..de4cd0f34 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex @@ -1,2 +1,2 @@ -

Authorization exists

-

Access token is
<%= @token.token %>

+

<%= Gettext.dpgettext("static_pages", "oauth authorization exists page title", "Authorization exists") %>

+

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: html_escape(@auth.token)) %>

diff --git a/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex index 3ac428b2f..1f661efb2 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/register.html.eex @@ -5,34 +5,34 @@ <% end %> -

Registration Details

+

<%= Gettext.dpgettext("static_pages", "oauth register page title", "Registration Details") %>

-

If you'd like to register a new account, please provide the details below.

+

<%= Gettext.dpgettext("static_pages", "oauth register page fill form prompt", "If you'd like to register a new account, please provide the details below.") %>

<%= form_for @conn, Routes.o_auth_path(@conn, :register), [as: "authorization"], fn f -> %>
- <%= label f, :nickname, "Nickname" %> + <%= label f, :nickname, Gettext.dpgettext("static_pages", "oauth register page nickname prompt", "Nickname") %> <%= text_input f, :nickname, value: @nickname, autocomplete: "username" %>
- <%= label f, :email, "Email" %> + <%= label f, :email, Gettext.dpgettext("static_pages", "oauth register page email prompt", "Email") %> <%= text_input f, :email, value: @email, autocomplete: "email" %>
-<%= submit "Proceed as new user", name: "op", value: "register" %> +<%= submit Gettext.dpgettext("static_pages", "oauth register page register button", "Proceed as new user"), name: "op", value: "register" %> -

Alternatively, sign in to connect to existing account.

+

<%= Gettext.dpgettext("static_pages", "oauth register page login prompt", "Alternatively, sign in to connect to existing account.") %>

- <%= label f, :name, "Name or email" %> + <%= label f, :name, Gettext.dpgettext("static_pages", "oauth register page login username prompt", "Name or email") %> <%= text_input f, :name, autocomplete: "username" %>
- <%= label f, :password, "Password" %> + <%= label f, :password, Gettext.dpgettext("static_pages", "oauth register page login password prompt", "Password") %> <%= password_input f, :password, autocomplete: "password" %>
-<%= submit "Proceed as existing user", name: "op", value: "connect" %> +<%= submit Gettext.dpgettext("static_pages", "oauth register page login button", "Proceed as existing user"), name: "op", value: "connect" %> <%= hidden_input f, :client_id, value: @client_id %> <%= hidden_input f, :redirect_uri, value: @redirect_uri %> diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index d63da6c1d..31ae3cd1b 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -20,21 +20,23 @@
<%= if @app do %> -

Application <%= @app.client_name %> is requesting access to your account.

+

<%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application %{client_name} is requesting access to your account.", client_name: html_escape(@app.client_name)) %>

<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> <% end %> <%= if @user do %>
- Cancel - <%= submit "Approve", class: "button--approve" %> + + <%= Gettext.dpgettext("static_pages", "oauth authorize cancel button", "Cancel") %> + + <%= submit Gettext.dpgettext("static_pages", "oauth authorize approve button", "Approve"), class: "button--approve" %>
<% else %> <%= if @params["registration"] in ["true", true] do %> -

This is the first time you visit! Please enter your Pleroma handle.

-

Choose carefully! You won't be able to change this later. You will be able to change your display name, though.

+

<%= Gettext.dpgettext("static_pages", "oauth register page title", "This is the first time you visit! Please enter your Pleroma handle.") %>

+

<%= Gettext.dpgettext("static_pages", "oauth register nickname unchangeable warning", "Choose carefully! You won't be able to change this later. You will be able to change your display name, though.") %>

- <%= label f, :nickname, "Pleroma Handle" %> + <%= label f, :nickname, Gettext.dpgettext("static_pages", "oauth register nickname prompt", "Pleroma Handle") %> <%= text_input f, :nickname, placeholder: "lain", autocomplete: "username" %>
<%= hidden_input f, :name, value: @params["name"] %> @@ -42,14 +44,14 @@
<% else %>
- <%= label f, :name, "Username" %> + <%= label f, :name, Gettext.dpgettext("static_pages", "oauth login username prompt", "Username") %> <%= text_input f, :name %>
- <%= label f, :password, "Password" %> + <%= label f, :password, Gettext.dpgettext("static_pages", "oauth login password prompt", "Password") %> <%= password_input f, :password %>
- <%= submit "Log In" %> + <%= submit Gettext.dpgettext("static_pages", "oauth login button", "Log In") %> <% end %> <% end %>
-- cgit v1.2.3 From cadca083ea2a12a0e97fbd5e0e4fbae26b5d79a3 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 11:07:28 -0500 Subject: Make mfa pages translatable --- lib/pleroma/web/o_auth/mfa_view.ex | 1 + lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex | 8 ++++---- lib/pleroma/web/templates/o_auth/mfa/totp.html.eex | 8 ++++---- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/o_auth/mfa_view.ex b/lib/pleroma/web/o_auth/mfa_view.ex index 3d473f29c..952c90efe 100644 --- a/lib/pleroma/web/o_auth/mfa_view.ex +++ b/lib/pleroma/web/o_auth/mfa_view.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.OAuth.MFAView do use Pleroma.Web, :view import Phoenix.HTML.Form alias Pleroma.MFA + alias Pleroma.Web.Gettext def render("mfa_response.json", %{token: token, user: user}) do %{ diff --git a/lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex b/lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex index b9daa8d8b..e45d13bdf 100644 --- a/lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex +++ b/lib/pleroma/web/templates/o_auth/mfa/recovery.html.eex @@ -5,11 +5,11 @@ <% end %> -

Two-factor recovery

+

<%= Gettext.dpgettext("static_pages", "mfa recover page title", "Two-factor recovery") %>

<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
- <%= label f, :code, "Recovery code" %> + <%= label f, :code, Gettext.dpgettext("static_pages", "mfa recover recovery code prompt", "Recovery code") %> <%= text_input f, :code, [autocomplete: false, autocorrect: "off", autocapitalize: "off", autofocus: true, spellcheck: false] %> <%= hidden_input f, :mfa_token, value: @mfa_token %> <%= hidden_input f, :state, value: @state %> @@ -17,8 +17,8 @@ <%= hidden_input f, :challenge_type, value: "recovery" %>
-<%= submit "Verify" %> +<%= submit Gettext.dpgettext("static_pages", "mfa recover verify recovery code button", "Verify") %> <% end %> "> - Enter a two-factor code + <%= Gettext.dpgettext("static_pages", "mfa recover use 2fa code link", "Enter a two-factor code") %> diff --git a/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex b/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex index 27600253c..50e6c04b6 100644 --- a/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex +++ b/lib/pleroma/web/templates/o_auth/mfa/totp.html.eex @@ -5,11 +5,11 @@ <% end %> -

Two-factor authentication

+

<%= Gettext.dpgettext("static_pages", "mfa auth page title", "Two-factor authentication") %>

<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
- <%= label f, :code, "Authentication code" %> + <%= label f, :code, Gettext.dpgettext("static_pages", "mfa auth code prompt", "Authentication code") %> <%= text_input f, :code, [autocomplete: "one-time-code", autocorrect: "off", autocapitalize: "off", autofocus: true, pattern: "[0-9]*", spellcheck: false] %> <%= hidden_input f, :mfa_token, value: @mfa_token %> <%= hidden_input f, :state, value: @state %> @@ -17,8 +17,8 @@ <%= hidden_input f, :challenge_type, value: "totp" %>
-<%= submit "Verify" %> +<%= submit Gettext.dpgettext("static_pages", "mfa auth verify code button", "Verify") %> <% end %> "> - Enter a two-factor recovery code + <%= Gettext.dpgettext("static_pages", "mfa auth page use recovery code link", "Enter a two-factor recovery code") %> -- cgit v1.2.3 From fdbf9b06e5672cf6e6038165191fae9bf01bee9f Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 28 Feb 2022 11:23:15 -0500 Subject: Fix tests --- lib/pleroma/web/feed/feed_view.ex | 2 +- .../web/templates/o_auth/o_auth/oob_authorization_created.html.eex | 2 +- lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex | 2 +- lib/pleroma/web/templates/o_auth/o_auth/show.html.eex | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/feed/feed_view.ex b/lib/pleroma/web/feed/feed_view.ex index d674bc26f..52771205e 100644 --- a/lib/pleroma/web/feed/feed_view.ex +++ b/lib/pleroma/web/feed/feed_view.ex @@ -9,8 +9,8 @@ defmodule Pleroma.Web.Feed.FeedView do alias Pleroma.Formatter alias Pleroma.Object alias Pleroma.User - alias Pleroma.Web.MediaProxy alias Pleroma.Web.Gettext + alias Pleroma.Web.MediaProxy require Pleroma.Constants diff --git a/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex index aaa38513a..76ed3fda5 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/oob_authorization_created.html.eex @@ -1,2 +1,2 @@

<%= Gettext.dpgettext("static_pages", "oauth authorized page title", "Successfully authorized") %>

-

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: html_escape(@auth.token)) %>

+

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: safe_to_string(html_escape(@auth.token))) %>

diff --git a/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex index de4cd0f34..754bf2eb0 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/oob_token_exists.html.eex @@ -1,2 +1,2 @@

<%= Gettext.dpgettext("static_pages", "oauth authorization exists page title", "Authorization exists") %>

-

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: html_escape(@auth.token)) %>

+

<%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is
%{token}", token: safe_to_string(html_escape(@token.token))) %>

diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index 31ae3cd1b..a2f41618e 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -20,7 +20,7 @@
<%= if @app do %> -

<%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application %{client_name} is requesting access to your account.", client_name: html_escape(@app.client_name)) %>

+

<%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application %{client_name} is requesting access to your account.", client_name: safe_to_string(html_escape(@app.client_name))) %>

<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %> <% end %> -- cgit v1.2.3 From 32e4aa42d395fceb592b783cdca1268835fe41b5 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 1 Mar 2022 18:48:08 -0500 Subject: Make static fe translatable --- lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex b/lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex index 3191bf450..a14ca305e 100644 --- a/lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex +++ b/lib/pleroma/web/templates/static_fe/static_fe/profile.html.eex @@ -5,7 +5,7 @@
- +
<%= raw Formatter.emojify(@user.name, @user.emoji) %> | <%= link "@#{@user.nickname}@#{Endpoint.host()}", to: (@user.uri || @user.ap_id) %> -- cgit v1.2.3 From 1deab33fb0beee8803d3673f86ae7b0dca8eec80 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 1 Mar 2022 19:17:11 -0500 Subject: Make mail and mailer translatable --- lib/pleroma/web/templates/email/digest.html.eex | 10 +++++----- .../templates/mailer/subscription/unsubscribe_failure.html.eex | 2 +- .../templates/mailer/subscription/unsubscribe_success.html.eex | 2 +- lib/pleroma/web/views/email_view.ex | 1 + lib/pleroma/web/views/mailer/subscription_view.ex | 1 + 5 files changed, 9 insertions(+), 7 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/templates/email/digest.html.eex b/lib/pleroma/web/templates/email/digest.html.eex index 60eceff22..1efc76e1a 100644 --- a/lib/pleroma/web/templates/email/digest.html.eex +++ b/lib/pleroma/web/templates/email/digest.html.eex @@ -160,7 +160,7 @@

Hey <%= @user.nickname %>, here is what you've missed!

+ style="font-size: 30px; color: <%= @styling.header_color %>;"><%= Gettext.dpgettext("static_pages", "digest email header line", "Hey %{nickname}, here is what you've missed!", nickname: @user.nickname) %>

@@ -382,7 +382,7 @@

<%= length(@followers) %> New Followers<%= Gettext.dpngettext("static_pages", "new followers count header", "%{count} New Follower", "%{count} New Followers", length(@followers), count: length(@followers)) %>

@@ -535,16 +535,16 @@ style="color:<%= @styling.text_color %>;font-family:Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height:120%;padding-top:10px;padding-right:10px;padding-bottom:10px;padding-left:10px;">

- You have received this email because you have signed up to receive digest emails from <%= @instance %> Pleroma instance.

+ <%= raw Gettext.dpgettext("static_pages", "digest email sending reason", "You have received this email because you have signed up to receive digest emails from %{instance} Pleroma instance.", instance: safe_to_string(html_escape(@instance))) %>

 

- The email address you are subscribed as is <%= @user.email %>.

+ <%= raw Gettext.dpgettext("static_pages", "digest email receiver address", "The email address you are subscribed as is %{email}. ", color: safe_to_string(html_escape(@styling.link_color)), email: safe_to_string(html_escape(@user.email))) %>

- To unsubscribe, please go <%= link "here", style: "color: #{@styling.link_color};text-decoration: none;", to: @unsubscribe_link %>.

+ <%= raw Gettext.dpgettext("static_pages", "digest email unsubscribe action", "To unsubscribe, please go %{here}.", here: safe_to_string link(Gettext.dpgettext("static_pages", "digest email unsubscribe action link text", "here"), style: "color: #{@styling.link_color};text-decoration: none;", to: @unsubscribe_link)) %>

diff --git a/lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex b/lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex index 7b476f02d..df090ffcd 100644 --- a/lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex +++ b/lib/pleroma/web/templates/mailer/subscription/unsubscribe_failure.html.eex @@ -1 +1 @@ -

UNSUBSCRIBE FAILURE

+

<%= Gettext.dpgettext("static_pages", "mailer unsubscribe failed message", "UNSUBSCRIBE FAILURE") %>

diff --git a/lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex b/lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex index 6dfa2c185..cbce495d4 100644 --- a/lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex +++ b/lib/pleroma/web/templates/mailer/subscription/unsubscribe_success.html.eex @@ -1 +1 @@ -

UNSUBSCRIBE SUCCESSFUL

+

<%= Gettext.dpgettext("static_pages", "mailer unsubscribe successful message", "UNSUBSCRIBE SUCCESSFUL") %>

diff --git a/lib/pleroma/web/views/email_view.ex b/lib/pleroma/web/views/email_view.ex index f7659b994..2ef049d27 100644 --- a/lib/pleroma/web/views/email_view.ex +++ b/lib/pleroma/web/views/email_view.ex @@ -6,6 +6,7 @@ defmodule Pleroma.Web.EmailView do use Pleroma.Web, :view import Phoenix.HTML import Phoenix.HTML.Link + alias Pleroma.Web.Gettext def avatar_url(user) do Pleroma.User.avatar_url(user) diff --git a/lib/pleroma/web/views/mailer/subscription_view.ex b/lib/pleroma/web/views/mailer/subscription_view.ex index 1dc80987b..01e96c61c 100644 --- a/lib/pleroma/web/views/mailer/subscription_view.ex +++ b/lib/pleroma/web/views/mailer/subscription_view.ex @@ -4,4 +4,5 @@ defmodule Pleroma.Web.Mailer.SubscriptionView do use Pleroma.Web, :view + alias Pleroma.Web.Gettext end -- cgit v1.2.3 From af82f09ce39dcc36498549be00f52c530936d0cd Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 1 Mar 2022 20:29:26 -0500 Subject: Make all emails translatable --- lib/pleroma/emails/user_email.ex | 207 +++++++++++++++++++++++++++++++-------- 1 file changed, 164 insertions(+), 43 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex index e38c681ba..cd06ab23c 100644 --- a/lib/pleroma/emails/user_email.ex +++ b/lib/pleroma/emails/user_email.ex @@ -5,9 +5,12 @@ defmodule Pleroma.Emails.UserEmail do @moduledoc "User emails" + require Pleroma.Web.Gettext + alias Pleroma.Config alias Pleroma.User alias Pleroma.Web.Endpoint + alias Pleroma.Web.Gettext alias Pleroma.Web.Router import Swoosh.Email @@ -30,25 +33,64 @@ defmodule Pleroma.Emails.UserEmail do new() |> to(recipient(user)) |> from(Map.get(opts, :sender, sender())) - |> subject(Map.get(opts, :subject, "Welcome to #{instance_name()}!")) - |> html_body(Map.get(opts, :html, "Welcome to #{instance_name()}!")) - |> text_body(Map.get(opts, :text, "Welcome to #{instance_name()}!")) + |> subject( + Map.get( + opts, + :subject, + Gettext.dpgettext("static_pages", "welcome email subject", "Welcome to %{instance_name}!", + instance_name: instance_name() + ) + ) + ) + |> html_body( + Map.get( + opts, + :html, + Gettext.dpgettext( + "static_pages", + "welcome email html body", + "Welcome to %{instance_name}!", + instance_name: instance_name() + ) + ) + ) + |> text_body( + Map.get( + opts, + :text, + Gettext.dpgettext( + "static_pages", + "welcome email text body", + "Welcome to %{instance_name}!", + instance_name: instance_name() + ) + ) + ) end def password_reset_email(user, token) when is_binary(token) do password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token) - html_body = """ -

Reset your password at #{instance_name()}

-

Someone has requested password change for your account at #{instance_name()}.

-

If it was you, visit the following link to proceed: reset password.

-

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

- """ + html_body = + Gettext.dpgettext( + "static_pages", + "password reset email body", + """ +

Reset your password at %{instance_name}

+

Someone has requested password change for your account at %{instance_name}.

+

If it was you, visit the following link to proceed: reset password.

+

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

+ """, + instance_name: instance_name(), + password_reset_url: password_reset_url + ) new() |> to(recipient(user)) |> from(sender()) - |> subject("Password reset") + |> subject( + Gettext.dpgettext("static_pages", "password reset email subject", "Password reset") + ) |> html_body(html_body) end @@ -65,16 +107,31 @@ defmodule Pleroma.Emails.UserEmail do user_invite_token.token ) - html_body = """ -

You are invited to #{instance_name()}

-

#{user.name} invites you to join #{instance_name()}, an instance of Pleroma federated social networking platform.

-

Click the following link to register: accept invitation.

- """ + html_body = + Gettext.dpgettext( + "static_pages", + "user invitation email body", + """ +

You are invited to %{instance_name}

+

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

+

Click the following link to register: accept invitation.

+ """, + instance_name: instance_name(), + inviter_name: user.name, + registration_url: registration_url + ) new() |> to(recipient(to_email, to_name)) |> from(sender()) - |> subject("Invitation to #{instance_name()}") + |> subject( + Gettext.dpgettext( + "static_pages", + "user invitation email subject", + "Invitation to %{instance_name}", + instance_name: instance_name() + ) + ) |> html_body(html_body) end @@ -87,43 +144,83 @@ defmodule Pleroma.Emails.UserEmail do to_string(user.confirmation_token) ) - html_body = """ -

Thank you for registering on #{instance_name()}

-

Email confirmation is required to activate the account.

-

Please click the following link to activate your account.

- """ + html_body = + Gettext.dpgettext( + "static_pages", + "confirmation email body", + """ +

Thank you for registering on %{instance_name}

+

Email confirmation is required to activate the account.

+

Please click the following link to activate your account.

+ """, + instance_name: instance_name(), + confirmation_url: confirmation_url + ) new() |> to(recipient(user)) |> from(sender()) - |> subject("#{instance_name()} account confirmation") + |> subject( + Gettext.dpgettext( + "static_pages", + "confirmation email subject", + "%{instance_name} account confirmation", + instance_name: instance_name() + ) + ) |> html_body(html_body) end def approval_pending_email(user) do - html_body = """ -

Awaiting Approval

-

Your account at #{instance_name()} is being reviewed by staff. You will receive another email once your account is approved.

- """ + html_body = + Gettext.dpgettext( + "static_pages", + "approval pending email body", + """ +

Awaiting Approval

+

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

+ """, + instance_name: instance_name() + ) new() |> to(recipient(user)) |> from(sender()) - |> subject("Your account is awaiting approval") + |> subject( + Gettext.dpgettext( + "static_pages", + "approval pending email subject", + "Your account is awaiting approval" + ) + ) |> html_body(html_body) end def successful_registration_email(user) do - html_body = """ -

Hello @#{user.nickname},

-

Your account at #{instance_name()} has been registered successfully.

-

No further action is required to activate your account.

- """ + html_body = + Gettext.dpgettext( + "static_pages", + "successful registration email body", + """ +

Hello @%{nickname},

+

Your account at %{instance_name} has been registered successfully.

+

No further action is required to activate your account.

+ """, + nickname: user.nickname, + instance_name: instance_name() + ) new() |> to(recipient(user)) |> from(sender()) - |> subject("Account registered on #{instance_name()}") + |> subject( + Gettext.dpgettext( + "static_pages", + "successful registration email subject", + "Account registered on %{instance_name}", + instance_name: instance_name() + ) + ) |> html_body(html_body) end @@ -193,7 +290,14 @@ defmodule Pleroma.Emails.UserEmail do new() |> to(recipient(user)) |> from(sender()) - |> subject("Your digest from #{instance_name()}") + |> subject( + Gettext.dpgettext( + "static_pages", + "digest email subject", + "Your digest from %{instance_name}", + instance_name: instance_name() + ) + ) |> put_layout(false) |> render_body("digest.html", html_data) |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline)) @@ -230,23 +334,40 @@ defmodule Pleroma.Emails.UserEmail do html_body = if is_nil(admin_user_id) do - """ -

You requested a full backup of your Pleroma account. It's ready for download:

-

#{download_url}

- """ + Gettext.dpgettext( + "static_pages", + "account archive email body - self-requested", + """ +

You requested a full backup of your Pleroma account. It's ready for download:

+

%{download_url}

+ """, + download_url: download_url + ) else admin = Pleroma.Repo.get(User, admin_user_id) - """ -

Admin @#{admin.nickname} requested a full backup of your Pleroma account. It's ready for download:

-

#{download_url}

- """ + Gettext.dpgettext( + "static_pages", + "account archive email body - admin requested", + """ +

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

+

%{download_url}

+ """, + admin_nickname: admin.nickname, + download_url: download_url + ) end new() |> to(recipient(user)) |> from(sender()) - |> subject("Your account archive is ready") + |> subject( + Gettext.dpgettext( + "static_pages", + "account archive email subject", + "Your account archive is ready" + ) + ) |> html_body(html_body) end end -- cgit v1.2.3 From 0149ea453868b701d949a5cfee429dfd9d78bb65 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 1 Mar 2022 21:24:17 -0500 Subject: Send emails i18n'd using backend-stored user language --- lib/pleroma/emails/user_email.ex | 534 ++++++++++++++++--------------- lib/pleroma/user.ex | 1 + lib/pleroma/web/gettext.ex | 22 ++ lib/pleroma/web/plugs/set_locale_plug.ex | 4 +- 4 files changed, 301 insertions(+), 260 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/emails/user_email.ex b/lib/pleroma/emails/user_email.ex index cd06ab23c..24adfabd7 100644 --- a/lib/pleroma/emails/user_email.ex +++ b/lib/pleroma/emails/user_email.ex @@ -30,68 +30,75 @@ defmodule Pleroma.Emails.UserEmail do @spec welcome(User.t(), map()) :: Swoosh.Email.t() def welcome(user, opts \\ %{}) do - new() - |> to(recipient(user)) - |> from(Map.get(opts, :sender, sender())) - |> subject( - Map.get( - opts, - :subject, - Gettext.dpgettext("static_pages", "welcome email subject", "Welcome to %{instance_name}!", - instance_name: instance_name() + Gettext.with_locale_or_default user.language do + new() + |> to(recipient(user)) + |> from(Map.get(opts, :sender, sender())) + |> subject( + Map.get( + opts, + :subject, + Gettext.dpgettext( + "static_pages", + "welcome email subject", + "Welcome to %{instance_name}!", + instance_name: instance_name() + ) ) ) - ) - |> html_body( - Map.get( - opts, - :html, - Gettext.dpgettext( - "static_pages", - "welcome email html body", - "Welcome to %{instance_name}!", - instance_name: instance_name() + |> html_body( + Map.get( + opts, + :html, + Gettext.dpgettext( + "static_pages", + "welcome email html body", + "Welcome to %{instance_name}!", + instance_name: instance_name() + ) ) ) - ) - |> text_body( - Map.get( - opts, - :text, - Gettext.dpgettext( - "static_pages", - "welcome email text body", - "Welcome to %{instance_name}!", - instance_name: instance_name() + |> text_body( + Map.get( + opts, + :text, + Gettext.dpgettext( + "static_pages", + "welcome email text body", + "Welcome to %{instance_name}!", + instance_name: instance_name() + ) ) ) - ) + end end def password_reset_email(user, token) when is_binary(token) do - password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token) - - html_body = - Gettext.dpgettext( - "static_pages", - "password reset email body", - """ -

Reset your password at %{instance_name}

-

Someone has requested password change for your account at %{instance_name}.

-

If it was you, visit the following link to proceed: reset password.

-

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

- """, - instance_name: instance_name(), - password_reset_url: password_reset_url - ) + Gettext.with_locale_or_default user.language do + password_reset_url = Router.Helpers.reset_password_url(Endpoint, :reset, token) + + html_body = + Gettext.dpgettext( + "static_pages", + "password reset email body", + """ +

Reset your password at %{instance_name}

+

Someone has requested password change for your account at %{instance_name}.

+

If it was you, visit the following link to proceed: reset password.

+

If it was someone else, nothing to worry about: your data is secure and your password has not been changed.

+ """, + instance_name: instance_name(), + password_reset_url: password_reset_url + ) - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext("static_pages", "password reset email subject", "Password reset") - ) - |> html_body(html_body) + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( + Gettext.dpgettext("static_pages", "password reset email subject", "Password reset") + ) + |> html_body(html_body) + end end def user_invitation_email( @@ -100,128 +107,136 @@ defmodule Pleroma.Emails.UserEmail do to_email, to_name \\ nil ) do - registration_url = - Router.Helpers.redirect_url( - Endpoint, - :registration_page, - user_invite_token.token - ) + Gettext.with_locale_or_default user.language do + registration_url = + Router.Helpers.redirect_url( + Endpoint, + :registration_page, + user_invite_token.token + ) - html_body = - Gettext.dpgettext( - "static_pages", - "user invitation email body", - """ -

You are invited to %{instance_name}

-

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

-

Click the following link to register: accept invitation.

- """, - instance_name: instance_name(), - inviter_name: user.name, - registration_url: registration_url - ) + html_body = + Gettext.dpgettext( + "static_pages", + "user invitation email body", + """ +

You are invited to %{instance_name}

+

%{inviter_name} invites you to join %{instance_name}, an instance of Pleroma federated social networking platform.

+

Click the following link to register: accept invitation.

+ """, + instance_name: instance_name(), + inviter_name: user.name, + registration_url: registration_url + ) - new() - |> to(recipient(to_email, to_name)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "user invitation email subject", - "Invitation to %{instance_name}", - instance_name: instance_name() + new() + |> to(recipient(to_email, to_name)) + |> from(sender()) + |> subject( + Gettext.dpgettext( + "static_pages", + "user invitation email subject", + "Invitation to %{instance_name}", + instance_name: instance_name() + ) ) - ) - |> html_body(html_body) + |> html_body(html_body) + end end def account_confirmation_email(user) do - confirmation_url = - Router.Helpers.confirm_email_url( - Endpoint, - :confirm_email, - user.id, - to_string(user.confirmation_token) - ) + Gettext.with_locale_or_default user.language do + confirmation_url = + Router.Helpers.confirm_email_url( + Endpoint, + :confirm_email, + user.id, + to_string(user.confirmation_token) + ) - html_body = - Gettext.dpgettext( - "static_pages", - "confirmation email body", - """ -

Thank you for registering on %{instance_name}

-

Email confirmation is required to activate the account.

-

Please click the following link to activate your account.

- """, - instance_name: instance_name(), - confirmation_url: confirmation_url - ) + html_body = + Gettext.dpgettext( + "static_pages", + "confirmation email body", + """ +

Thank you for registering on %{instance_name}

+

Email confirmation is required to activate the account.

+

Please click the following link to activate your account.

+ """, + instance_name: instance_name(), + confirmation_url: confirmation_url + ) - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "confirmation email subject", - "%{instance_name} account confirmation", - instance_name: instance_name() + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( + Gettext.dpgettext( + "static_pages", + "confirmation email subject", + "%{instance_name} account confirmation", + instance_name: instance_name() + ) ) - ) - |> html_body(html_body) + |> html_body(html_body) + end end def approval_pending_email(user) do - html_body = - Gettext.dpgettext( - "static_pages", - "approval pending email body", - """ -

Awaiting Approval

-

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

- """, - instance_name: instance_name() - ) + Gettext.with_locale_or_default user.language do + html_body = + Gettext.dpgettext( + "static_pages", + "approval pending email body", + """ +

Awaiting Approval

+

Your account at %{instance_name} is being reviewed by staff. You will receive another email once your account is approved.

+ """, + instance_name: instance_name() + ) - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "approval pending email subject", - "Your account is awaiting approval" + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( + Gettext.dpgettext( + "static_pages", + "approval pending email subject", + "Your account is awaiting approval" + ) ) - ) - |> html_body(html_body) + |> html_body(html_body) + end end def successful_registration_email(user) do - html_body = - Gettext.dpgettext( - "static_pages", - "successful registration email body", - """ -

Hello @%{nickname},

-

Your account at %{instance_name} has been registered successfully.

-

No further action is required to activate your account.

- """, - nickname: user.nickname, - instance_name: instance_name() - ) + Gettext.with_locale_or_default user.language do + html_body = + Gettext.dpgettext( + "static_pages", + "successful registration email body", + """ +

Hello @%{nickname},

+

Your account at %{instance_name} has been registered successfully.

+

No further action is required to activate your account.

+ """, + nickname: user.nickname, + instance_name: instance_name() + ) - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "successful registration email subject", - "Account registered on %{instance_name}", - instance_name: instance_name() + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( + Gettext.dpgettext( + "static_pages", + "successful registration email subject", + "Account registered on %{instance_name}", + instance_name: instance_name() + ) ) - ) - |> html_body(html_body) + |> html_body(html_body) + end end @doc """ @@ -231,76 +246,78 @@ defmodule Pleroma.Emails.UserEmail do """ @spec digest_email(User.t()) :: Swoosh.Email.t() | nil def digest_email(user) do - notifications = Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at) - - mentions = - notifications - |> Enum.filter(&(&1.activity.data["type"] == "Create")) - |> Enum.map(fn notification -> - object = Pleroma.Object.normalize(notification.activity, fetch: false) - - if not is_nil(object) do - object = update_in(object.data["content"], &format_links/1) - - %{ - data: notification, - object: object, - from: User.get_by_ap_id(notification.activity.actor) - } - end - end) - |> Enum.filter(& &1) - - followers = - notifications - |> Enum.filter(&(&1.activity.data["type"] == "Follow")) - |> Enum.map(fn notification -> - from = User.get_by_ap_id(notification.activity.actor) - - if not is_nil(from) do - %{ - data: notification, - object: Pleroma.Object.normalize(notification.activity, fetch: false), - from: User.get_by_ap_id(notification.activity.actor) - } - end - end) - |> Enum.filter(& &1) - - unless Enum.empty?(mentions) do - styling = Config.get([__MODULE__, :styling]) - logo = Config.get([__MODULE__, :logo]) - - html_data = %{ - instance: instance_name(), - user: user, - mentions: mentions, - followers: followers, - unsubscribe_link: unsubscribe_url(user, "digest"), - styling: styling - } - - logo_path = - if is_nil(logo) do - Path.join(:code.priv_dir(:pleroma), "static/static/logo.svg") - else - Path.join(Config.get([:instance, :static_dir]), logo) - end - - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "digest email subject", - "Your digest from %{instance_name}", - instance_name: instance_name() + Gettext.with_locale_or_default user.language do + notifications = Pleroma.Notification.for_user_since(user, user.last_digest_emailed_at) + + mentions = + notifications + |> Enum.filter(&(&1.activity.data["type"] == "Create")) + |> Enum.map(fn notification -> + object = Pleroma.Object.normalize(notification.activity, fetch: false) + + if not is_nil(object) do + object = update_in(object.data["content"], &format_links/1) + + %{ + data: notification, + object: object, + from: User.get_by_ap_id(notification.activity.actor) + } + end + end) + |> Enum.filter(& &1) + + followers = + notifications + |> Enum.filter(&(&1.activity.data["type"] == "Follow")) + |> Enum.map(fn notification -> + from = User.get_by_ap_id(notification.activity.actor) + + if not is_nil(from) do + %{ + data: notification, + object: Pleroma.Object.normalize(notification.activity, fetch: false), + from: User.get_by_ap_id(notification.activity.actor) + } + end + end) + |> Enum.filter(& &1) + + unless Enum.empty?(mentions) do + styling = Config.get([__MODULE__, :styling]) + logo = Config.get([__MODULE__, :logo]) + + html_data = %{ + instance: instance_name(), + user: user, + mentions: mentions, + followers: followers, + unsubscribe_link: unsubscribe_url(user, "digest"), + styling: styling + } + + logo_path = + if is_nil(logo) do + Path.join(:code.priv_dir(:pleroma), "static/static/logo.svg") + else + Path.join(Config.get([:instance, :static_dir]), logo) + end + + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( + Gettext.dpgettext( + "static_pages", + "digest email subject", + "Your digest from %{instance_name}", + instance_name: instance_name() + ) ) - ) - |> put_layout(false) - |> render_body("digest.html", html_data) - |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline)) + |> put_layout(false) + |> render_body("digest.html", html_data) + |> attachment(Swoosh.Attachment.new(logo_path, filename: "logo.svg", type: :inline)) + end end end @@ -330,44 +347,47 @@ defmodule Pleroma.Emails.UserEmail do def backup_is_ready_email(backup, admin_user_id \\ nil) do %{user: user} = Pleroma.Repo.preload(backup, :user) - download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup) - html_body = - if is_nil(admin_user_id) do - Gettext.dpgettext( - "static_pages", - "account archive email body - self-requested", - """ -

You requested a full backup of your Pleroma account. It's ready for download:

-

%{download_url}

- """, - download_url: download_url - ) - else - admin = Pleroma.Repo.get(User, admin_user_id) + Gettext.with_locale_or_default user.language do + download_url = Pleroma.Web.PleromaAPI.BackupView.download_url(backup) + + html_body = + if is_nil(admin_user_id) do + Gettext.dpgettext( + "static_pages", + "account archive email body - self-requested", + """ +

You requested a full backup of your Pleroma account. It's ready for download:

+

%{download_url}

+ """, + download_url: download_url + ) + else + admin = Pleroma.Repo.get(User, admin_user_id) + + Gettext.dpgettext( + "static_pages", + "account archive email body - admin requested", + """ +

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

+

%{download_url}

+ """, + admin_nickname: admin.nickname, + download_url: download_url + ) + end + new() + |> to(recipient(user)) + |> from(sender()) + |> subject( Gettext.dpgettext( "static_pages", - "account archive email body - admin requested", - """ -

Admin @%{admin_nickname} requested a full backup of your Pleroma account. It's ready for download:

-

%{download_url}

- """, - admin_nickname: admin.nickname, - download_url: download_url + "account archive email subject", + "Your account archive is ready" ) - end - - new() - |> to(recipient(user)) - |> from(sender()) - |> subject( - Gettext.dpgettext( - "static_pages", - "account archive email subject", - "Your account archive is ready" ) - ) - |> html_body(html_body) + |> html_body(html_body) + end end end diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 36177bda3..cc8a26b48 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -156,6 +156,7 @@ defmodule Pleroma.User do field(:last_status_at, :naive_datetime) field(:birthday, :date) field(:show_birthday, :boolean, default: false) + field(:language, :string) embeds_one( :notification_settings, diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index c8a739c2b..e85290496 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -34,4 +34,26 @@ defmodule Pleroma.Web.Gettext do Gettext.get_locale() |> String.replace("_", "-", global: true) end + + def supports_locale?(locale) do + Pleroma.Web.Gettext + |> Gettext.known_locales() + |> Enum.member?(locale) + end + + def locale_or_default(locale) do + if supports_locale?(locale) do + locale + else + Gettext.get_locale() + end + end + + defmacro with_locale_or_default(locale, do: fun) do + quote do + Gettext.with_locale(Pleroma.Web.Gettext.locale_or_default(unquote(locale)), fn -> + unquote(fun) + end) + end + end end diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index a9387ba7e..3c3fffa81 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -64,9 +64,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do end defp supported_locale?(locale) do - Pleroma.Web.Gettext - |> Gettext.known_locales() - |> Enum.member?(locale) + Pleroma.Web.Gettext.supports_locale?(locale) end defp parse_language_option(string) do -- cgit v1.2.3 From 396f036b132271ebb0a6a88d28672792528b3b9c Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 2 Mar 2022 00:58:02 -0500 Subject: Allow update_credentials to update User.language --- lib/pleroma/web/mastodon_api/controllers/account_controller.ex | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 8e6d49168..2c97cadc2 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -221,6 +221,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do # Note: param name is indeed :discoverable (not an error) |> Maps.put_if_present(:is_discoverable, params[:discoverable]) |> Maps.put_if_present(:birthday, params[:birthday]) + |> Maps.put_if_present(:language, params[:language]) # What happens here: # -- cgit v1.2.3 From e644f8dea52cb823076f63a18b18c1566c5190b6 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 2 Mar 2022 01:41:13 -0500 Subject: Allow user to register with custom language --- lib/pleroma/user.ex | 3 ++- lib/pleroma/web/api_spec/operations/account_operation.ex | 5 +++++ lib/pleroma/web/gettext.ex | 8 ++++++++ lib/pleroma/web/mastodon_api/controllers/account_controller.ex | 2 +- lib/pleroma/web/plugs/set_locale_plug.ex | 2 +- lib/pleroma/web/twitter_api/twitter_api.ex | 6 ++++++ 6 files changed, 23 insertions(+), 3 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index cc8a26b48..6bce832ea 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -747,7 +747,8 @@ defmodule Pleroma.User do :emoji, :accepts_chat_messages, :registration_reason, - :birthday + :birthday, + :language ]) |> validate_required([:name, :nickname, :password, :password_confirmation]) |> validate_confirmation(:password) diff --git a/lib/pleroma/web/api_spec/operations/account_operation.ex b/lib/pleroma/web/api_spec/operations/account_operation.ex index 03efa3c38..c704ef5d6 100644 --- a/lib/pleroma/web/api_spec/operations/account_operation.ex +++ b/lib/pleroma/web/api_spec/operations/account_operation.ex @@ -549,6 +549,11 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do nullable: true, description: "User's birthday", format: :date + }, + language: %Schema{ + type: :string, + nullable: true, + description: "User's preferred language for emails" } }, example: %{ diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index e85290496..828b98b15 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -35,6 +35,14 @@ defmodule Pleroma.Web.Gettext do |> String.replace("_", "-", global: true) end + def normalize_locale(locale) do + if is_binary(locale) do + String.replace(locale, "-", "_") + else + nil + end + end + def supports_locale?(locale) do Pleroma.Web.Gettext |> Gettext.known_locales() diff --git a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex index 2c97cadc2..e1c68a98e 100644 --- a/lib/pleroma/web/mastodon_api/controllers/account_controller.ex +++ b/lib/pleroma/web/mastodon_api/controllers/account_controller.ex @@ -221,7 +221,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do # Note: param name is indeed :discoverable (not an error) |> Maps.put_if_present(:is_discoverable, params[:discoverable]) |> Maps.put_if_present(:birthday, params[:birthday]) - |> Maps.put_if_present(:language, params[:language]) + |> Maps.put_if_present(:language, Pleroma.Web.Gettext.normalize_locale(params[:language])) # What happens here: # diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index 3c3fffa81..4c6e44fb5 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -25,7 +25,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do defp normalize_language_codes(codes) do codes - |> Enum.map(fn code -> String.replace(code, "-", "_") end) + |> Enum.map(fn code -> Pleroma.Web.Gettext.normalize_locale(code) end) end defp extract_preferred_language(conn) do diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index aa4dfb145..a8a931f2a 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -12,6 +12,8 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do alias Pleroma.UserInviteToken def register_user(params, opts \\ []) do + fallback_language = Gettext.get_locale() + params = params |> Map.take([:email, :token, :password]) @@ -21,6 +23,10 @@ defmodule Pleroma.Web.TwitterAPI.TwitterAPI do |> Map.put(:password_confirmation, params[:password]) |> Map.put(:registration_reason, params[:reason]) |> Map.put(:birthday, params[:birthday]) + |> Map.put( + :language, + Pleroma.Web.Gettext.normalize_locale(params[:language]) || fallback_language + ) if Pleroma.Config.get([:instance, :registrations_open]) do create_user(params, opts) -- cgit v1.2.3 From 8de573b04783ef50b74bd629843a58b37c0ce31d Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 2 Mar 2022 19:59:11 -0500 Subject: Fallback to a variant if the language in general is not supported For an example, here, zh is not supported, but zh_Hans and zh_Hant are. If the user asks for zh, we should choose a variant for them instead of fallbacking to default. Some browsers (e.g. Firefox) does not allow users to customize their language codes. For example, there is no zh-Hans, but only zh, zh-CN, zh-TW, zh-HK, etc. This provides a workaround for those users suffering from bad design decisions. --- lib/pleroma/web/gettext.ex | 14 ++++++++++++++ lib/pleroma/web/plugs/set_locale_plug.ex | 6 ++++++ 2 files changed, 20 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index 828b98b15..cfd92f991 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -49,6 +49,20 @@ defmodule Pleroma.Web.Gettext do |> Enum.member?(locale) end + def variant?(locale), do: String.contains?(locale, "_") + + def supported_variants_of_locale(locale) do + cond do + variant?(locale) -> + [locale] + supports_locale?(locale) -> + [locale] + true -> + Gettext.known_locales(Pleroma.Web.Gettext) + |> Enum.filter(fn l -> String.starts_with?(l, locale <> "_") end) + end + end + def locale_or_default(locale) do if supports_locale?(locale) do locale diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index 4c6e44fb5..78ae566c7 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -20,6 +20,12 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do conn |> extract_preferred_language() |> normalize_language_codes() + |> first_supported() + end + + defp first_supported(locales) do + locales + |> Enum.flat_map(&Pleroma.Web.Gettext.supported_variants_of_locale/1) |> Enum.find(&supported_locale?/1) end -- cgit v1.2.3 From d3f3f30c6a7fae04af27d256d0c2fd90ce03adf0 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 2 Mar 2022 22:56:19 -0500 Subject: Make lint happy --- lib/pleroma/web/gettext.ex | 2 ++ 1 file changed, 2 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index cfd92f991..694ad8ad6 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -55,8 +55,10 @@ defmodule Pleroma.Web.Gettext do cond do variant?(locale) -> [locale] + supports_locale?(locale) -> [locale] + true -> Gettext.known_locales(Pleroma.Web.Gettext) |> Enum.filter(fn l -> String.starts_with?(l, locale <> "_") end) -- cgit v1.2.3 From 7ea330b4fe1c93eb7caba2631e1adf133708fa20 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Thu, 3 Mar 2022 02:03:44 -0500 Subject: Support multiple locales formally elixir gettext current does not fully support fallback to another language [0]. But it might in the future. We adapt it so that all languages in Accept-Language headers are received by Pleroma.Web.Gettext. User.languages is now a comma-separated list. [0]: https://github.com/elixir-gettext/gettext/issues/303 --- lib/pleroma/web/gettext.ex | 57 ++++++++++++++++++++++++++++++-- lib/pleroma/web/plugs/set_locale_plug.ex | 19 +++++++---- 2 files changed, 67 insertions(+), 9 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index 694ad8ad6..e17451c09 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -65,6 +65,24 @@ defmodule Pleroma.Web.Gettext do end end + def get_locales() do + Process.get({Pleroma.Web.Gettext, :locales}, []) + end + + def is_locale_list(locales) do + Enum.all?(locales, &is_binary/1) + end + + def put_locales(locales) do + if is_locale_list(locales) do + Process.put({Pleroma.Web.Gettext, :locales}, Enum.uniq(locales)) + Gettext.put_locale(Enum.at(locales, 0, Gettext.get_locale())) + :ok + else + {:error, :not_locale_list} + end + end + def locale_or_default(locale) do if supports_locale?(locale) do locale @@ -73,11 +91,46 @@ defmodule Pleroma.Web.Gettext do end end - defmacro with_locale_or_default(locale, do: fun) do + def with_locales_func(locales, fun) do + prev_locales = Process.get({Pleroma.Web.Gettext, :locales}) + put_locales(locales) + + try do + fun.() + after + if prev_locales do + put_locales(prev_locales) + else + Process.delete({Pleroma.Web.Gettext, :locales}) + end + end + end + + defmacro with_locales(locales, do: fun) do quote do - Gettext.with_locale(Pleroma.Web.Gettext.locale_or_default(unquote(locale)), fn -> + Pleroma.Web.Gettext.with_locales_func(unquote(locales), fn -> unquote(fun) end) end end + + def to_locale_list(locale) when is_binary(locale) do + locale + |> String.split(",") + |> Enum.filter(&supports_locale?/1) + end + + def to_locale_list(_), do: [] + + defmacro with_locale_or_default(locale, do: fun) do + quote do + Pleroma.Web.Gettext.with_locales_func( + Pleroma.Web.Gettext.to_locale_list(unquote(locale)) + |> Enum.concat(Pleroma.Web.Gettext.get_locales()), + fn -> + unquote(fun) + end + ) + end + end end diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index 78ae566c7..936f65f5d 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -11,22 +11,27 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do def init(_), do: nil def call(conn, _) do - locale = get_locale_from_header(conn) || Gettext.get_locale() - Gettext.put_locale(locale) - assign(conn, :locale, locale) + locales = get_locales_from_header(conn) + first_locale = Enum.at(locales, 0, Gettext.get_locale()) + + Pleroma.Web.Gettext.put_locales(locales) + + conn + |> assign(:locale, first_locale) + |> assign(:locales, locales) end - defp get_locale_from_header(conn) do + defp get_locales_from_header(conn) do conn |> extract_preferred_language() |> normalize_language_codes() - |> first_supported() + |> all_supported() end - defp first_supported(locales) do + defp all_supported(locales) do locales |> Enum.flat_map(&Pleroma.Web.Gettext.supported_variants_of_locale/1) - |> Enum.find(&supported_locale?/1) + |> Enum.filter(&supported_locale?/1) end defp normalize_language_codes(codes) do -- cgit v1.2.3 From aca11fb70ef7d9f4004d6efd10fb39261f476852 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Thu, 3 Mar 2022 02:31:36 -0500 Subject: Support multiple locales from userLanguage cookie --- lib/pleroma/web/gettext.ex | 27 +++++++++++++++++++++------ lib/pleroma/web/plugs/set_locale_plug.ex | 14 +++----------- 2 files changed, 24 insertions(+), 17 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index e17451c09..cd795008d 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -37,7 +37,7 @@ defmodule Pleroma.Web.Gettext do def normalize_locale(locale) do if is_binary(locale) do - String.replace(locale, "-", "_") + String.replace(locale, "-", "_", global: true) else nil end @@ -51,13 +51,28 @@ defmodule Pleroma.Web.Gettext do def variant?(locale), do: String.contains?(locale, "_") - def supported_variants_of_locale(locale) do - cond do - variant?(locale) -> - [locale] + def language_for_variant(locale) do + Enum.at(String.split(locale, "_"), 0) + end + def ensure_fallbacks(locales) do + locales + |> Enum.flat_map(fn locale -> + others = other_supported_variants_of_locale(locale) + |> Enum.filter(fn l -> not Enum.member?(locales, l) end) + + [locale] ++ others + end) + end + + def other_supported_variants_of_locale(locale) do + cond do supports_locale?(locale) -> - [locale] + [] + + variant?(locale) -> + lang = language_for_variant(locale) + if supports_locale?(lang), do: [lang], else: [] true -> Gettext.known_locales(Pleroma.Web.Gettext) diff --git a/lib/pleroma/web/plugs/set_locale_plug.ex b/lib/pleroma/web/plugs/set_locale_plug.ex index 936f65f5d..e78917199 100644 --- a/lib/pleroma/web/plugs/set_locale_plug.ex +++ b/lib/pleroma/web/plugs/set_locale_plug.ex @@ -26,11 +26,12 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do |> extract_preferred_language() |> normalize_language_codes() |> all_supported() + |> Enum.uniq() end defp all_supported(locales) do locales - |> Enum.flat_map(&Pleroma.Web.Gettext.supported_variants_of_locale/1) + |> Pleroma.Web.Gettext.ensure_fallbacks() |> Enum.filter(&supported_locale?/1) end @@ -53,8 +54,7 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do [] fe_lang -> - [fe_lang] - |> ensure_language_fallbacks() + String.split(fe_lang, ",") end end @@ -67,7 +67,6 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do |> Enum.sort(&(&1.quality > &2.quality)) |> Enum.map(& &1.tag) |> Enum.reject(&is_nil/1) - |> ensure_language_fallbacks() _ -> [] @@ -89,11 +88,4 @@ defmodule Pleroma.Web.Plugs.SetLocalePlug do %{tag: captures["tag"], quality: quality} end - - defp ensure_language_fallbacks(tags) do - Enum.flat_map(tags, fn tag -> - [language | _] = String.split(tag, "-") - if Enum.member?(tags, language), do: [tag], else: [tag, language] - end) - end end -- cgit v1.2.3 From cd42e2bed0039ce4939e4c55fb7fcd7cf2568b44 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Thu, 3 Mar 2022 09:40:18 -0500 Subject: Lint --- lib/pleroma/web/gettext.ex | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index cd795008d..89feb0bb3 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -58,7 +58,8 @@ defmodule Pleroma.Web.Gettext do def ensure_fallbacks(locales) do locales |> Enum.flat_map(fn locale -> - others = other_supported_variants_of_locale(locale) + others = + other_supported_variants_of_locale(locale) |> Enum.filter(fn l -> not Enum.member?(locales, l) end) [locale] ++ others @@ -80,7 +81,7 @@ defmodule Pleroma.Web.Gettext do end end - def get_locales() do + def get_locales do Process.get({Pleroma.Web.Gettext, :locales}, []) end -- cgit v1.2.3 From 79ccb6b9998ffffa32ba059c8e97f0f604db81f6 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sun, 6 Mar 2022 11:43:31 -0500 Subject: Support fallbacking to other languages --- lib/pleroma/web/gettext.ex | 53 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+) (limited to 'lib') diff --git a/lib/pleroma/web/gettext.ex b/lib/pleroma/web/gettext.ex index 89feb0bb3..51e56939e 100644 --- a/lib/pleroma/web/gettext.ex +++ b/lib/pleroma/web/gettext.ex @@ -118,6 +118,7 @@ defmodule Pleroma.Web.Gettext do put_locales(prev_locales) else Process.delete({Pleroma.Web.Gettext, :locales}) + Process.delete(Gettext) end end end @@ -149,4 +150,56 @@ defmodule Pleroma.Web.Gettext do ) end end + + defp next_locale(locale, list) do + index = Enum.find_index(list, fn item -> item == locale end) + + if not is_nil(index) do + Enum.at(list, index + 1) + else + nil + end + end + + def handle_missing_translation(locale, domain, msgctxt, msgid, bindings) do + next = next_locale(locale, get_locales()) + + if is_nil(next) do + super(locale, domain, msgctxt, msgid, bindings) + else + {:ok, + Gettext.with_locale(next, fn -> + Gettext.dpgettext(Pleroma.Web.Gettext, domain, msgctxt, msgid, bindings) + end)} + end + end + + def handle_missing_plural_translation( + locale, + domain, + msgctxt, + msgid, + msgid_plural, + n, + bindings + ) do + next = next_locale(locale, get_locales()) + + if is_nil(next) do + super(locale, domain, msgctxt, msgid, msgid_plural, n, bindings) + else + {:ok, + Gettext.with_locale(next, fn -> + Gettext.dpngettext( + Pleroma.Web.Gettext, + domain, + msgctxt, + msgid, + msgid_plural, + n, + bindings + ) + end)} + end + end end -- cgit v1.2.3