fix(finance): i18n — fix TOML duplicate key and missing Lang on Translator
- Remove conflicting `analysis = "..."` scalar from [nav] in both en.toml and pt.toml; it shadowed the [nav.analysis] sub-table, causing the TOML parser to reject the entire file at startup - Update nav analysis dropdown label to reuse nav.drawer.analysis_label - Add lang field to Translator and expose T.Lang() method so base.html can highlight the active language in the switcher without requiring a Lang field on every page data struct Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
2166790fab
commit
7aa510e1f5
@ -65,6 +65,7 @@ func flattenTOML(prefix string, node map[string]any, out catalogue) {
|
|||||||
// Translator wraps a locale lookup and exposes a Get method callable from
|
// Translator wraps a locale lookup and exposes a Get method callable from
|
||||||
// Go templates as {{.T.Get "key"}}.
|
// Go templates as {{.T.Get "key"}}.
|
||||||
type Translator struct {
|
type Translator struct {
|
||||||
|
lang string
|
||||||
cat catalogue
|
cat catalogue
|
||||||
en catalogue
|
en catalogue
|
||||||
}
|
}
|
||||||
@ -79,13 +80,19 @@ func (tr *Translator) Get(key string) string {
|
|||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Lang returns the active language code for use in templates (e.g. {{.T.Lang}}).
|
||||||
|
func (tr *Translator) Lang() string {
|
||||||
|
return tr.lang
|
||||||
|
}
|
||||||
|
|
||||||
// newT returns a Translator for the given language.
|
// newT returns a Translator for the given language.
|
||||||
func newT(lang string) *Translator {
|
func newT(lang string) *Translator {
|
||||||
cat, ok := catalogues[lang]
|
cat, ok := catalogues[lang]
|
||||||
if !ok {
|
if !ok {
|
||||||
|
lang = defaultLang
|
||||||
cat = catalogues[defaultLang]
|
cat = catalogues[defaultLang]
|
||||||
}
|
}
|
||||||
return &Translator{cat: cat, en: catalogues[defaultLang]}
|
return &Translator{lang: lang, cat: cat, en: catalogues[defaultLang]}
|
||||||
}
|
}
|
||||||
|
|
||||||
// detectLang reads the lang from a cookie, falling back to Accept-Language,
|
// detectLang reads the lang from a cookie, falling back to Accept-Language,
|
||||||
|
|||||||
@ -8,7 +8,6 @@ portfolio = "Portfolio"
|
|||||||
goals = "Goals"
|
goals = "Goals"
|
||||||
property = "Property"
|
property = "Property"
|
||||||
people = "People"
|
people = "People"
|
||||||
analysis = "Analysis"
|
|
||||||
settings = "Settings"
|
settings = "Settings"
|
||||||
business = "🏢 Business"
|
business = "🏢 Business"
|
||||||
hub_back = "← Hub"
|
hub_back = "← Hub"
|
||||||
|
|||||||
@ -8,7 +8,6 @@ portfolio = "Carteira"
|
|||||||
goals = "Objetivos"
|
goals = "Objetivos"
|
||||||
property = "Imóveis"
|
property = "Imóveis"
|
||||||
people = "Pessoas"
|
people = "Pessoas"
|
||||||
analysis = "Análise"
|
|
||||||
settings = "Definições"
|
settings = "Definições"
|
||||||
business = "🏢 Empresa"
|
business = "🏢 Empresa"
|
||||||
hub_back = "← Hub"
|
hub_back = "← Hub"
|
||||||
|
|||||||
@ -584,7 +584,7 @@
|
|||||||
{{$analysisActive := or (eq .Route "reports") (eq .Route "projections") (eq .Route "networth") (eq .Route "simulator") (eq .Route "tax")}}
|
{{$analysisActive := or (eq .Route "reports") (eq .Route "projections") (eq .Route "networth") (eq .Route "simulator") (eq .Route "tax")}}
|
||||||
<div class="nav-group">
|
<div class="nav-group">
|
||||||
<button class="nav-group-btn {{if $analysisActive}}active{{end}}">
|
<button class="nav-group-btn {{if $analysisActive}}active{{end}}">
|
||||||
{{.T.Get "nav.analysis"}} <svg viewBox="0 0 10 6" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 1l4 4 4-4"/></svg>
|
{{.T.Get "nav.drawer.analysis_label"}} <svg viewBox="0 0 10 6" fill="none" stroke="currentColor" stroke-width="1.5"><path d="M1 1l4 4 4-4"/></svg>
|
||||||
</button>
|
</button>
|
||||||
<div class="nav-dropdown">
|
<div class="nav-dropdown">
|
||||||
<a href="/reports" class="{{if eq .Route "reports"}}active{{end}}">{{.T.Get "nav.analysis.reports"}}</a>
|
<a href="/reports" class="{{if eq .Route "reports"}}active{{end}}">{{.T.Get "nav.analysis.reports"}}</a>
|
||||||
@ -614,8 +614,8 @@
|
|||||||
<span class="nav-email">{{.Email}}</span>
|
<span class="nav-email">{{.Email}}</span>
|
||||||
<form method="POST" action="/lang" style="display:inline;">
|
<form method="POST" action="/lang" style="display:inline;">
|
||||||
<select name="lang" onchange="this.form.submit()" style="font-size:12px; background:var(--bg2); color:var(--text2); border:1px solid var(--border2); border-radius:var(--radius-sm); padding:4px 6px; cursor:pointer;">
|
<select name="lang" onchange="this.form.submit()" style="font-size:12px; background:var(--bg2); color:var(--text2); border:1px solid var(--border2); border-radius:var(--radius-sm); padding:4px 6px; cursor:pointer;">
|
||||||
<option value="en" {{if eq .Lang "en"}}selected{{end}}>EN</option>
|
<option value="en" {{if eq (.T.Lang) "en"}}selected{{end}}>EN</option>
|
||||||
<option value="pt" {{if eq .Lang "pt"}}selected{{end}}>PT</option>
|
<option value="pt" {{if eq (.T.Lang) "pt"}}selected{{end}}>PT</option>
|
||||||
</select>
|
</select>
|
||||||
</form>
|
</form>
|
||||||
<button class="theme-btn" id="theme-toggle" title="{{.T.Get "nav.theme.toggle_title"}}">🌙</button>
|
<button class="theme-btn" id="theme-toggle" title="{{.T.Get "nav.theme.toggle_title"}}">🌙</button>
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user