Merge branch 'from/upstream-develop/tusooa/translate-pages' into 'develop'

Translate backend-rendered pages

See merge request pleroma/pleroma!3634
This commit is contained in:
Haelwenn 2022-03-20 18:14:37 +00:00
commit d7c53da77a
58 changed files with 3319 additions and 446 deletions

View file

@ -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: %{

View file

@ -9,6 +9,7 @@ defmodule Pleroma.Web.Feed.FeedView do
alias Pleroma.Formatter
alias Pleroma.Object
alias Pleroma.User
alias Pleroma.Web.Gettext
alias Pleroma.Web.MediaProxy
require Pleroma.Constants

View file

@ -25,4 +25,181 @@ 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
def normalize_locale(locale) do
if is_binary(locale) do
String.replace(locale, "-", "_", global: true)
else
nil
end
end
def supports_locale?(locale) do
Pleroma.Web.Gettext
|> Gettext.known_locales()
|> Enum.member?(locale)
end
def variant?(locale), do: String.contains?(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) ->
[]
variant?(locale) ->
lang = language_for_variant(locale)
if supports_locale?(lang), do: [lang], else: []
true ->
Gettext.known_locales(Pleroma.Web.Gettext)
|> Enum.filter(fn l -> String.starts_with?(l, locale <> "_") end)
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
else
Gettext.get_locale()
end
end
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})
Process.delete(Gettext)
end
end
end
defmacro with_locales(locales, do: fun) do
quote do
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
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

View file

@ -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, Pleroma.Web.Gettext.normalize_locale(params[:language]))
# What happens here:
#

View file

@ -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
%{

View file

@ -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

View file

@ -6,18 +6,56 @@
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
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_accept_language()
|> Enum.find(&supported_locale?/1)
|> extract_preferred_language()
|> normalize_language_codes()
|> all_supported()
|> Enum.uniq()
end
defp all_supported(locales) do
locales
|> Pleroma.Web.Gettext.ensure_fallbacks()
|> Enum.filter(&supported_locale?/1)
end
defp normalize_language_codes(codes) do
codes
|> Enum.map(fn code -> Pleroma.Web.Gettext.normalize_locale(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 ->
String.split(fe_lang, ",")
end
end
defp extract_accept_language(conn) do
@ -29,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()
_ ->
[]
@ -37,9 +74,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
@ -53,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

View file

@ -160,7 +160,7 @@
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;line-height: 14px; color: <%= @styling.header_color %>;">
<p style="line-height: 36px; text-align: center; margin: 0;"><span
style="font-size: 30px; color: <%= @styling.header_color %>;">Hey <%= @user.nickname %>, here is what you've missed!</span></p>
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) %></span></p>
</div>
</div>
<!--[if mso]></td></tr></table><![endif]-->
@ -382,7 +382,7 @@
<div
style="font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; font-size: 12px; line-height: 14px; color: <%= @styling.text_color %>;">
<p style="font-size: 12px; line-height: 24px; text-align: center; margin: 0;"><span
style="font-size: 20px;"><%= length(@followers) %> New Followers</span><span
style="font-size: 20px;"><%= Gettext.dpngettext("static_pages", "new followers count header", "%{count} New Follower", "%{count} New Followers", length(@followers), count: length(@followers)) %></span><span
style="font-size: 20px; line-height: 24px;"></span></p>
</div>
</div>
@ -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;">
<p
style="font-size: 12px; line-height: 16px; text-align: center; color: <%= @styling.text_color %>; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0;">
<span style="font-size: 14px;">You have received this email because you have signed up to receive digest emails from <b><%= @instance %></b> Pleroma instance.</span></p>
<span style="font-size: 14px;"><%= raw Gettext.dpgettext("static_pages", "digest email sending reason", "You have received this email because you have signed up to receive digest emails from <b>%{instance}</b> Pleroma instance.", instance: safe_to_string(html_escape(@instance))) %></span></p>
<p
style="font-size: 12px; line-height: 14px; text-align: center; color: <%= @styling.text_color %>; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0;">
 </p>
<p
style="font-size: 12px; line-height: 16px; text-align: center; color: <%= @styling.text_color %>; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0;">
<span style="font-size: 14px;">The email address you are subscribed as is <a href="mailto:<%= @user.email %>" style="color: <%= @styling.link_color %>;text-decoration: none;"><%= @user.email %></a>. </span></p>
<span style="font-size: 14px;"><%= raw Gettext.dpgettext("static_pages", "digest email receiver address", "The email address you are subscribed as is <a href='mailto:%{@user.email}' style='color: %{color};text-decoration: none;'>%{email}</a>. ", color: safe_to_string(html_escape(@styling.link_color)), email: safe_to_string(html_escape(@user.email))) %></span></p>
<p
style="font-size: 12px; line-height: 16px; text-align: center; color: <%= @styling.text_color %>; font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif; margin: 0;">
<span style="font-size: 14px;">To unsubscribe, please go <%= link "here", style: "color: #{@styling.link_color};text-decoration: none;", to: @unsubscribe_link %>.</span></p>
<span style="font-size: 14px;"><%= 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)) %></span></p>
</div>
<!--[if mso]></td></tr></table><![endif]-->
<!--[if (!mso)&(!IE)]><!-->

View file

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom"
<feed xml:lang="<%= Gettext.language_tag() %>" xmlns="http://www.w3.org/2005/Atom"
xmlns:thr="http://purl.org/syndication/thread/1.0"
xmlns:georss="http://www.georss.org/georss"
xmlns:activity="http://activitystrea.ms/spec/1.0/"
@ -12,7 +12,7 @@
<id><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></id>
<title>#<%= @tag %></title>
<subtitle>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</subtitle>
<subtitle><%= 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) %></subtitle>
<logo><%= feed_logo() %></logo>
<updated><%= most_recent_update(@activities) %></updated>
<link rel="self" href="<%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.atom' %>" type="application/atom+xml"/>

View file

@ -4,7 +4,7 @@
<title>#<%= @tag %></title>
<description>These are public toots tagged with #<%= @tag %>. You can interact with them if you have an account anywhere in the fediverse.</description>
<description><%= 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) %></description>
<link><%= '#{Routes.tag_feed_url(@conn, :feed, @tag)}.rss' %></link>
<webfeeds:logo><%= feed_logo() %></webfeeds:logo>
<webfeeds:accentColor>2b90d9</webfeeds:accentColor>

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="<%= Pleroma.Web.Gettext.language_tag() %>">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1,minimal-ui">

View file

@ -1,5 +1,5 @@
<!DOCTYPE html>
<html lang="en">
<html lang="<%= Pleroma.Web.Gettext.language_tag() %>">
<head>
<meta charset="utf-8">
<title><%= @email.subject %></title>
@ -7,4 +7,4 @@
<body>
<%= render @view_module, @view_template, assigns %>
</body>
</html>
</html>

View file

@ -1 +1 @@
<h1>UNSUBSCRIBE FAILURE</h1>
<h1><%= Gettext.dpgettext("static_pages", "mailer unsubscribe failed message", "UNSUBSCRIBE FAILURE") %></h1>

View file

@ -1 +1 @@
<h1>UNSUBSCRIBE SUCCESSFUL</h1>
<h1><%= Gettext.dpgettext("static_pages", "mailer unsubscribe successful message", "UNSUBSCRIBE SUCCESSFUL") %></h1>

View file

@ -5,11 +5,11 @@
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<% end %>
<h2>Two-factor recovery</h2>
<h2><%= Gettext.dpgettext("static_pages", "mfa recover page title", "Two-factor recovery") %></h2>
<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
<div class="input">
<%= 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" %>
</div>
<%= submit "Verify" %>
<%= submit Gettext.dpgettext("static_pages", "mfa recover verify recovery code button", "Verify") %>
<% end %>
<a href="<%= Routes.mfa_path(@conn, :show, %{challenge_type: "totp", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
Enter a two-factor code
<%= Gettext.dpgettext("static_pages", "mfa recover use 2fa code link", "Enter a two-factor code") %>
</a>

View file

@ -5,11 +5,11 @@
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<% end %>
<h2>Two-factor authentication</h2>
<h2><%= Gettext.dpgettext("static_pages", "mfa auth page title", "Two-factor authentication") %></h2>
<%= form_for @conn, Routes.mfa_verify_path(@conn, :verify), [as: "mfa"], fn f -> %>
<div class="input">
<%= 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" %>
</div>
<%= submit "Verify" %>
<%= submit Gettext.dpgettext("static_pages", "mfa auth verify code button", "Verify") %>
<% end %>
<a href="<%= Routes.mfa_path(@conn, :show, %{challenge_type: "recovery", mfa_token: @mfa_token, state: @state, redirect_uri: @redirect_uri}) %>">
Enter a two-factor recovery code
<%= Gettext.dpgettext("static_pages", "mfa auth page use recovery code link", "Enter a two-factor recovery code") %>
</a>

View file

@ -1,5 +1,5 @@
<div class="scopes-input">
<%= 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") %>
<div class="scopes">
<%= 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 %>

View file

@ -1,4 +1,4 @@
<h2>Sign in with external provider</h2>
<h2><%= Gettext.dpgettext("static_pages", "oauth external provider page title", "Sign in with external provider") %></h2>
<%= form_for @conn, Routes.o_auth_path(@conn, :prepare_request), [as: "authorization", method: "get"], fn f -> %>
<div style="display: none">
@ -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 %>

View file

@ -1,2 +1,2 @@
<h1>Successfully authorized</h1>
<h2>Token code is <br><%= @auth.token %></h2>
<h1><%= Gettext.dpgettext("static_pages", "oauth authorized page title", "Successfully authorized") %></h1>
<h2><%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is <br>%{token}", token: safe_to_string(html_escape(@auth.token))) %></h2>

View file

@ -1,2 +1,2 @@
<h1>Authorization exists</h1>
<h2>Access token is <br><%= @token.token %></h2>
<h1><%= Gettext.dpgettext("static_pages", "oauth authorization exists page title", "Authorization exists") %></h1>
<h2><%= raw Gettext.dpgettext("static_pages", "oauth token code message", "Token code is <br>%{token}", token: safe_to_string(html_escape(@token.token))) %></h2>

View file

@ -5,34 +5,34 @@
<p class="alert alert-danger" role="alert"><%= get_flash(@conn, :error) %></p>
<% end %>
<h2>Registration Details</h2>
<h2><%= Gettext.dpgettext("static_pages", "oauth register page title", "Registration Details") %></h2>
<p>If you'd like to register a new account, please provide the details below.</p>
<p><%= Gettext.dpgettext("static_pages", "oauth register page fill form prompt", "If you'd like to register a new account, please provide the details below.") %></p>
<%= form_for @conn, Routes.o_auth_path(@conn, :register), [as: "authorization"], fn f -> %>
<div class="input">
<%= 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" %>
</div>
<div class="input">
<%= 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" %>
</div>
<%= 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" %>
<p>Alternatively, sign in to connect to existing account.</p>
<p><%= Gettext.dpgettext("static_pages", "oauth register page login prompt", "Alternatively, sign in to connect to existing account.") %></p>
<div class="input">
<%= 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" %>
</div>
<div class="input">
<%= label f, :password, "Password" %>
<%= label f, :password, Gettext.dpgettext("static_pages", "oauth register page login password prompt", "Password") %>
<%= password_input f, :password, autocomplete: "password" %>
</div>
<%= 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 %>

View file

@ -20,21 +20,23 @@
<div class="container__content">
<%= if @app do %>
<p>Application <strong><%= @app.client_name %></strong> is requesting access to your account.</p>
<p><%= raw Gettext.dpgettext("static_pages", "oauth authorize message", "Application <strong>%{client_name}</strong> is requesting access to your account.", client_name: safe_to_string(html_escape(@app.client_name))) %></p>
<%= render @view_module, "_scopes.html", Map.merge(assigns, %{form: f}) %>
<% end %>
<%= if @user do %>
<div class="actions">
<a class="button button--cancel" href="/">Cancel</a>
<%= submit "Approve", class: "button--approve" %>
<a class="button button--cancel" href="/">
<%= Gettext.dpgettext("static_pages", "oauth authorize cancel button", "Cancel") %>
</a>
<%= submit Gettext.dpgettext("static_pages", "oauth authorize approve button", "Approve"), class: "button--approve" %>
</div>
<% else %>
<%= if @params["registration"] in ["true", true] do %>
<h3>This is the first time you visit! Please enter your Pleroma handle.</h3>
<p>Choose carefully! You won't be able to change this later. You will be able to change your display name, though.</p>
<h3><%= Gettext.dpgettext("static_pages", "oauth register page title", "This is the first time you visit! Please enter your Pleroma handle.") %></h3>
<p><%= 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.") %></p>
<div class="input">
<%= 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" %>
</div>
<%= hidden_input f, :name, value: @params["name"] %>
@ -42,14 +44,14 @@
<br>
<% else %>
<div class="input">
<%= label f, :name, "Username" %>
<%= label f, :name, Gettext.dpgettext("static_pages", "oauth login username prompt", "Username") %>
<%= text_input f, :name %>
</div>
<div class="input">
<%= label f, :password, "Password" %>
<%= label f, :password, Gettext.dpgettext("static_pages", "oauth login password prompt", "Password") %>
<%= password_input f, :password %>
</div>
<%= submit "Log In" %>
<%= submit Gettext.dpgettext("static_pages", "oauth login button", "Log In") %>
<% end %>
<% end %>
</div>

View file

@ -5,7 +5,7 @@
<form class="pull-right collapse" method="POST" action="<%= Helpers.util_path(@conn, :remote_subscribe) %>">
<input type="hidden" name="nickname" value="<%= @user.nickname %>">
<input type="hidden" name="profile" value="">
<button type="submit" class="collapse">Remote follow</button>
<button type="submit" class="collapse"><%= Gettext.dpgettext("static_pages", "static fe profile page remote follow button", "Remote follow") %></button>
</form>
<%= raw Formatter.emojify(@user.name, @user.emoji) %> |
<%= link "@#{@user.nickname}@#{Endpoint.host()}", to: (@user.uri || @user.ap_id) %>

View file

@ -1 +1 @@
<h2>Invalid Token</h2>
<h2><%= Gettext.dpgettext("static_pages", "password reset invalid token message", "Invalid Token") %></h2>

View file

@ -1,13 +1,13 @@
<h2>Password Reset for <%= @user.nickname %></h2>
<%= form_for @conn, Routes.reset_password_path(@conn, :do_reset), [as: "data"], fn f -> %>
<div class="form-row">
<%= label f, :password, "Password" %>
<%= label f, :password, Gettext.dpgettext("static_pages", "password reset form password prompt", "Password") %>
<%= password_input f, :password %>
</div>
<div class="form-row">
<%= 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 %>
</div>
<%= hidden_input f, :token, value: @token.token %>
<%= submit "Reset" %>
<%= submit Gettext.dpgettext("static_pages", "password reset button", "Reset") %>
<% end %>

View file

@ -1,2 +1,6 @@
<h2>Password reset failed</h2>
<h3><a href="<%= Pleroma.Web.Endpoint.url() %>">Homepage</a></h3>
<h2><%= Gettext.dpgettext("static_pages", "password reset failed message", "Password reset failed") %></h2>
<h3>
<a href="<%= Pleroma.Web.Endpoint.url() %>">
<%= Gettext.dpgettext("static_pages", "password reset failed homepage link", "Homepage") %>
</a>
</h3>

View file

@ -1,2 +1,2 @@
<h2>Password changed!</h2>
<h3><a href="<%= Pleroma.Web.Endpoint.url() %>">Homepage</a></h3>
<h2><%= Gettext.dpgettext("static_pages", "password reset successful message", "Password changed!") %></h2>
<h3><a href="<%= Pleroma.Web.Endpoint.url() %>"><%= Gettext.dpgettext("static_pages", "password reset successful homepage link", "Homepage") %></a></h3>

View file

@ -1,11 +1,11 @@
<%= if @error == :error do %>
<h2>Error fetching user</h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow error", "Error fetching user") %></h2>
<% else %>
<h2>Remote follow</h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remote follow") %></h2>
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
<p><%= @followee.nickname %></p>
<%= 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 %>

View file

@ -1,14 +1,14 @@
<%= if @error do %>
<h2><%= @error %></h2>
<% end %>
<h2>Log in to follow</h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow header, need login", "Log in to follow") %></h2>
<p><%= @followee.nickname %></p>
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
<%= 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" %>
<br>
<%= 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" %>
<br>
<%= hidden_input f, :id, value: @followee.id %>
<%= submit "Authorize" %>
<%= submit Gettext.dpgettext("static_pages", "remote follow authorization button for login", "Authorize") %>
<% end %>

View file

@ -1,13 +1,13 @@
<%= if @error do %>
<h2><%= @error %></h2>
<% end %>
<h2>Two-factor authentication</h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow mfa header", "Two-factor authentication") %></h2>
<p><%= @followee.nickname %></p>
<img height="128" width="128" src="<%= avatar_url(@followee) %>">
<%= 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 %>
<br>
<%= 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 %>

View file

@ -1,6 +1,5 @@
<%= if @error do %>
<p>Error following account</p>
<p><%= Gettext.dpgettext("static_pages", "remote follow error", "Error following account") %></p>
<% else %>
<h2>Account followed!</h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow success", "Account followed!") %></h2>
<% end %>

View file

@ -1,10 +1,10 @@
<%= if @error do %>
<h2>Error: <%= @error %></h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow error", "Error: %{error}", error: @error) %></h2>
<% else %>
<h2>Remotely follow <%= @nickname %></h2>
<h2><%= Gettext.dpgettext("static_pages", "remote follow header", "Remotely follow %{nickname}", nickname: @nickname) %></h2>
<%= 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 %>

View file

@ -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)

View file

@ -5,4 +5,5 @@
defmodule Pleroma.Web.TwitterAPI.PasswordView do
use Pleroma.Web, :view
import Phoenix.HTML.Form
alias Pleroma.Web.Gettext
end

View file

@ -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

View file

@ -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
"""

View file

@ -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)

View file

@ -4,4 +4,5 @@
defmodule Pleroma.Web.Mailer.SubscriptionView do
use Pleroma.Web, :view
alias Pleroma.Web.Gettext
end