diff --git a/deploy/available_languages.sql b/deploy/available_languages.sql index 28618d3..74c1f86 100644 --- a/deploy/available_languages.sql +++ b/deploy/available_languages.sql @@ -4,10 +4,10 @@ begin; -insert into public.language (lang_tag, name, endonym, selectable) -values ('und', 'Undefined', 'Undefined', false) - , ('ca', 'Catalan', 'català', true) - , ('es', 'Spanish', 'español', true) +insert into public.language (lang_tag, name, endonym, selectable, currency_pattern) +values ('und', 'Undefined', 'Undefined', false, '%[3]s%.[1]*[2]f') + , ('ca', 'Catalan', 'català', true, '%.[1]*[2]f %[3]s') + , ('es', 'Spanish', 'español', true, '%.[1]*[2]f %[3]s') ; commit; diff --git a/deploy/language.sql b/deploy/language.sql index 52865be..2e012f5 100644 --- a/deploy/language.sql +++ b/deploy/language.sql @@ -9,7 +9,8 @@ create table language ( lang_tag text primary key check (length(lang_tag) < 36), -- RFC5646 recommends 35 at least name text not null, endonym text not null, - selectable boolean not null + selectable boolean not null, + currency_pattern text not null ); grant select on table language to guest; diff --git a/pkg/locale.go b/pkg/locale.go index 7363147..d241ea9 100644 --- a/pkg/locale.go +++ b/pkg/locale.go @@ -12,27 +12,31 @@ const contextLocaleKey = "numerus-locale" type Locale struct { *gotext.Locale - Language language.Tag + CurrencyPattern string + Language language.Tag } -func NewLocale(lang language.Tag) *Locale { +func NewLocale(lang availableLanguage) *Locale { return &Locale{ - gotext.NewLocale("locales", lang.String()), - lang, + gotext.NewLocale("locales", lang.tag.String()), + lang.currencyPattern, + lang.tag, } } func LocaleSetter(db *Db, next http.Handler) http.Handler { availableLanguages := mustGetAvailableLanguages(db) - var matcher = language.NewMatcher(availableLanguages) locales := map[language.Tag]*Locale{} + var tags []language.Tag for _, lang := range availableLanguages { locale := NewLocale(lang) locale.AddDomain("numerus") - locales[lang] = locale + locales[lang.tag] = locale + tags = append(tags, lang.tag) } defaultLocale := locales[language.Catalan] + var matcher = language.NewMatcher(tags) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { var locale *Locale @@ -70,21 +74,27 @@ func gettext(str string, locale *Locale) string { return locale.Get(str) } -func mustGetAvailableLanguages(db *Db) []language.Tag { - rows, err := db.Query(context.Background(), "select lang_tag from language where selectable") +type availableLanguage struct { + tag language.Tag + currencyPattern string +} + +func mustGetAvailableLanguages(db *Db) []availableLanguage { + rows, err := db.Query(context.Background(), "select lang_tag, currency_pattern from language where selectable") if err != nil { panic(err) } defer rows.Close() - var langs []language.Tag + var langs []availableLanguage for rows.Next() { var langTag string - err = rows.Scan(&langTag) + var currencyPattern string + err = rows.Scan(&langTag, ¤cyPattern) if err != nil { panic(err) } - langs = append(langs, language.MustParse(langTag)) + langs = append(langs, availableLanguage{language.MustParse(langTag), currencyPattern}) } if rows.Err() != nil { panic(rows.Err()) diff --git a/pkg/template.go b/pkg/template.go index a4e3b13..3ef5742 100644 --- a/pkg/template.go +++ b/pkg/template.go @@ -38,7 +38,7 @@ func mustRenderTemplate(wr io.Writer, r *http.Request, layout string, filename s if err != nil { f = math.NaN() } - return p.Sprintf("%.*f", company.DecimalDigits, number.Decimal(f)) + return p.Sprintf(locale.CurrencyPattern, company.DecimalDigits, number.Decimal(f), company.CurrencySymbol) }, "formatDate": func(time time.Time) string { return time.Format("02/01/2006") diff --git a/test/language.sql b/test/language.sql index d9ed368..0f65eb8 100644 --- a/test/language.sql +++ b/test/language.sql @@ -7,7 +7,7 @@ begin; set search_path to public; -select plan(23); +select plan(27); select has_table('language'); select has_pk('language'); @@ -37,6 +37,11 @@ select col_type_is('language', 'selectable', 'boolean'); select col_not_null('language', 'selectable'); select col_hasnt_default('language', 'selectable'); +select has_column('language', 'currency_pattern'); +select col_type_is('language', 'currency_pattern', 'text'); +select col_not_null('language', 'currency_pattern'); +select col_hasnt_default('language', 'currency_pattern'); + select * from finish(); diff --git a/verify/available_languages.sql b/verify/available_languages.sql index e807730..446c9ac 100644 --- a/verify/available_languages.sql +++ b/verify/available_languages.sql @@ -9,20 +9,23 @@ from language where lang_tag = 'und' and name = 'Undefined' and endonym = 'Undefined' - and not selectable; + and not selectable + and currency_pattern = '%[3]s%.[1]*[2]f'; select 1 / count(*) from language where lang_tag = 'ca' and name = 'Catalan' and endonym = 'català' - and selectable; + and selectable + and currency_pattern = '%.[1]*[2]f %[3]s'; select 1 / count(*) from language where lang_tag = 'es' and name = 'Spanish' and endonym = 'español' - and selectable; + and selectable + and currency_pattern = '%.[1]*[2]f %[3]s'; rollback; diff --git a/verify/language.sql b/verify/language.sql index d4d705c..a26b3b9 100644 --- a/verify/language.sql +++ b/verify/language.sql @@ -6,6 +6,7 @@ select lang_tag , name , endonym , selectable + , currency_pattern from public.language where false; diff --git a/web/template/invoices/products.gohtml b/web/template/invoices/products.gohtml index 9a2de2d..e6c9678 100644 --- a/web/template/invoices/products.gohtml +++ b/web/template/invoices/products.gohtml @@ -49,7 +49,7 @@ - {{ .Price | formatPrice }} + {{ .Price | formatPrice }} {{- end }} {{ else }} diff --git a/web/template/products/index.gohtml b/web/template/products/index.gohtml index 561fd43..faf70eb 100644 --- a/web/template/products/index.gohtml +++ b/web/template/products/index.gohtml @@ -29,7 +29,7 @@ {{ .Name }} - {{ .Price | formatPrice }} + {{ .Price | formatPrice }} {{- end }} {{ else }}