fully impleemnted localelist dialog type
This commit is contained in:
@@ -14,6 +14,7 @@ require (
|
|||||||
github.com/labstack/echo/v4 v4.13.4
|
github.com/labstack/echo/v4 v4.13.4
|
||||||
github.com/labstack/gommon v0.4.2
|
github.com/labstack/gommon v0.4.2
|
||||||
github.com/sirupsen/logrus v1.9.3
|
github.com/sirupsen/logrus v1.9.3
|
||||||
|
golang.org/x/text v0.30.0
|
||||||
gopkg.in/yaml.v3 v3.0.1
|
gopkg.in/yaml.v3 v3.0.1
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -30,6 +31,5 @@ require (
|
|||||||
golang.org/x/crypto v0.38.0 // indirect
|
golang.org/x/crypto v0.38.0 // indirect
|
||||||
golang.org/x/net v0.40.0 // indirect
|
golang.org/x/net v0.40.0 // indirect
|
||||||
golang.org/x/sys v0.33.0 // indirect
|
golang.org/x/sys v0.33.0 // indirect
|
||||||
golang.org/x/text v0.25.0 // indirect
|
|
||||||
golang.org/x/time v0.11.0 // indirect
|
golang.org/x/time v0.11.0 // indirect
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -63,8 +63,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||||||
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||||
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
golang.org/x/sys v0.33.0 h1:q3i8TbbEz+JRD9ywIRlyRAQbM0qF7hu24q3teo2hbuw=
|
||||||
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
golang.org/x/sys v0.33.0/go.mod h1:BJP2sWEmIv4KK5OTEluFJCKSidICx8ciO85XgH3Ak8k=
|
||||||
golang.org/x/text v0.25.0 h1:qVyWApTSYLk/drJRO5mDlNYskwQznZmkpV2c8q9zls4=
|
golang.org/x/text v0.30.0 h1:yznKA/E9zq54KzlzBEAWn1NXSQ8DIp/NYMy88xJjl4k=
|
||||||
golang.org/x/text v0.25.0/go.mod h1:WEdwpYrmk1qmdHvhkSTNPm3app7v4rsT8F2UD6+VHIA=
|
golang.org/x/text v0.30.0/go.mod h1:yDdHFIX9t+tORqspjENWgzaCVXgk0yYnYuSZ8UzzBVM=
|
||||||
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
golang.org/x/time v0.11.0 h1:/bpjEDfN9tkoN/ryeYHnv5hcMlc8ncjMcM4XBk5NWV0=
|
||||||
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
golang.org/x/time v0.11.0/go.mod h1:CDIdPxbZBQxdj6cxyCIdrNogrJKMJ7pr37NYpMcMDSg=
|
||||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||||
|
|||||||
+6
-1
@@ -170,8 +170,13 @@ func (d *Dialog) Render(ctxt AmContext) (string, any, error) {
|
|||||||
if fld.Required {
|
if fld.Required {
|
||||||
required = true // display the "required" blurb
|
required = true // display the "required" blurb
|
||||||
}
|
}
|
||||||
if fld.Type == "password" { // clear all "password" fields as a security measure
|
switch fld.Type {
|
||||||
|
case "password": // clear all "password" fields as a security measure
|
||||||
d.Fields[i].Value = ""
|
d.Fields[i].Value = ""
|
||||||
|
case "localelist": // default locale to en-US if we don't have one
|
||||||
|
if d.Fields[i].Value == "" {
|
||||||
|
d.Fields[i].Value = "en-US"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ctxt.VarMap().Set("amsterdam_required", required)
|
ctxt.VarMap().Set("amsterdam_required", required)
|
||||||
|
|||||||
@@ -0,0 +1,150 @@
|
|||||||
|
ja-JP
|
||||||
|
es-PE
|
||||||
|
en
|
||||||
|
es-PA
|
||||||
|
sr-BA
|
||||||
|
mk
|
||||||
|
es-GT
|
||||||
|
ar-AE
|
||||||
|
no-NO
|
||||||
|
sq-AL
|
||||||
|
bg
|
||||||
|
ar-IQ
|
||||||
|
ar-YE
|
||||||
|
hu
|
||||||
|
pt-PT
|
||||||
|
el-CY
|
||||||
|
ar-QA
|
||||||
|
mk-MK
|
||||||
|
sv
|
||||||
|
de-CH
|
||||||
|
en-US
|
||||||
|
fi-FI
|
||||||
|
is
|
||||||
|
cs
|
||||||
|
en-MT
|
||||||
|
sl-SI
|
||||||
|
sk-SK
|
||||||
|
it
|
||||||
|
tr-TR
|
||||||
|
zh
|
||||||
|
th
|
||||||
|
ar-SA
|
||||||
|
no
|
||||||
|
en-GB
|
||||||
|
sr-CS
|
||||||
|
lt
|
||||||
|
ro
|
||||||
|
en-NZ
|
||||||
|
nn-NO
|
||||||
|
lt-LT
|
||||||
|
es-NI
|
||||||
|
nl
|
||||||
|
ga-IE
|
||||||
|
fr-BE
|
||||||
|
es-ES
|
||||||
|
ar-LB
|
||||||
|
ko
|
||||||
|
fr-CA
|
||||||
|
et-EE
|
||||||
|
ar-KW
|
||||||
|
sr-RS
|
||||||
|
es-US
|
||||||
|
es-MX
|
||||||
|
ar-SD
|
||||||
|
in-ID
|
||||||
|
ru
|
||||||
|
lv
|
||||||
|
es-UY
|
||||||
|
lv-LV
|
||||||
|
iw
|
||||||
|
pt-BR
|
||||||
|
ar-SY
|
||||||
|
hr
|
||||||
|
et
|
||||||
|
es-DO
|
||||||
|
fr-CH
|
||||||
|
hi-IN
|
||||||
|
es-VE
|
||||||
|
ar-BH
|
||||||
|
en-PH
|
||||||
|
ar-TN
|
||||||
|
fi
|
||||||
|
de-AT
|
||||||
|
es
|
||||||
|
nl-NL
|
||||||
|
es-EC
|
||||||
|
zh-TW
|
||||||
|
ar-JO
|
||||||
|
be
|
||||||
|
is-IS
|
||||||
|
es-CO
|
||||||
|
es-CR
|
||||||
|
es-CL
|
||||||
|
ar-EG
|
||||||
|
en-ZA
|
||||||
|
th-TH
|
||||||
|
el-GR
|
||||||
|
it-IT
|
||||||
|
ca
|
||||||
|
hu-HU
|
||||||
|
fr
|
||||||
|
en-IE
|
||||||
|
uk-UA
|
||||||
|
pl-PL
|
||||||
|
fr-LU
|
||||||
|
nl-BE
|
||||||
|
en-IN
|
||||||
|
ca-ES
|
||||||
|
ar-MA
|
||||||
|
es-BO
|
||||||
|
en-AU
|
||||||
|
sr
|
||||||
|
zh-SG
|
||||||
|
pt
|
||||||
|
uk
|
||||||
|
es-SV
|
||||||
|
ru-RU
|
||||||
|
ko-KR
|
||||||
|
vi
|
||||||
|
ar-DZ
|
||||||
|
vi-VN
|
||||||
|
sr-ME
|
||||||
|
sq
|
||||||
|
ar-LY
|
||||||
|
ar
|
||||||
|
zh-CN
|
||||||
|
be-BY
|
||||||
|
zh-HK
|
||||||
|
ja
|
||||||
|
iw-IL
|
||||||
|
bg-BG
|
||||||
|
in
|
||||||
|
mt-MT
|
||||||
|
es-PY
|
||||||
|
sl
|
||||||
|
fr-FR
|
||||||
|
cs-CZ
|
||||||
|
it-CH
|
||||||
|
ro-RO
|
||||||
|
es-PR
|
||||||
|
en-CA
|
||||||
|
de-DE
|
||||||
|
ga
|
||||||
|
de-LU
|
||||||
|
de
|
||||||
|
es-AR
|
||||||
|
sk
|
||||||
|
ms-MY
|
||||||
|
hr-HR
|
||||||
|
en-SG
|
||||||
|
da
|
||||||
|
mt
|
||||||
|
pl
|
||||||
|
ar-OM
|
||||||
|
tr
|
||||||
|
el
|
||||||
|
ms
|
||||||
|
sv-SE
|
||||||
|
da-DK
|
||||||
|
es-HN
|
||||||
+56
-1
@@ -22,6 +22,7 @@ import (
|
|||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
"unicode"
|
"unicode"
|
||||||
|
_ "unsafe" // HACK HACK HACK
|
||||||
|
|
||||||
"git.erbosoft.com/amy/amsterdam/config"
|
"git.erbosoft.com/amy/amsterdam/config"
|
||||||
"github.com/CloudyKit/jet/v6"
|
"github.com/CloudyKit/jet/v6"
|
||||||
@@ -30,6 +31,8 @@ import (
|
|||||||
"github.com/biter777/countries"
|
"github.com/biter777/countries"
|
||||||
"github.com/labstack/echo/v4"
|
"github.com/labstack/echo/v4"
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
"golang.org/x/text/language"
|
||||||
|
"golang.org/x/text/language/display"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:embed views/*
|
//go:embed views/*
|
||||||
@@ -38,6 +41,56 @@ var static_views embed.FS
|
|||||||
// views is the main Jet template repository.
|
// views is the main Jet template repository.
|
||||||
var views *jet.Set
|
var views *jet.Set
|
||||||
|
|
||||||
|
//go:embed languages.txt
|
||||||
|
var knownLanguages string
|
||||||
|
|
||||||
|
// Language is a type for a list of all supportred languages.
|
||||||
|
type Language struct {
|
||||||
|
Tag string // the BCP 47 tag, such as "en-US"
|
||||||
|
Name string // the human-readable name, like "American English"
|
||||||
|
}
|
||||||
|
|
||||||
|
// cachedLanguageList is the cached language list.
|
||||||
|
var cachedLanguageList []Language = nil
|
||||||
|
|
||||||
|
// languageListMutex controls access to internalGetLanguageList.
|
||||||
|
var languageListMutex sync.Mutex
|
||||||
|
|
||||||
|
// internalGetLanguageList is a wrapper around "allTags" that sorts it by language name.
|
||||||
|
func internalGetLanguageList() []Language {
|
||||||
|
languageListMutex.Lock()
|
||||||
|
defer languageListMutex.Unlock()
|
||||||
|
if cachedLanguageList == nil {
|
||||||
|
langs := strings.Split(knownLanguages, "\n")
|
||||||
|
enNamer := display.English.Tags()
|
||||||
|
cachedLanguageList = make([]Language, 0, len(langs))
|
||||||
|
for _, l := range langs {
|
||||||
|
tag, err := language.Parse(l)
|
||||||
|
if err == nil {
|
||||||
|
cachedLanguageList = append(cachedLanguageList, Language{
|
||||||
|
Tag: tag.String(),
|
||||||
|
Name: enNamer.Name(tag),
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
log.Errorf("*** PUKE on parsing language tag %s: %v", l, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
slices.SortFunc(cachedLanguageList, func(a Language, b Language) int {
|
||||||
|
return strings.Compare(a.Name, b.Name)
|
||||||
|
})
|
||||||
|
log.Infof("internalGetLanguageList() loaded %d languages", len(cachedLanguageList))
|
||||||
|
}
|
||||||
|
return cachedLanguageList
|
||||||
|
}
|
||||||
|
|
||||||
|
// getLanguageList is a wrapper around the list of languages that can be added to the template context.
|
||||||
|
func getLanguageList(a jet.Arguments) reflect.Value {
|
||||||
|
rc := internalGetLanguageList()
|
||||||
|
log.Infof("GetLanguageList() provides %d items", len(rc))
|
||||||
|
return reflect.ValueOf(rc)
|
||||||
|
}
|
||||||
|
|
||||||
// cachedCountryList is the cached country list after sorting.
|
// cachedCountryList is the cached country list after sorting.
|
||||||
var cachedCountryList []countries.CountryCode = nil
|
var cachedCountryList []countries.CountryCode = nil
|
||||||
|
|
||||||
@@ -170,6 +223,7 @@ func SetupTemplates() {
|
|||||||
views.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT)
|
views.AddGlobal("AmsterdamCopyright", config.AMSTERDAM_COPYRIGHT)
|
||||||
views.AddGlobal("GlobalConfig", config.GlobalConfig)
|
views.AddGlobal("GlobalConfig", config.GlobalConfig)
|
||||||
views.AddGlobalFunc("GetCountryList", getCountryList)
|
views.AddGlobalFunc("GetCountryList", getCountryList)
|
||||||
|
views.AddGlobalFunc("GetLanguageList", getLanguageList)
|
||||||
views.AddGlobalFunc("GetMonthList", getMonthList)
|
views.AddGlobalFunc("GetMonthList", getMonthList)
|
||||||
views.AddGlobalFunc("MakeIntRange", makeIntRange)
|
views.AddGlobalFunc("MakeIntRange", makeIntRange)
|
||||||
views.AddGlobalFunc("MakeYearRange", makeYearRange)
|
views.AddGlobalFunc("MakeYearRange", makeYearRange)
|
||||||
@@ -179,8 +233,9 @@ func SetupTemplates() {
|
|||||||
return reflect.ValueOf(CapitalizeString(s))
|
return reflect.ValueOf(CapitalizeString(s))
|
||||||
})
|
})
|
||||||
|
|
||||||
// preload the country list in the background
|
// preload the lists in the background
|
||||||
go internalGetCountryList()
|
go internalGetCountryList()
|
||||||
|
go internalGetLanguageList()
|
||||||
}
|
}
|
||||||
|
|
||||||
// TemplateRenderer is the Renderer instance set into the Echo context at creation time, to render Jet templates.
|
// TemplateRenderer is the Renderer instance set into the Echo context at creation time, to render Jet templates.
|
||||||
|
|||||||
+4
-1
@@ -130,9 +130,12 @@
|
|||||||
{{ .Caption }}{{ if .Subcaption != "" }} {{ .Subcaption }}{{ end }}
|
{{ .Caption }}{{ if .Subcaption != "" }} {{ .Subcaption }}{{ end }}
|
||||||
{{ if .Required }}<span class="text-red-600">*</span>{{ end }}
|
{{ if .Required }}<span class="text-red-600">*</span>{{ end }}
|
||||||
</label>
|
</label>
|
||||||
|
{{ v := .Value }}
|
||||||
<select id="{{ .Name }}" name="{{ .Name }}" {{ if .Required }}required{{ end }}
|
<select id="{{ .Name }}" name="{{ .Name }}" {{ if .Required }}required{{ end }}
|
||||||
class="flex-1 max-w-md px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
class="flex-1 max-w-md px-3 py-2 border border-gray-300 rounded focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500">
|
||||||
<option value="XX">Unknown</option>{* TODO *}
|
{{ range GetLanguageList() }}
|
||||||
|
<option value="{{ .Tag }}" {{ if .Tag == v }}selected{{ end }}>{{ .Name }}</option>
|
||||||
|
{{ end }}
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
{{ else if .Type == "tzlist" }}
|
{{ else if .Type == "tzlist" }}
|
||||||
|
|||||||
Reference in New Issue
Block a user