lang support
This commit is contained in:
parent
5822b75d66
commit
5dd3114e2d
8 changed files with 150 additions and 23 deletions
1
go.mod
1
go.mod
|
@ -26,6 +26,7 @@ require (
|
||||||
github.com/chai2010/webp v1.1.1 // indirect
|
github.com/chai2010/webp v1.1.1 // indirect
|
||||||
github.com/disintegration/imaging v1.6.2 // indirect
|
github.com/disintegration/imaging v1.6.2 // indirect
|
||||||
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
github.com/fsnotify/fsnotify v1.7.0 // indirect
|
||||||
|
github.com/leonelquinteros/gotext v1.7.0 // indirect
|
||||||
golang.org/x/image v0.20.0 // indirect
|
golang.org/x/image v0.20.0 // indirect
|
||||||
gopkg.in/ini.v1 v1.67.0 // indirect
|
gopkg.in/ini.v1 v1.67.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
2
go.sum
2
go.sum
|
@ -25,6 +25,8 @@ github.com/gobwas/ws v1.3.2/go.mod h1:hRKAFb8wOxFROYNsT1bqfWnhX+b5MFeJM9r2ZSwg/K
|
||||||
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
|
||||||
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
|
||||||
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
github.com/ledongthuc/pdf v0.0.0-20220302134840-0c2507a12d80/go.mod h1:imJHygn/1yfhB7XSJJKlFZKl/J+dCPAknuiaGOshXAs=
|
||||||
|
github.com/leonelquinteros/gotext v1.7.0 h1:jcJmF4AXqyamP7vuw2MMIKs+O3jAEmvrc5JQiI8Ht/8=
|
||||||
|
github.com/leonelquinteros/gotext v1.7.0/go.mod h1:qJdoQuERPpccw7L70uoU+K/BvTfRBHYsisCQyFLXyvw=
|
||||||
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
|
||||||
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
|
||||||
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
github.com/orisano/pixelmatch v0.0.0-20220722002657-fb0b55479cde/go.mod h1:nZgzbfBr3hhjoZnS66nKrHmduYNpc34ny7RK4z5/HM0=
|
||||||
|
|
32
lang.go
Normal file
32
lang.go
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/leonelquinteros/gotext"
|
||||||
|
)
|
||||||
|
|
||||||
|
var translations *gotext.Locale
|
||||||
|
|
||||||
|
// InitializeLanguage loads the language strings from .po files based on the selected language.
|
||||||
|
func InitializeLanguage(siteLanguage string) {
|
||||||
|
translationsDir := "lang"
|
||||||
|
localeDir := filepath.Join(translationsDir, siteLanguage, "LC_MESSAGES")
|
||||||
|
if _, err := os.Stat(localeDir); os.IsNotExist(err) {
|
||||||
|
printWarn("Translation directory for language '%s' does not exist. Using default.", siteLanguage)
|
||||||
|
siteLanguage = "en" // Use default language if not found
|
||||||
|
localeDir = filepath.Join(translationsDir, siteLanguage, "LC_MESSAGES")
|
||||||
|
}
|
||||||
|
|
||||||
|
translations = gotext.NewLocale(translationsDir, siteLanguage)
|
||||||
|
translations.AddDomain("default")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Translate wraps gotext.Get and returns a translated string based on the given key.
|
||||||
|
func Translate(key string, params ...interface{}) string {
|
||||||
|
if translations == nil {
|
||||||
|
return key // Fallback if translations are not initialized
|
||||||
|
}
|
||||||
|
return translations.Get(key, params...)
|
||||||
|
}
|
45
lang/en/LC_MESSAGES/default.po
Normal file
45
lang/en/LC_MESSAGES/default.po
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
msgid "settings_title"
|
||||||
|
msgstr "Settings"
|
||||||
|
|
||||||
|
msgid "settings"
|
||||||
|
msgstr "Settings"
|
||||||
|
|
||||||
|
msgid "theme"
|
||||||
|
msgstr "Theme"
|
||||||
|
|
||||||
|
msgid "theme_dark"
|
||||||
|
msgstr "Dark"
|
||||||
|
|
||||||
|
msgid "theme_light"
|
||||||
|
msgstr "Light"
|
||||||
|
|
||||||
|
msgid "theme_night"
|
||||||
|
msgstr "Night"
|
||||||
|
|
||||||
|
msgid "theme_black"
|
||||||
|
msgstr "Black"
|
||||||
|
|
||||||
|
msgid "theme_mocha"
|
||||||
|
msgstr "Mocha"
|
||||||
|
|
||||||
|
msgid "theme_latte"
|
||||||
|
msgstr "Latte"
|
||||||
|
|
||||||
|
msgid "safe_search"
|
||||||
|
msgstr "Safe Search"
|
||||||
|
|
||||||
|
msgid "safe_search_off"
|
||||||
|
msgstr "Off"
|
||||||
|
|
||||||
|
msgid "safe_search_on"
|
||||||
|
msgstr "On"
|
||||||
|
|
||||||
|
msgid "site_language"
|
||||||
|
msgstr "Site Language"
|
||||||
|
|
||||||
|
msgid "search_language"
|
||||||
|
msgstr "Search Language"
|
||||||
|
|
||||||
|
msgid "save_settings"
|
||||||
|
msgstr "Save Settings"
|
45
lang/pl/LC_MESSAGES/default.po
Normal file
45
lang/pl/LC_MESSAGES/default.po
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
|
||||||
|
msgid "settings_title"
|
||||||
|
msgstr "Ustawienia"
|
||||||
|
|
||||||
|
msgid "settings"
|
||||||
|
msgstr "Ustawienia"
|
||||||
|
|
||||||
|
msgid "theme"
|
||||||
|
msgstr "Motyw"
|
||||||
|
|
||||||
|
msgid "theme_dark"
|
||||||
|
msgstr "Ciemny"
|
||||||
|
|
||||||
|
msgid "theme_light"
|
||||||
|
msgstr "Jasny"
|
||||||
|
|
||||||
|
msgid "theme_night"
|
||||||
|
msgstr "Nocny"
|
||||||
|
|
||||||
|
msgid "theme_black"
|
||||||
|
msgstr "Czarny"
|
||||||
|
|
||||||
|
msgid "theme_mocha"
|
||||||
|
msgstr "Mocha"
|
||||||
|
|
||||||
|
msgid "theme_latte"
|
||||||
|
msgstr "Latte"
|
||||||
|
|
||||||
|
msgid "safe_search"
|
||||||
|
msgstr "Bezpieczne wyszukiwanie"
|
||||||
|
|
||||||
|
msgid "safe_search_off"
|
||||||
|
msgstr "Wyłączone"
|
||||||
|
|
||||||
|
msgid "safe_search_on"
|
||||||
|
msgstr "Włączone"
|
||||||
|
|
||||||
|
msgid "site_language"
|
||||||
|
msgstr "Język witryny"
|
||||||
|
|
||||||
|
msgid "search_language"
|
||||||
|
msgstr "Język wyszukiwania"
|
||||||
|
|
||||||
|
msgid "save_settings"
|
||||||
|
msgstr "Zapisz ustawienia"
|
2
main.go
2
main.go
|
@ -107,6 +107,8 @@ func handleSearch(w http.ResponseWriter, r *http.Request) {
|
||||||
settings.IsThemeDark = false
|
settings.IsThemeDark = false
|
||||||
}
|
}
|
||||||
|
|
||||||
|
InitializeLanguage(settings.SiteLanguage)
|
||||||
|
|
||||||
if query == "" {
|
if query == "" {
|
||||||
data := struct {
|
data := struct {
|
||||||
LanguageOptions []LanguageOption
|
LanguageOptions []LanguageOption
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="{{.CurrentSiteLang}}">
|
||||||
<head>
|
<head>
|
||||||
<meta charset="UTF-8">
|
<meta charset="UTF-8">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
||||||
{{ if .IsThemeDark }}
|
{{ if .IsThemeDark }}
|
||||||
<meta name="darkreader-lock">
|
<meta name="darkreader-lock">
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<title>Settings - Ocásek</title>
|
<title>{{ translate "settings_title" }}</title>
|
||||||
<link rel="stylesheet" href="/static/css/style.css">
|
<link rel="stylesheet" href="/static/css/style.css">
|
||||||
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
<link rel="stylesheet" href="/static/css/{{.Theme}}.css">
|
||||||
<link rel="stylesheet" href="/static/css/style-settings.css">
|
<link rel="stylesheet" href="/static/css/style-settings.css">
|
||||||
|
@ -14,67 +14,67 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div class="settings-nav">
|
<div class="settings-nav">
|
||||||
<h1 class="logomobile"><a class="no-decoration" href="./">Settings</a></h1>
|
<h1 class="logomobile"><a class="no-decoration" href="./">{{ translate "settings" }}</a></h1>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-container">
|
<div class="settings-container">
|
||||||
<form action="/save-settings" method="post">
|
<form action="/save-settings" method="post">
|
||||||
<div class="settings">
|
<div class="settings">
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<span class="highlight"><p>Theme</p></span>
|
<span class="highlight"><p>{{ translate "theme" }}</p></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="theme-settings">
|
<div class="theme-settings">
|
||||||
<div class="themes-settings-menu">
|
<div class="themes-settings-menu">
|
||||||
<a href="/search?theme=dark" class="theme-link">
|
<a href="/search?theme=dark" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="dark">
|
<div class="view-image-search clickable" id="dark">
|
||||||
<img src="/static/images/dark.webp" alt="Dark (Default)">
|
<img src="/static/images/dark.webp" alt="{{ translate "theme_dark" }}">
|
||||||
<div class="theme-tooltip">Dark (Default)</div>
|
<div class="theme-tooltip">{{ translate "theme_dark" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/search?theme=light" class="theme-link">
|
<a href="/search?theme=light" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="light">
|
<div class="view-image-search clickable" id="light">
|
||||||
<img src="/static/images/light.webp" alt="Light">
|
<img src="/static/images/light.webp" alt="{{ translate "theme_light" }}">
|
||||||
<div class="theme-tooltip">Light</div>
|
<div class="theme-tooltip">{{ translate "theme_light" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/search?theme=night" class="theme-link">
|
<a href="/search?theme=night" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="night">
|
<div class="view-image-search clickable" id="night">
|
||||||
<img src="/static/images/night.webp" alt="Night">
|
<img src="/static/images/night.webp" alt="{{ translate "theme_night" }}">
|
||||||
<div class="theme-tooltip">Night</div>
|
<div class="theme-tooltip">{{ translate "theme_night" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/search?theme=black" class="theme-link">
|
<a href="/search?theme=black" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="black">
|
<div class="view-image-search clickable" id="black">
|
||||||
<img src="/static/images/black.webp" alt="Black">
|
<img src="/static/images/black.webp" alt="{{ translate "theme_black" }}">
|
||||||
<div class="theme-tooltip">Black</div>
|
<div class="theme-tooltip">{{ translate "theme_black" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/search?theme=mocha" class="theme-link">
|
<a href="/search?theme=mocha" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="mocha">
|
<div class="view-image-search clickable" id="mocha">
|
||||||
<img src="/static/images/mocha.webp" alt="🌿 Mocha">
|
<img src="/static/images/mocha.webp" alt="🌿 {{ translate "theme_mocha" }}">
|
||||||
<div class="theme-tooltip">Mocha</div>
|
<div class="theme-tooltip">🌿 {{ translate "theme_mocha" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
<a href="/search?theme=latte" class="theme-link">
|
<a href="/search?theme=latte" class="theme-link">
|
||||||
<div class="view-image-search clickable" id="latte">
|
<div class="view-image-search clickable" id="latte">
|
||||||
<img src="/static/images/latte.webp" alt="🌻 Latte">
|
<img src="/static/images/latte.webp" alt="🌻 {{ translate "theme_latte" }}">
|
||||||
<div class="theme-tooltip">Latte</div>
|
<div class="theme-tooltip">🌻 {{ translate "theme_latte" }}</div>
|
||||||
</div>
|
</div>
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<p>Safe Search</p>
|
<p>{{ translate "safe_search" }}</p>
|
||||||
<select class="results-settings" name="safe" id="safeSearchSelect">
|
<select class="results-settings" name="safe" id="safeSearchSelect">
|
||||||
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>Safe Search Off</option>
|
<option value="disabled" {{if eq .Safe "disabled"}}selected{{end}}>{{ translate "safe_search_off" }}</option>
|
||||||
<option value="active" {{if eq .Safe "active"}}selected{{end}}>Safe Search On</option>
|
<option value="active" {{if eq .Safe "active"}}selected{{end}}>{{ translate "safe_search_on" }}</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<p>Site Language</p>
|
<p>{{ translate "site_language" }}</p>
|
||||||
<select class="results-settings" name="site_lang" id="siteLanguageSelect">
|
<select class="results-settings" name="site_lang" id="siteLanguageSelect">
|
||||||
{{range .LanguageOptions}}
|
{{range .LanguageOptions}}
|
||||||
<option value="{{.Code}}" {{if eq .Code $.CurrentSiteLang}}selected{{end}}>{{.Name}}</option>
|
<option value="{{.Code}}" {{if eq .Code $.CurrentSiteLang}}selected{{end}}>{{.Name}}</option>
|
||||||
|
@ -83,7 +83,7 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<p>Search Language</p>
|
<p>{{ translate "search_language" }}</p>
|
||||||
<select class="results-settings" name="search_lang" id="searchLanguageSelect">
|
<select class="results-settings" name="search_lang" id="searchLanguageSelect">
|
||||||
{{range .LanguageOptions}}
|
{{range .LanguageOptions}}
|
||||||
<option value="{{.Code}}" {{if eq .Code $.CurrentSearchLang}}selected{{end}}>{{.Name}}</option>
|
<option value="{{.Code}}" {{if eq .Code $.CurrentSearchLang}}selected{{end}}>{{.Name}}</option>
|
||||||
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
<div class="settings-row">
|
<div class="settings-row">
|
||||||
<p class="font-hide"> </p>
|
<p class="font-hide"> </p>
|
||||||
<button class="save save-settings-page" type="submit">Save Settings</button>
|
<button class="save save-settings-page" type="submit">{{ translate "save_settings" }}</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</form>
|
</form>
|
||||||
|
|
|
@ -164,7 +164,7 @@ func handleSettings(w http.ResponseWriter, r *http.Request) {
|
||||||
|
|
||||||
printDebug("Rendering settings with data: %+v", data)
|
printDebug("Rendering settings with data: %+v", data)
|
||||||
|
|
||||||
tmpl, err := template.ParseFiles("templates/settings.html")
|
tmpl, err := template.New("settings.html").Funcs(template.FuncMap{"translate": Translate}).ParseFiles("templates/settings.html")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
printErr("Error parsing template: %s", err)
|
printErr("Error parsing template: %s", err)
|
||||||
http.Error(w, "Internal Server Error", 500)
|
http.Error(w, "Internal Server Error", 500)
|
||||||
|
|
Loading…
Add table
Reference in a new issue