Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add translation strings #269

Merged
merged 4 commits into from
May 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions internal/i18n/locale.go
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,20 @@ func (store *LocaleStore) MatchTag(langs []language.Tag) string {
return "en-US"
}

func (l *Locale) String(key string, args ...any) string {
message := l.Messages[key]

if message == "" {
return Locales.Locales["en-US"].String(key, args...)
}

if len(args) == 0 {
return message
}

return fmt.Sprintf(message, args...)
}

func (l *Locale) Tr(key string, args ...any) template.HTML {
message := l.Messages[key]

Expand Down
61 changes: 60 additions & 1 deletion internal/i18n/locales/en-US.yml
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,10 @@ gist.new.create-public-button: Create public gist
gist.new.create-unlisted-button: Create unlisted gist
gist.new.create-private-button: Create private gist
gist.new.preview: Preview
gist.new.create-a-new-gist: Create a new gist

gist.edit.editing: Editing
gist.edit.edit-gist: Edit %s
gist.edit.change-visibility: Make
gist.edit.delete: Delete
gist.edit.cancel: Cancel
Expand All @@ -68,6 +70,9 @@ gist.list.forks: forks
gist.list.files: files
gist.list.last-active: Last active
gist.list.no-gists: No gists
gist.list.all-liked-by: All gists liked by %s
gist.list.all-forked-by: All gists forked by %s
gist.list.all-from: All gists from %s

gist.search.found: gists found
gist.search.no-results: No gists found
Expand All @@ -80,9 +85,11 @@ gist.search.help.language: gists having files with given language
gist.forks: Forks
gist.forks.view: View fork
gist.forks.no: No public forks
gist.forks.for: Forks for %s

gist.likes: Likes
gist.likes.no: No likes yet
gist.likes.for: Likes for %s

gist.revisions: Revisions
gist.revision.revised: revised this gist
Expand All @@ -95,6 +102,7 @@ gist.revision.file-renamed-no-changes: File renamed without changes
gist.revision.empty-file: Empty file
gist.revision.no-changes: No changes
gist.revision.no-revisions: No revisions to show
gist.revision-of: Revision of %s

settings: Settings
settings.email: Email
Expand Down Expand Up @@ -136,6 +144,16 @@ auth.login-instead: Login instead
auth.oauth: Continue with %s account

error: Error
error.page-not-found: Page not found
error.bad-request: Bad request
error.signup-disabled: Signing up is disabled
error.signup-disabled-form: Signing up via registration form is disabled
error.login-disabled-form: Logging in via login form is disabled
error.complete-oauth-login: "Cannot complete user auth: %s"
error.oauth-unsupported: Unsupported provider
error.cannot-bind-data: Cannot bind data
error.invalid-number: Invalid number
error.invalid-character-unescaped: Invalid character unescaped

header.menu.all: All
header.menu.new: New
Expand Down Expand Up @@ -204,4 +222,45 @@ admin.invitations.expires_at: Expires at
admin.invitations.code: Code
admin.invitations.copy_link: Copy link
admin.invitations.uses: Uses
admin.invitations.expired: Expired
admin.invitations.expired: Expired

flash.admin.user-deleted: User has been deleted
flash.admin.gist-deleted: Gist has been deleted
flash.admin.invitation-created: Invitation has been created
flash.admin.invitation-deleted: Invitation has been deleted
flash.admin.sync-fs: Syncing repositories from filesystem...
flash.admin.sync-db: Syncing repositories from database...
flash.admin.git-gc: Garbage collecting repositories...
flash.admin.sync-previews: Syncing Gist previews...
flash.admin.reset-hooks: Resetting Git server hooks for all repositories...
flash.admin.index-gists: Indexing all gists...

flash.auth.username-exists: Username already exists
flash.auth.invalid-credentials: Invalid credentials
flash.auth.account-linked-oauth: Account linked to %s
flash.auth.account-unlinked-oauth: Account unlinked from %s
flash.auth.user-sshkeys-not-retrievable: Could not get user keys
flash.auth.user-sshkeys-not-created: Could not create ssh key
flash.auth.must-be-logged-in: You must be logged in to access gists

flash.gist.visibility-changed: Gist visibility has been changed
flash.gist.deleted: Gist has been deleted
flash.gist.fork-own-gist: Unable to fork own gists
flash.gist.forked: Gist has been forked

flash.user.email-updated: Email updated
flash.user.invalid-ssh-key: Invalid SSH key
flash.user.ssh-key-added: SSH key added
flash.user.ssh-key-deleted: SSH key deleted
flash.user.password-updated: Password updated
flash.user.username-updated: Username updated

validation.is-too-long: Field %s is too long
validation.should-not-be-empty: Field %s should not be empty
validation.should-not-include-sub-directory: Field %s should not include a sub directory
validation.should-only-contain-alphanumeric-characters: Field %s should only contain alphanumeric characters
validation.should-only-contain-alphanumeric-characters-and-dashes: Field %s should only contain alphanumeric characters and dashes
validation.not-enough: Not enough %s
validation.invalid: Invalid %s

html.title.admin-panel: Admin panel
17 changes: 9 additions & 8 deletions internal/utils/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package utils

import (
"github.com/go-playground/validator/v10"
"github.com/thomiceli/opengist/internal/i18n"
"regexp"
"strings"
)
Expand All @@ -26,26 +27,26 @@ func (cv *OpengistValidator) Var(field interface{}, tag string) error {
return cv.v.Var(field, tag)
}

func ValidationMessages(err *error) string {
func ValidationMessages(err *error, locale *i18n.Locale) string {
errs := (*err).(validator.ValidationErrors)
messages := make([]string, len(errs))
for i, e := range errs {
switch e.Tag() {
case "max":
messages[i] = e.Field() + " is too long"
messages[i] = locale.String("validation.is-too-long", e.Field())
case "required":
messages[i] = e.Field() + " should not be empty"
messages[i] = locale.String("validation.should-not-be-empty", e.Field())
case "excludes":
messages[i] = e.Field() + " should not include a sub directory"
messages[i] = locale.String("validation.should-not-include-sub-directory", e.Field())
case "alphanum":
messages[i] = e.Field() + " should only contain alphanumeric characters"
messages[i] = locale.String("validation.should-only-contain-alphanumeric-characters", e.Field())
case "alphanumdash":
case "alphanumdashorempty":
messages[i] = e.Field() + " should only contain alphanumeric characters and dashes"
messages[i] = locale.String("validation.should-only-contain-alphanumeric-characters-and-dashes", e.Field())
case "min":
messages[i] = "Not enough " + e.Field()
messages[i] = locale.String("validation.not-enough", e.Field())
case "notreserved":
messages[i] = "Invalid " + e.Field()
messages[i] = locale.String("validation.invalid", e.Field())
}
}

Expand Down
39 changes: 17 additions & 22 deletions internal/web/admin.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ import (
)

func adminIndex(ctx echo.Context) error {
setData(ctx, "title", "Admin panel")
setData(ctx, "htmlTitle", "Admin panel")
setData(ctx, "htmlTitle", trH(ctx, "admin.admin_panel"))
setData(ctx, "adminHeaderPage", "index")

setData(ctx, "opengistVersion", config.OpengistVersion)
Expand Down Expand Up @@ -52,8 +51,7 @@ func adminIndex(ctx echo.Context) error {
}

func adminUsers(ctx echo.Context) error {
setData(ctx, "title", "Users")
setData(ctx, "htmlTitle", "Users - Admin panel")
setData(ctx, "htmlTitle", trH(ctx, "admin.users")+" - "+trH(ctx, "admin.admin_panel"))
setData(ctx, "adminHeaderPage", "users")
pageInt := getPage(ctx)

Expand All @@ -64,15 +62,14 @@ func adminUsers(ctx echo.Context) error {
}

if err = paginate(ctx, data, pageInt, 10, "data", "admin-panel/users", 1); err != nil {
return errorRes(404, "Page not found", nil)
return errorRes(404, tr(ctx, "error.page-not-found"), nil)
}

return html(ctx, "admin_users.html")
}

func adminGists(ctx echo.Context) error {
setData(ctx, "title", "Gists")
setData(ctx, "htmlTitle", "Gists - Admin panel")
setData(ctx, "htmlTitle", trH(ctx, "admin.gists")+" - "+trH(ctx, "admin.admin_panel"))
setData(ctx, "adminHeaderPage", "gists")
pageInt := getPage(ctx)

Expand All @@ -83,7 +80,7 @@ func adminGists(ctx echo.Context) error {
}

if err = paginate(ctx, data, pageInt, 10, "data", "admin-panel/gists", 1); err != nil {
return errorRes(404, "Page not found", nil)
return errorRes(404, tr(ctx, "error.page-not-found"), nil)
}

return html(ctx, "admin_gists.html")
Expand All @@ -100,7 +97,7 @@ func adminUserDelete(ctx echo.Context) error {
return errorRes(500, "Cannot delete this user", err)
}

addFlash(ctx, "User has been deleted", "success")
addFlash(ctx, tr(ctx, "flash.admin.user-deleted"), "success")
return redirect(ctx, "/admin-panel/users")
}

Expand All @@ -120,49 +117,48 @@ func adminGistDelete(ctx echo.Context) error {

gist.RemoveFromIndex()

addFlash(ctx, "Gist has been deleted", "success")
addFlash(ctx, tr(ctx, "flash.admin.gist-deleted"), "success")
return redirect(ctx, "/admin-panel/gists")
}

func adminSyncReposFromFS(ctx echo.Context) error {
addFlash(ctx, "Syncing repositories from filesystem...", "success")
addFlash(ctx, tr(ctx, "flash.admin.sync-fs"), "success")
go actions.Run(actions.SyncReposFromFS)
return redirect(ctx, "/admin-panel")
}

func adminSyncReposFromDB(ctx echo.Context) error {
addFlash(ctx, "Syncing repositories from database...", "success")
addFlash(ctx, tr(ctx, "flash.admin.sync-db"), "success")
go actions.Run(actions.SyncReposFromDB)
return redirect(ctx, "/admin-panel")
}

func adminGcRepos(ctx echo.Context) error {
addFlash(ctx, "Garbage collecting repositories...", "success")
addFlash(ctx, tr(ctx, "flash.admin.git-gc"), "success")
go actions.Run(actions.GitGcRepos)
return redirect(ctx, "/admin-panel")
}

func adminSyncGistPreviews(ctx echo.Context) error {
addFlash(ctx, "Syncing Gist previews...", "success")
addFlash(ctx, tr(ctx, "flash.admin.sync-previews"), "success")
go actions.Run(actions.SyncGistPreviews)
return redirect(ctx, "/admin-panel")
}

func adminResetHooks(ctx echo.Context) error {
addFlash(ctx, "Resetting Git server hooks for all repositories...", "success")
addFlash(ctx, tr(ctx, "flash.admin.reset-hooks"), "success")
go actions.Run(actions.ResetHooks)
return redirect(ctx, "/admin-panel")
}

func adminIndexGists(ctx echo.Context) error {
addFlash(ctx, "Indexing all gists...", "success")
addFlash(ctx, tr(ctx, "flash.admin.index-gists"), "success")
go actions.Run(actions.IndexGists)
return redirect(ctx, "/admin-panel")
}

func adminConfig(ctx echo.Context) error {
setData(ctx, "title", "Configuration")
setData(ctx, "htmlTitle", "Configuration - Admin panel")
setData(ctx, "htmlTitle", trH(ctx, "admin.configuration")+" - "+trH(ctx, "admin.admin_panel"))
setData(ctx, "adminHeaderPage", "config")

return html(ctx, "admin_config.html")
Expand All @@ -182,8 +178,7 @@ func adminSetConfig(ctx echo.Context) error {
}

func adminInvitations(ctx echo.Context) error {
setData(ctx, "title", "Invitations")
setData(ctx, "htmlTitle", "Invitations - Admin panel")
setData(ctx, "htmlTitle", trH(ctx, "admin.invitations")+" - "+trH(ctx, "admin.admin_panel"))
setData(ctx, "adminHeaderPage", "invitations")

var invitations []*db.Invitation
Expand Down Expand Up @@ -218,7 +213,7 @@ func adminInvitationsCreate(ctx echo.Context) error {
return errorRes(500, "Cannot create invitation", err)
}

addFlash(ctx, "Invitation has been created", "success")
addFlash(ctx, tr(ctx, "flash.admin.invitation-created"), "success")
return redirect(ctx, "/admin-panel/invitations")
}

Expand All @@ -233,6 +228,6 @@ func adminInvitationsDelete(ctx echo.Context) error {
return errorRes(500, "Cannot delete this invitation", err)
}

addFlash(ctx, "Invitation has been deleted", "success")
addFlash(ctx, tr(ctx, "flash.admin.invitation-deleted"), "success")
return redirect(ctx, "/admin-panel/invitations")
}
Loading
Loading