diff --git a/front.go b/front.go index 8ef69b1..0ee8d91 100644 --- a/front.go +++ b/front.go @@ -17,7 +17,6 @@ import ( "github.com/zitadel/oidc/v3/pkg/oidc" "golang.org/x/text/language" "gorm.io/gorm" - "html" "html/template" "io" "log" @@ -69,7 +68,6 @@ func NewTemplate(app *App) *Template { funcMap := template.FuncMap{ "render": RenderHTML, - "html": func(x string) template.HTML { return template.HTML(x) }, "PrimaryPlayerSkinURL": app.PrimaryPlayerSkinURL, "PlayerSkinURL": app.PlayerSkinURL, "InviteURL": app.InviteURL, @@ -161,6 +159,11 @@ func NewWebError(returnURL string, message string, args ...interface{}) error { } func RenderHTML(templateString string, args ...interface{}) (template.HTML, error) { + // If there are no args, skip parsing and return the "template" as-is + if len(args) == 0 { + return template.HTML(templateString), nil + } + t, err := template.New("").Parse(templateString) if err != nil { return "", err @@ -176,7 +179,7 @@ func RenderHTML(templateString string, args ...interface{}) (template.HTML, erro } type baseContext struct { - T func(string, ...interface{}) template.HTML + T func(string, ...interface{}) string App *App L *gotext.Locale URL string @@ -185,24 +188,9 @@ type baseContext struct { ErrorMessage string } -func NewT(l *gotext.Locale) func(string, ...interface{}) template.HTML { - return func(msgid string, args ...interface{}) template.HTML { - sanitized := make([]interface{}, 0, len(args)) - for _, arg := range args { - switch arg.(type) { - case template.HTML: - sanitized = append(sanitized, arg) - default: - sanitized = append(sanitized, html.EscapeString(fmt.Sprint(arg))) - } - } - return template.HTML(l.Get(msgid, sanitized...)) - } -} - func (app *App) NewBaseContext(c *echo.Context) baseContext { l := (*c).Get(CONTEXT_KEY_LOCALE).(*gotext.Locale) - T := NewT((*c).Get(CONTEXT_KEY_LOCALE).(*gotext.Locale)) + T := l.Get return baseContext{ App: app, L: l, diff --git a/locales/es/default.po b/locales/es/default.po deleted file mode 100644 index 15fe35c..0000000 --- a/locales/es/default.po +++ /dev/null @@ -1,212 +0,0 @@ -msgid "" -msgstr "" -"Content-Type: text/plain; charset=UTF-8\n" -"Language: es\n" - -msgid "OpenID logo" -msgstr "Logo de OpenID" - -msgid "Registration" -msgstr "Registro" - -msgid "Register" -msgstr "Registrarse" - -msgid "Admin" -msgstr "Administrador" - -msgid "%s's Account" -msgstr "Cuenta de %s" - -msgid "Log out" -msgstr "Cerrar sesión" - -msgid "Log in" -msgstr "Iniciar sesión" - -msgid "Sign in with %s" -msgstr "Iniciar sesión con %s" - -msgid "or" -msgstr "o" - -msgid "Username" -msgstr "Nombre de usuario" - -msgid "Password" -msgstr "Contraseña" - -msgid "Configuring your client" -msgstr "Configurando tu cliente" - -msgid "Using %s on the client requires a third-party launcher that supports custom API servers. %s, a fork of Prism Launcher, is recommended, but %s also works. Both are free/libre." -msgstr "Usar %s en el cliente requiere un lanzador de terceros que soporte servidores API personalizados. Se recomienda %s, un fork de Prism Launcher, pero %s también funciona. Ambos son libres." - -msgid "Click your account in the top right and select “Manage Accounts...”." -msgstr "Haz clic en tu cuenta en la esquina superior derecha y selecciona “Administrar cuentas...”." - -msgid "Click “Add authlib-injector” in the right-hand sidebar." -msgstr "Haz clic en “Add authlib-injector” en la barra lateral derecha." - -msgid "Enter your player name and your %s password or Minecraft Token, and use %s for the URL. Click “OK”." -msgstr "Introduce tu nombre de jugador y tu contraseña de %s o Token de Minecraft, y usa %s para la URL. Haz clic en “Aceptar”." - -msgid "Go to the “Account List” view by clicking the account at the top of the sidebar." -msgstr "Ve a la vista “Lista de cuentas” haciendo clic en la cuenta en la parte superior de la barra lateral." - -msgid "At the bottom left, click “New Auth Server” and enter %s. Click “Next” and then “Finish”." -msgstr "En la parte inferior izquierda, haz clic en “Añadir un servidor de autenticación” e ingresa %s. Haz clic en “Siguiente” y luego en “Finalizar”." - -msgid "In the sidebar, click the newly-added authentication server, labeled “%s”. Enter your %s player name and password and click “Login”." -msgstr "En la barra lateral, haz clic en el servidor de autenticación recién añadido, etiquetado como “%s”. Ingresa tu nombre de jugador y contraseña de %s y haz clic en “Acceder”." - -msgid "Other launchers" -msgstr "Otros lanzadores" - -msgid "Use the authlib-injector URL %s." -msgstr "Usa la URL de authlib-injector %s." - -msgid "Or, if your launcher supports custom API servers but not via authlib-injector, use the following URLs:" -msgstr "O, si tu lanzador soporta servidores API personalizados pero no a través de authlib-injector, usa las siguientes URLs:" - -msgid "Authentication server:" -msgstr "Servidor de “Authentication”:" - -msgid "Account server:" -msgstr "Servidor de “Account”:" - -msgid "Session server:" -msgstr "Servidor de “Session”:" - -msgid "Services server:" -msgstr "Servidor de “Services”:" - -msgid "Configuring your server" -msgstr "Configurando tu servidor" - -msgid "Minecraft 1.16 and later" -msgstr "Minecraft 1.16 y posteriores" - -msgid "On recent versions of Minecraft, you can use %s on an unmodified Vanilla server. To do so, add the following arguments before you specify the jar file when you start the server:" -msgstr "En las versiones recientes de Minecraft, puedes usar %s en un servidor Vanilla sin modificaciones. Para hacerlo, agrega los siguientes argumentos antes de especificar el archivo jar al iniciar el servidor:" - -msgid "For example, the full command you use to start the server might be:" -msgstr "Por ejemplo, el comando completo que usas para iniciar el servidor podría ser:" - -msgid "Minecraft 1.7.2 through 1.15.2" -msgstr "Minecraft 1.7.2 a 1.15.2" - -msgid "Refer to the authlib-injector documentation on setting up a server." -msgstr "Consulta la documentación de authlib-injector sobre cómo configurar un servidor." - -msgid "Alternatively, you can patch your server to use a newer version of Mojang's authlib that supports the arguments for custom API servers. Replace the files under com/mojang/authlib in your server.jar with the files in authlib-1.6.25.jar." -msgstr "Alternativamente, puedes parchear tu servidor para usar una versión más reciente de authlib de Mojang que soporte los argumentos para servidores API personalizados. Reemplaza los archivos bajo com/mojang/authlib en tu server.jar con los archivos en authlib-1.6.25.jar." - -msgid "Late Classic, Alpha, Beta, etc. through Minecraft 1.6.4" -msgstr "Clásico Tardío, Alpha, Beta, etc. hasta Minecraft 1.6.4" - -msgid "Use %s and start the server with the -Dminecraft.api.session.host argument described above. For example, the full command you use to start the server might be:" -msgstr "Usa %s y arranca el servidor con el argumento -Dminecraft.api.session.host descrito arriba. Por ejemplo, el comando completo que usas para iniciar el servidor podría ser:" - -msgid "Drasl version %s." -msgstr "Versión de Drasl %s." - -msgid "Licensed as %s." -msgstr "Con licencia %s." - -msgid "Source code." -msgstr "Código fuente." - -msgid "Signing in with %s requires an invite." -msgstr "Iniciar sesión con %s requiere una invitación." - -msgid "Register a new account:" - -msgid "Register a new account with a random UUID:" - -msgid "Player UUID (leave blank for random)" -msgstr "UUID del jugador (dejar en blanco para uno aleatorio)" - -msgid "Using invite code %s" -msgstr "Usando el código de invitación %s" - -msgid "Register from an existing Minecraft player" -msgstr "Registrarse como un jugador existente de Minecraft" - -msgid "Registration as a new player is invite-only." -msgstr "El registro como nuevo jugador es solo por invitación." - -msgid "Registration as an existing player is invite-only." -msgstr "El registro como jugador existente es solo por invitación." - -msgid "Register a new account with the UUID of an existing %s account. Requires verification that you own the account." -msgstr "Registra una nueva cuenta con el UUID de una cuenta existente de %s. Se requiere verificación de que eres el propietario de la cuenta." - -msgid "Register a new account with the UUID of an existing %s account" -msgstr "Registrar una nueva cuenta con el UUID de una cuenta existente de %s" - -msgid "%s player name" -msgstr "Nombre de jugador de %s" - -msgid "Continue" -msgstr "Continuar" - -msgid "Register" -msgstr "Registrarse" - -msgid "Migrate an existing user" -msgstr "Migrar un usuario existente" - -msgid "You can link this identity provider to an existing %s account." -msgstr "Puedes vincular este proveedor de identidad a una cuenta existente de %s." - -msgid "If you do so, you will no longer be able to log in using your %s password. You'll need to use your Minecraft Token to log in to Minecraft launchers." -msgstr "Si lo haces, ya no podrás iniciar sesión usando tu contraseña de %s. Necesitarás usar tu Token de Minecraft para iniciar sesión en los lanzadores de Minecraft." - -msgid "Link account" -msgstr "Vincular cuenta" - -msgid "Create a player" -msgstr "Crear un jugador" - -msgid "Complete registration by creating a new player:" -msgstr "Completa el registro creando un nuevo jugador:" - -msgid "Complete registration by creating a new player with a random UUID:" -msgstr "Completa el registro creando un nuevo jugador con un UUID aleatorio:" - -msgid "Choosing a player name is not allowed." -msgstr "No está permitido elegir un nombre de jugador." - -msgid "Player name" -msgstr "Nombre de jugador" - -msgid "We need to verify that you own the %s account “%s” before you register its UUID." -msgstr "Necesitamos verificar que eres el propietario de la cuenta %s “%s” antes de registrar su UUID." - -msgid "Download this image and set it as your skin on your %s account, on this page." -msgstr "Descarga esta imagen y configúrala como tu skin en tu cuenta de %s, en esta página." - -msgid "Download this image and set it as your skin on your %s account." -msgstr "Descarga esta imagen y configúrala como tu skin en tu cuenta de %s." - -msgid "%s verification skin" -msgstr "Skin de verificación de %s" - -msgid "%s-verification-skin.png" -msgstr "%s-skin-de-verificación.png" - -msgid "Download skin" -msgstr "Descargar skin" - -msgid "When you are done, hit “Register”." -msgstr "Cuando termines, haz clic en “Registrarse”." - -msgid "When you are done, enter a password for your %s account and hit “Register”." -msgstr "Cuando termines, ingresa una contraseña para tu cuenta de %s y haz clic en “Registrarse”." - -msgid "When you are done, hit “Create player”." -msgstr "Cuando termines, haz clic en “Crear jugador”." - -msgid "Create player" -msgstr "Crear jugador" diff --git a/public/style.css b/public/style.css index 36e4373..07e79d8 100644 --- a/public/style.css +++ b/public/style.css @@ -45,6 +45,7 @@ table { thead { font-weight: bold; + white-space: nowrap; } td:not(:last-child) { diff --git a/view/admin.tmpl b/view/admin.tmpl index 18fdab7..924def8 100644 --- a/view/admin.tmpl +++ b/view/admin.tmpl @@ -1,12 +1,12 @@ {{ template "layout" . }} -{{ define "title" }}Admin - {{ .App.Config.ApplicationName }}{{ end }} +{{ define "title" }}{{ call .T "Admin" }}{{ end }} {{ define "content" }} {{ template "header" . }} -

Pending Invites

+

{{ call .T "Pending Invites" }}

- +
{{ if .Invites }} - - + + @@ -50,7 +50,7 @@ value="{{ $invite.Code }}" hidden /> - + @@ -58,10 +58,10 @@
LinkDate Generated{{ call .T "Link" }}{{ call .T "Date Generated" }}
{{ else }} - No invites to show. + {{ call .T "No invites to show." }} {{ end }} -

All Users

+

{{ call .T "All Users" }}

{{ range $user := .Users }} @@ -69,7 +69,7 @@ id="delete-{{ $user.UUID }}" action="{{ $.App.FrontEndURL }}/web/delete-user" method="post" - onsubmit="return confirm('Are you sure you want to delete the account “{{ $user.Username }}”? This action is irreversible.');" + onsubmit="return confirm('{{ call $.T "Are you sure you want to delete the account “%s”? This action is irreversible." $user.Username }}');" > - User - Players - Max # players* - Admin - Locked - Delete Account + {{ call .T "User" }} + {{ call .T "Players" }} + {{ call .T "Max # players*" }} + {{ call .T "Admin" }} + {{ call .T "Locked" }} + {{ call .T "Delete Account" }} @@ -122,7 +122,7 @@ {{ $player.Name }} {{ end }} {{ else if gt (len $user.Players) 1 }} - {{ len $user.Players }} players + {{ len $user.Players }} {{ end }} @@ -130,7 +130,7 @@ name="max-player-count-{{ $user.UUID }}" type="number" {{ if $user.IsAdmin }} - title="Admins can always create unlimited players" + title="{{ call $.T "Admins can always create unlimited players" }}" disabled {{ end }} value="{{ if or $user.IsAdmin (eq $user.MaxPlayerCount $.App.Constants.MaxPlayerCountUnlimited) }}-1{{ else if eq $user.MaxPlayerCount $.App.Constants.MaxPlayerCountUseDefault}}{{ else }}{{ $user.MaxPlayerCount }}{{ end }}" @@ -140,17 +140,12 @@ @@ -158,11 +153,9 @@ @@ -171,17 +164,17 @@ {{ end }} -

*Specify -1 to allow an unlimited number of players. Leave blank to use the default max number, which is {{ $.App.Config.DefaultMaxPlayerCount }}.

+

{{ call .T "*Specify -1 to allow an unlimited number of players. Leave blank to use the default max number, which is %d." $.App.Config.DefaultMaxPlayerCount }}

- +

diff --git a/view/challenge.tmpl b/view/challenge.tmpl index e955b01..bc0386c 100644 --- a/view/challenge.tmpl +++ b/view/challenge.tmpl @@ -1,4 +1,7 @@ {{ template "layout" . }} + +{{ define "title" }}{{ call .T "Skin Verification" }}{{ end }} + {{ define "content" }} {{ template "header" . }} diff --git a/view/complete-registration.tmpl b/view/complete-registration.tmpl index bfad22e..86560cf 100644 --- a/view/complete-registration.tmpl +++ b/view/complete-registration.tmpl @@ -1,6 +1,6 @@ {{ template "layout" . }} -{{ define "title" }}Complete Registration - {{ .App.Config.ApplicationName }}{{ end }} +{{ define "title" }}{{ call .T "Complete Registration" }}{{ end }} {{ define "content" diff --git a/view/footer.tmpl b/view/footer.tmpl index be27c4c..5d66fb1 100644 --- a/view/footer.tmpl +++ b/view/footer.tmpl @@ -3,8 +3,8 @@
{{ call .T `Drasl version %s.` .App.Constants.Version }} - {{ call .T `Licensed as %s.` (render `{{ index . 1 }}` .App.Constants.LicenseURL .App.Constants.License) }} - {{ call .T `Source code.` .App.Constants.RepositoryURL }} + {{ render (call .T `Licensed as {{ index . 0 }}.`) (render `{{ index . 1 }}` .App.Constants.LicenseURL .App.Constants.License) }} + {{ render (call .T `Source code.`) .App.Constants.RepositoryURL }} {{ end }} {{ end }} diff --git a/view/registration.tmpl b/view/registration.tmpl index 2cef844..1fbd555 100644 --- a/view/registration.tmpl +++ b/view/registration.tmpl @@ -1,6 +1,6 @@ {{ template "layout" . }} -{{ define "title" }}Register - {{ .App.Config.ApplicationName }}{{ end }} +{{ define "title" }}{{ call .T "Registration" }}{{ end }} {{ define "content" diff --git a/view/root.tmpl b/view/root.tmpl index b8724e4..9d45e36 100644 --- a/view/root.tmpl +++ b/view/root.tmpl @@ -5,7 +5,7 @@ {{ define "content" }} {{ template "header" . }} - {{ $authlibInjectorLink := render `{{ index . 1}}` .App.AuthlibInjectorURL .App.AuthlibInjectorURL }} + {{ $authlibInjectorLink := render `{{ index . 0}}` .App.AuthlibInjectorURL }}

{{ call .T "Log in" }}

@@ -47,10 +47,10 @@

{{ call .T "Configuring your client" }}

- {{ call .T "Using %s on the client requires a third-party launcher that supports custom API servers. %s, a fork of Prism Launcher, is recommended, but %s also works. Both are free/libre." + {{ render (call .T `Using {{ index . 0 }} on the client requires a third-party launcher that supports custom API servers. {{ index . 1 }}, a fork of Prism Launcher, is recommended, but {{ index . 2 }} also works. Both are free/libre.`) .App.Config.ApplicationName - (html `Fjord Launcher`) - (html `HMCL`) }} + (render `Fjord Launcher`) + (render `HMCL` ) }}

Fjord Launcher

@@ -58,8 +58,8 @@
  1. {{ call .T "Click your account in the top right and select “Manage Accounts...”." }}
  2. {{ call .T "Click “Add authlib-injector” in the right-hand sidebar." }}
  3. -
  4. {{ call .T - "Enter your player name and your %s password or Minecraft Token, and use %s for the URL. Click “OK”." +
  5. {{ render + (call .T `Enter your player name and your {{ index . 0 }} password or Minecraft Token, and use {{ index . 1 }} for the URL. Click “OK”.`) .App.Config.ApplicationName $authlibInjectorLink }}
  6. @@ -70,8 +70,8 @@
    1. {{ call .T "Go to the “Account List” view by clicking the account at the top of the sidebar." }}
    2. - {{ call .T - "At the bottom left, click “New Auth Server” and enter %s. Click “Next” and then “Finish”." + {{ render + (call .T `At the bottom left, click “New Auth Server” and enter {{ index . 0 }} . Click “Next” and then “Finish”.`) $authlibInjectorLink }}
    3. @@ -86,7 +86,10 @@

      {{ call .T "Other launchers" }}

      -

      {{ call .T "Use the authlib-injector URL %s." $authlibInjectorLink }}

      +

      {{ render + (call .T `Use the authlib-injector URL {{ index . 0 }}.`) + $authlibInjectorLink + }}

      {{ call .T "Or, if your launcher supports custom API servers but not via authlib-injector, use the following URLs:" }}

      @@ -133,21 +136,24 @@ java -Xmx1024M -Xms1024M \

      {{ call .T "Minecraft 1.7.2 through 1.15.2" }}

      -

      {{ call .T - `Refer to the authlib-injector documentation on setting up a server.` +

      {{ render + (call .T `Refer to the authlib-injector documentation on setting up a server.`) "https://github.com/yushijinhun/authlib-injector/blob/develop/README.en.md#deploy" }}

      -

      {{ call .T - `Alternatively, you can patch your server to use a newer version of Mojang's authlib that supports the arguments for custom API servers. Replace the files under com/mojang/authlib in your server.jar with the files in authlib-1.6.25.jar.` +

      {{ render + (call .T `Alternatively, you can patch your server to use a newer version of Mojang's authlib that supports the arguments for custom API servers. Replace the files under com/mojang/authlib in your server.jar with the files in authlib-1.6.25.jar.`) "https://libraries.minecraft.net/com/mojang/authlib/1.6.25/authlib-1.6.25.jar" }}

      -

      {{ call .T `Late Classic, Alpha, Beta, etc. through Minecraft 1.6.4` "https://minecraft.wiki/w/Java_Edition_Late_Classic" }}

      +

      {{ render (call .T + `Late Classic, Alpha, Beta, etc. through Minecraft 1.6.4`) + "https://minecraft.wiki/w/Java_Edition_Late_Classic" + }}

      -

      {{ call .T - `Use %s and start the server with the -Dminecraft.api.session.host argument described above. For example, the full command you use to start the server might be:` - (html `OnlineModeFix`) +

      {{ render (call .T + `Use {{ index . 0 }} and start the server with the -Dminecraft.api.session.host argument described above. For example, the full command you use to start the server might be:`) + (render `OnlineModeFix`) }}