Add internationalization and localization to seasons
This commit is contained in:
parent
0ce1b4bd64
commit
5f38ab8fd3
|
@ -242,6 +242,15 @@ select add_season(52, 'Temporada alta', '#ff926c');
|
||||||
select add_season(52, 'Temporada mitjana', '#ffe37f');
|
select add_season(52, 'Temporada mitjana', '#ffe37f');
|
||||||
select add_season(52, 'Temporada baixa', '#00aa7d');
|
select add_season(52, 'Temporada baixa', '#00aa7d');
|
||||||
|
|
||||||
|
insert into season_i18n (season_id, lang_tag, name)
|
||||||
|
values (92, 'en', 'Peak season')
|
||||||
|
, (92, 'es', 'Temporada alta')
|
||||||
|
, (93, 'en', 'Shoulder season')
|
||||||
|
, (93, 'es', 'Temporada media')
|
||||||
|
, (94, 'en', 'Offseason')
|
||||||
|
, (94, 'es', 'Temporada baja')
|
||||||
|
;
|
||||||
|
|
||||||
select set_season_range(92, '[2023-04-06, 2023-04-10]');
|
select set_season_range(92, '[2023-04-06, 2023-04-10]');
|
||||||
select set_season_range(94, '[2023-04-11, 2023-04-27]');
|
select set_season_range(94, '[2023-04-11, 2023-04-27]');
|
||||||
select set_season_range(93, '[2023-04-28, 2023-04-30]');
|
select set_season_range(93, '[2023-04-28, 2023-04-30]');
|
||||||
|
|
|
@ -0,0 +1,22 @@
|
||||||
|
-- Deploy camper:season_i18n to pg
|
||||||
|
-- requires: roles
|
||||||
|
-- requires: schema_camper
|
||||||
|
-- requires: season
|
||||||
|
-- requires: language
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
set search_path to camper, public;
|
||||||
|
|
||||||
|
create table season_i18n (
|
||||||
|
season_id integer not null references season,
|
||||||
|
lang_tag text not null references language,
|
||||||
|
name text not null,
|
||||||
|
primary key (season_id, lang_tag)
|
||||||
|
);
|
||||||
|
|
||||||
|
grant select on table season_i18n to guest;
|
||||||
|
grant select on table season_i18n to employee;
|
||||||
|
grant select, insert, update, delete on table season_i18n to admin;
|
||||||
|
|
||||||
|
commit;
|
|
@ -0,0 +1,27 @@
|
||||||
|
-- Deploy camper:translate_season to pg
|
||||||
|
-- requires: roles
|
||||||
|
-- requires: schema_camper
|
||||||
|
-- requires: season
|
||||||
|
-- requires: season_i18n
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
set search_path to camper, public;
|
||||||
|
|
||||||
|
create or replace function translate_season(slug uuid, lang_tag text, name text) returns void as
|
||||||
|
$$
|
||||||
|
insert into season_i18n (season_id, lang_tag, name)
|
||||||
|
select season_id, translate_season.lang_tag, translate_season.name
|
||||||
|
from season
|
||||||
|
where slug = translate_season.slug
|
||||||
|
on conflict (season_id, lang_tag) do update
|
||||||
|
set name = excluded.name
|
||||||
|
;
|
||||||
|
$$
|
||||||
|
language sql
|
||||||
|
;
|
||||||
|
|
||||||
|
revoke execute on function translate_season(uuid, text, text) from public;
|
||||||
|
grant execute on function translate_season(uuid, text, text) to admin;
|
||||||
|
|
||||||
|
commit;
|
|
@ -36,7 +36,7 @@ func newAdminHandler(locales locale.Locales, mediaDir string) *adminHandler {
|
||||||
company: company.NewAdminHandler(),
|
company: company.NewAdminHandler(),
|
||||||
home: home.NewAdminHandler(locales),
|
home: home.NewAdminHandler(locales),
|
||||||
media: media.NewAdminHandler(mediaDir),
|
media: media.NewAdminHandler(mediaDir),
|
||||||
season: season.NewAdminHandler(),
|
season: season.NewAdminHandler(locales),
|
||||||
services: services.NewAdminHandler(locales),
|
services: services.NewAdminHandler(locales),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||||
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||||
"dev.tandem.ws/tandem/camper/pkg/template"
|
"dev.tandem.ws/tandem/camper/pkg/template"
|
||||||
"dev.tandem.ws/tandem/camper/pkg/uuid"
|
"dev.tandem.ws/tandem/camper/pkg/uuid"
|
||||||
)
|
)
|
||||||
|
@ -31,7 +32,7 @@ func (h *PublicHandler) Handler(user *auth.User, company *auth.Company, conn *da
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
page, err := newPublicPage(r.Context(), user, conn, head)
|
page, err := newPublicPage(r.Context(), conn, user.Locale, head)
|
||||||
if database.ErrorIsNotFound(err) {
|
if database.ErrorIsNotFound(err) {
|
||||||
http.NotFound(w, r)
|
http.NotFound(w, r)
|
||||||
return
|
return
|
||||||
|
@ -59,7 +60,7 @@ type typePrice struct {
|
||||||
PricePerNight string
|
PricePerNight string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newPublicPage(ctx context.Context, user *auth.User, conn *database.Conn, slug string) (*publicPage, error) {
|
func newPublicPage(ctx context.Context, conn *database.Conn, loc *locale.Locale, slug string) (*publicPage, error) {
|
||||||
page := &publicPage{
|
page := &publicPage{
|
||||||
PublicPage: template.NewPublicPage(),
|
PublicPage: template.NewPublicPage(),
|
||||||
}
|
}
|
||||||
|
@ -70,23 +71,23 @@ func newPublicPage(ctx context.Context, user *auth.User, conn *database.Conn, sl
|
||||||
left join campsite_type_i18n as i18n on campsite_type.campsite_type_id = i18n.campsite_type_id and i18n.lang_tag = $1
|
left join campsite_type_i18n as i18n on campsite_type.campsite_type_id = i18n.campsite_type_id and i18n.lang_tag = $1
|
||||||
where slug = $2
|
where slug = $2
|
||||||
and active
|
and active
|
||||||
`, user.Locale.Language, slug)
|
`, loc.Language, slug)
|
||||||
if err := row.Scan(&page.Name, &page.Description); err != nil {
|
if err := row.Scan(&page.Name, &page.Description); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
rows, err := conn.Query(ctx, `
|
rows, err := conn.Query(ctx, `
|
||||||
select season.name --coalesce(i18n.name, season.name) as l10n_name
|
select coalesce(i18n.name, season.name) as l10n_name
|
||||||
, to_color(season.color)
|
, to_color(season.color)
|
||||||
, coalesce(min_nights, 1)
|
, coalesce(min_nights, 1)
|
||||||
, to_price(coalesce(cost_per_night, 0))::text
|
, to_price(coalesce(cost_per_night, 0))::text
|
||||||
from season
|
from season
|
||||||
--left join season_i18n as i18n on season.season_id = i18n.season_id and i18n.lang_tag = $1
|
left join season_i18n as i18n on season.season_id = i18n.season_id and i18n.lang_tag = $1
|
||||||
left join (
|
left join (
|
||||||
campsite_type_cost as cost join campsite_type as type on cost.campsite_type_id = type.campsite_type_id and type.slug = $1
|
campsite_type_cost as cost join campsite_type as type on cost.campsite_type_id = type.campsite_type_id and type.slug = $2
|
||||||
) as cost on cost.season_id = season.season_id
|
) as cost on cost.season_id = season.season_id
|
||||||
where season.active
|
where season.active
|
||||||
`, slug)
|
`, loc.Language, slug)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/jackc/pgtype"
|
"github.com/jackc/pgtype"
|
||||||
|
"github.com/jackc/pgx/v4"
|
||||||
|
|
||||||
"dev.tandem.ws/tandem/camper/pkg/auth"
|
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||||
"dev.tandem.ws/tandem/camper/pkg/database"
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||||
|
@ -28,10 +29,13 @@ import (
|
||||||
const unsetColor = 13750495
|
const unsetColor = 13750495
|
||||||
|
|
||||||
type AdminHandler struct {
|
type AdminHandler struct {
|
||||||
|
locales locale.Locales
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewAdminHandler() *AdminHandler {
|
func NewAdminHandler(locales locale.Locales) *AdminHandler {
|
||||||
return &AdminHandler{}
|
return &AdminHandler{
|
||||||
|
locales: locales,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.HandlerFunc {
|
func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *database.Conn) http.HandlerFunc {
|
||||||
|
@ -79,13 +83,37 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
|
||||||
}
|
}
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
switch r.Method {
|
var langTag string
|
||||||
case http.MethodGet:
|
langTag, r.URL.Path = httplib.ShiftPath(r.URL.Path)
|
||||||
f.MustRender(w, r, user, company)
|
|
||||||
case http.MethodPut:
|
switch langTag {
|
||||||
editSeason(w, r, user, company, conn, f)
|
case "":
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
f.MustRender(w, r, user, company)
|
||||||
|
case http.MethodPut:
|
||||||
|
editSeason(w, r, user, company, conn, f)
|
||||||
|
default:
|
||||||
|
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
|
loc, ok := h.locales.Get(langTag)
|
||||||
|
if !ok {
|
||||||
|
http.NotFound(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
l10n := newSeasonL10nForm(f, loc)
|
||||||
|
if err := l10n.FillFromDatabase(r.Context(), conn); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
switch r.Method {
|
||||||
|
case http.MethodGet:
|
||||||
|
l10n.MustRender(w, r, user, company)
|
||||||
|
case http.MethodPut:
|
||||||
|
editSeasonL10n(w, r, user, company, conn, l10n)
|
||||||
|
default:
|
||||||
|
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -120,13 +148,22 @@ func getCalendarYear(query url.Values) int {
|
||||||
|
|
||||||
func collectSeasonEntries(ctx context.Context, company *auth.Company, conn *database.Conn) ([]*seasonEntry, error) {
|
func collectSeasonEntries(ctx context.Context, company *auth.Company, conn *database.Conn) ([]*seasonEntry, error) {
|
||||||
rows, err := conn.Query(ctx, `
|
rows, err := conn.Query(ctx, `
|
||||||
select slug
|
select '/admin/seasons/' || season.slug
|
||||||
, name
|
, season.name
|
||||||
, to_color(color)::text
|
, to_color(color)::text
|
||||||
, active
|
, active
|
||||||
|
, array_agg((lang_tag, endonym, not exists (select 1 from season_i18n as i18n where i18n.season_id = season.season_id and i18n.lang_tag = language.lang_tag)) order by endonym)
|
||||||
from season
|
from season
|
||||||
where company_id = $1
|
join company using (company_id)
|
||||||
order by name`, company.ID)
|
, language
|
||||||
|
where lang_tag <> default_lang_tag
|
||||||
|
and language.selectable
|
||||||
|
and season.company_id = $1
|
||||||
|
group by season.slug
|
||||||
|
, season.name
|
||||||
|
, to_color(color)::text
|
||||||
|
, active
|
||||||
|
order by name`, pgx.QueryResultFormats{pgx.BinaryFormatCode}, company.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -135,9 +172,17 @@ func collectSeasonEntries(ctx context.Context, company *auth.Company, conn *data
|
||||||
var seasons []*seasonEntry
|
var seasons []*seasonEntry
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
entry := &seasonEntry{}
|
entry := &seasonEntry{}
|
||||||
if err = rows.Scan(&entry.Slug, &entry.Name, &entry.Color, &entry.Active); err != nil {
|
var translations database.RecordArray
|
||||||
|
if err = rows.Scan(&entry.URL, &entry.Name, &entry.Color, &entry.Active, &translations); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
for _, el := range translations.Elements {
|
||||||
|
entry.Translations = append(entry.Translations, &locale.Translation{
|
||||||
|
URL: entry.URL + "/" + el.Fields[0].Get().(string),
|
||||||
|
Endonym: el.Fields[1].Get().(string),
|
||||||
|
Missing: el.Fields[2].Get().(bool),
|
||||||
|
})
|
||||||
|
}
|
||||||
seasons = append(seasons, entry)
|
seasons = append(seasons, entry)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,10 +190,12 @@ func collectSeasonEntries(ctx context.Context, company *auth.Company, conn *data
|
||||||
}
|
}
|
||||||
|
|
||||||
type seasonEntry struct {
|
type seasonEntry struct {
|
||||||
Slug string
|
ID int
|
||||||
Name string
|
URL string
|
||||||
Color string
|
Name string
|
||||||
Active bool
|
Color string
|
||||||
|
Active bool
|
||||||
|
Translations []*locale.Translation
|
||||||
}
|
}
|
||||||
|
|
||||||
var longMonthNames = []string{
|
var longMonthNames = []string{
|
||||||
|
@ -396,13 +443,13 @@ func newCalendarForm(ctx context.Context, company *auth.Company, conn *database.
|
||||||
|
|
||||||
func mustCollectCalendarSeasons(ctx context.Context, company *auth.Company, conn *database.Conn) []*seasonEntry {
|
func mustCollectCalendarSeasons(ctx context.Context, company *auth.Company, conn *database.Conn) []*seasonEntry {
|
||||||
rows, err := conn.Query(ctx, `
|
rows, err := conn.Query(ctx, `
|
||||||
select '0' as slug
|
select 0 as season_id
|
||||||
, $1 as name
|
, $1 as name
|
||||||
, to_color($2)::text
|
, to_color($2)::text
|
||||||
, true
|
, true
|
||||||
, 0 as sort
|
, 0 as sort
|
||||||
union all
|
union all
|
||||||
select season_id::text
|
select season_id
|
||||||
, name
|
, name
|
||||||
, to_color(color)::text
|
, to_color(color)::text
|
||||||
, active
|
, active
|
||||||
|
@ -420,7 +467,7 @@ func mustCollectCalendarSeasons(ctx context.Context, company *auth.Company, conn
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
entry := &seasonEntry{}
|
entry := &seasonEntry{}
|
||||||
var sort int
|
var sort int
|
||||||
if err = rows.Scan(&entry.Slug, &entry.Name, &entry.Color, &entry.Active, &sort); err != nil {
|
if err = rows.Scan(&entry.ID, &entry.Name, &entry.Color, &entry.Active, &sort); err != nil {
|
||||||
panic(err)
|
panic(err)
|
||||||
}
|
}
|
||||||
seasons = append(seasons, entry)
|
seasons = append(seasons, entry)
|
||||||
|
|
|
@ -0,0 +1,71 @@
|
||||||
|
/*
|
||||||
|
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
|
||||||
|
* SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
*/
|
||||||
|
|
||||||
|
package season
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"net/http"
|
||||||
|
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/auth"
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/database"
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/form"
|
||||||
|
httplib "dev.tandem.ws/tandem/camper/pkg/http"
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/locale"
|
||||||
|
"dev.tandem.ws/tandem/camper/pkg/template"
|
||||||
|
)
|
||||||
|
|
||||||
|
type seasonL10nForm struct {
|
||||||
|
Locale *locale.Locale
|
||||||
|
Slug string
|
||||||
|
Name *form.L10nInput
|
||||||
|
}
|
||||||
|
|
||||||
|
func newSeasonL10nForm(f *seasonForm, loc *locale.Locale) *seasonL10nForm {
|
||||||
|
return &seasonL10nForm{
|
||||||
|
Locale: loc,
|
||||||
|
Slug: f.Slug,
|
||||||
|
Name: f.Name.L10nInput(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l10n *seasonL10nForm) FillFromDatabase(ctx context.Context, conn *database.Conn) error {
|
||||||
|
row := conn.QueryRow(ctx, `
|
||||||
|
select coalesce(i18n.name, '') as l10n_name
|
||||||
|
from season
|
||||||
|
left join season_i18n as i18n on season.season_id = i18n.season_id and i18n.lang_tag = $1
|
||||||
|
where slug = $2
|
||||||
|
`, l10n.Locale.Language, l10n.Slug)
|
||||||
|
return row.Scan(&l10n.Name.Val)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l10n *seasonL10nForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
|
||||||
|
template.MustRenderAdmin(w, r, user, company, "season/l10n.gohtml", l10n)
|
||||||
|
}
|
||||||
|
|
||||||
|
func editSeasonL10n(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, l10n *seasonL10nForm) {
|
||||||
|
if ok, err := form.Handle(l10n, w, r, user); err != nil {
|
||||||
|
return
|
||||||
|
} else if !ok {
|
||||||
|
l10n.MustRender(w, r, user, company)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
conn.MustExec(r.Context(), "select translate_season($1, $2, $3)", l10n.Slug, l10n.Locale.Language, l10n.Name)
|
||||||
|
httplib.Redirect(w, r, "/admin/seasons", http.StatusSeeOther)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l10n *seasonL10nForm) Parse(r *http.Request) error {
|
||||||
|
if err := r.ParseForm(); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
l10n.Name.FillValue(r)
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (l10n *seasonL10nForm) Valid(l *locale.Locale) bool {
|
||||||
|
v := form.NewValidator(l)
|
||||||
|
v.CheckRequired(&l10n.Name.Input, l.GettextNoop("Name can not be empty."))
|
||||||
|
return v.AllOK
|
||||||
|
}
|
65
po/ca.po
65
po/ca.po
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: camper\n"
|
"Project-Id-Version: camper\n"
|
||||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||||
"POT-Creation-Date: 2023-10-01 21:09+0200\n"
|
"POT-Creation-Date: 2023-10-03 21:05+0200\n"
|
||||||
"PO-Revision-Date: 2023-07-22 23:45+0200\n"
|
"PO-Revision-Date: 2023-07-22 23:45+0200\n"
|
||||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||||
"Language-Team: Catalan <ca@dodds.net>\n"
|
"Language-Team: Catalan <ca@dodds.net>\n"
|
||||||
|
@ -205,6 +205,7 @@ msgstr "Traducció de la diapositiva del carrusel a %s"
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:21
|
#: web/templates/admin/carousel/l10n.gohtml:21
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:21
|
#: web/templates/admin/campsite/type/l10n.gohtml:21
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:33
|
#: web/templates/admin/campsite/type/l10n.gohtml:33
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:21
|
||||||
#: web/templates/admin/services/l10n.gohtml:21
|
#: web/templates/admin/services/l10n.gohtml:21
|
||||||
#: web/templates/admin/services/l10n.gohtml:33
|
#: web/templates/admin/services/l10n.gohtml:33
|
||||||
msgid "Source:"
|
msgid "Source:"
|
||||||
|
@ -213,6 +214,7 @@ msgstr "Origen:"
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:23
|
#: web/templates/admin/carousel/l10n.gohtml:23
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:23
|
#: web/templates/admin/campsite/type/l10n.gohtml:23
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:36
|
#: web/templates/admin/campsite/type/l10n.gohtml:36
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:23
|
||||||
#: web/templates/admin/services/l10n.gohtml:23
|
#: web/templates/admin/services/l10n.gohtml:23
|
||||||
#: web/templates/admin/services/l10n.gohtml:36
|
#: web/templates/admin/services/l10n.gohtml:36
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
|
@ -221,6 +223,7 @@ msgstr "Traducció:"
|
||||||
|
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:32
|
#: web/templates/admin/carousel/l10n.gohtml:32
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:45
|
#: web/templates/admin/campsite/type/l10n.gohtml:45
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:32
|
||||||
#: web/templates/admin/services/l10n.gohtml:45
|
#: web/templates/admin/services/l10n.gohtml:45
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Translate"
|
msgid "Translate"
|
||||||
|
@ -282,13 +285,13 @@ msgstr "Tipus"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/index.gohtml:28
|
#: web/templates/admin/campsite/index.gohtml:28
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:35
|
#: web/templates/admin/campsite/type/index.gohtml:35
|
||||||
#: web/templates/admin/season/index.gohtml:31
|
#: web/templates/admin/season/index.gohtml:39
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr "Sí"
|
msgstr "Sí"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/index.gohtml:28
|
#: web/templates/admin/campsite/index.gohtml:28
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:35
|
#: web/templates/admin/campsite/type/index.gohtml:35
|
||||||
#: web/templates/admin/season/index.gohtml:31
|
#: web/templates/admin/season/index.gohtml:39
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "No"
|
msgstr "No"
|
||||||
|
|
||||||
|
@ -317,6 +320,7 @@ msgstr "Actiu"
|
||||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||||
#: web/templates/admin/season/form.gohtml:46
|
#: web/templates/admin/season/form.gohtml:46
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:20
|
||||||
#: web/templates/admin/services/form.gohtml:52
|
#: web/templates/admin/services/form.gohtml:52
|
||||||
#: web/templates/admin/services/l10n.gohtml:20
|
#: web/templates/admin/services/l10n.gohtml:20
|
||||||
#: web/templates/admin/profile.gohtml:26
|
#: web/templates/admin/profile.gohtml:26
|
||||||
|
@ -371,6 +375,7 @@ msgid "Name"
|
||||||
msgstr "Nom"
|
msgstr "Nom"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:18
|
#: web/templates/admin/campsite/type/index.gohtml:18
|
||||||
|
#: web/templates/admin/season/index.gohtml:19
|
||||||
#: web/templates/admin/services/index.gohtml:19
|
#: web/templates/admin/services/index.gohtml:19
|
||||||
#: web/templates/admin/services/index.gohtml:60
|
#: web/templates/admin/services/index.gohtml:60
|
||||||
#: web/templates/admin/home/index.gohtml:19
|
#: web/templates/admin/home/index.gohtml:19
|
||||||
|
@ -401,7 +406,7 @@ msgid "New Season"
|
||||||
msgstr "Nova temporada"
|
msgstr "Nova temporada"
|
||||||
|
|
||||||
#: web/templates/admin/season/form.gohtml:37
|
#: web/templates/admin/season/form.gohtml:37
|
||||||
#: web/templates/admin/season/index.gohtml:19
|
#: web/templates/admin/season/index.gohtml:20
|
||||||
msgctxt "season"
|
msgctxt "season"
|
||||||
msgid "Active"
|
msgid "Active"
|
||||||
msgstr "Activa"
|
msgstr "Activa"
|
||||||
|
@ -428,15 +433,21 @@ msgctxt "header"
|
||||||
msgid "Color"
|
msgid "Color"
|
||||||
msgstr "Color"
|
msgstr "Color"
|
||||||
|
|
||||||
#: web/templates/admin/season/index.gohtml:37
|
#: web/templates/admin/season/index.gohtml:45
|
||||||
msgid "No seasons added yet."
|
msgid "No seasons added yet."
|
||||||
msgstr "No s’ha afegit cap temporada encara."
|
msgstr "No s’ha afegit cap temporada encara."
|
||||||
|
|
||||||
#: web/templates/admin/season/index.gohtml:40
|
#: web/templates/admin/season/index.gohtml:48
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr "Calendari"
|
msgstr "Calendari"
|
||||||
|
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:7
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:14
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Translate Season to %s"
|
||||||
|
msgstr "Traducció de la temporada a %s"
|
||||||
|
|
||||||
#: web/templates/admin/season/calendar.gohtml:16
|
#: web/templates/admin/season/calendar.gohtml:16
|
||||||
msgctxt "day"
|
msgctxt "day"
|
||||||
msgid "Mon"
|
msgid "Mon"
|
||||||
|
@ -836,8 +847,8 @@ msgid "Automatic"
|
||||||
msgstr "Automàtic"
|
msgstr "Automàtic"
|
||||||
|
|
||||||
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
|
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
|
||||||
#: pkg/campsite/types/admin.go:387 pkg/season/admin.go:335
|
#: pkg/campsite/types/admin.go:387 pkg/season/l10n.go:69
|
||||||
#: pkg/services/l10n.go:73 pkg/services/admin.go:266
|
#: pkg/season/admin.go:382 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||||
msgid "Name can not be empty."
|
msgid "Name can not be empty."
|
||||||
msgstr "No podeu deixar el nom en blanc."
|
msgstr "No podeu deixar el nom en blanc."
|
||||||
|
|
||||||
|
@ -923,92 +934,92 @@ msgstr "El tipus d’allotjament escollit no és vàlid."
|
||||||
msgid "Label can not be empty."
|
msgid "Label can not be empty."
|
||||||
msgstr "No podeu deixar l’etiqueta en blanc."
|
msgstr "No podeu deixar l’etiqueta en blanc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:155
|
#: pkg/season/admin.go:202
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "January"
|
msgid "January"
|
||||||
msgstr "gener"
|
msgstr "gener"
|
||||||
|
|
||||||
#: pkg/season/admin.go:156
|
#: pkg/season/admin.go:203
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "February"
|
msgid "February"
|
||||||
msgstr "febrer"
|
msgstr "febrer"
|
||||||
|
|
||||||
#: pkg/season/admin.go:157
|
#: pkg/season/admin.go:204
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr "març"
|
msgstr "març"
|
||||||
|
|
||||||
#: pkg/season/admin.go:158
|
#: pkg/season/admin.go:205
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "April"
|
msgid "April"
|
||||||
msgstr "abril"
|
msgstr "abril"
|
||||||
|
|
||||||
#: pkg/season/admin.go:159
|
#: pkg/season/admin.go:206
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "May"
|
msgid "May"
|
||||||
msgstr "maig"
|
msgstr "maig"
|
||||||
|
|
||||||
#: pkg/season/admin.go:160
|
#: pkg/season/admin.go:207
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "June"
|
msgid "June"
|
||||||
msgstr "juny"
|
msgstr "juny"
|
||||||
|
|
||||||
#: pkg/season/admin.go:161
|
#: pkg/season/admin.go:208
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "July"
|
msgid "July"
|
||||||
msgstr "juliol"
|
msgstr "juliol"
|
||||||
|
|
||||||
#: pkg/season/admin.go:162
|
#: pkg/season/admin.go:209
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "August"
|
msgid "August"
|
||||||
msgstr "agost"
|
msgstr "agost"
|
||||||
|
|
||||||
#: pkg/season/admin.go:163
|
#: pkg/season/admin.go:210
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "September"
|
msgid "September"
|
||||||
msgstr "setembre"
|
msgstr "setembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:164
|
#: pkg/season/admin.go:211
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "October"
|
msgid "October"
|
||||||
msgstr "octubre"
|
msgstr "octubre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:165
|
#: pkg/season/admin.go:212
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "November"
|
msgid "November"
|
||||||
msgstr "novembre"
|
msgstr "novembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:166
|
#: pkg/season/admin.go:213
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "December"
|
msgid "December"
|
||||||
msgstr "desembre"
|
msgstr "desembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:336
|
#: pkg/season/admin.go:383
|
||||||
msgid "Color can not be empty."
|
msgid "Color can not be empty."
|
||||||
msgstr "No podeu deixar el color en blanc."
|
msgstr "No podeu deixar el color en blanc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:337
|
#: pkg/season/admin.go:384
|
||||||
msgid "This color is not valid. It must be like #123abc."
|
msgid "This color is not valid. It must be like #123abc."
|
||||||
msgstr "Aquest color no és vàlid. Hauria de ser similar a #123abc."
|
msgstr "Aquest color no és vàlid. Hauria de ser similar a #123abc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:413
|
#: pkg/season/admin.go:460
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Unset"
|
msgid "Unset"
|
||||||
msgstr "Desassigna"
|
msgstr "Desassigna"
|
||||||
|
|
||||||
#: pkg/season/admin.go:444
|
#: pkg/season/admin.go:491
|
||||||
msgid "Start date can not be empty."
|
msgid "Start date can not be empty."
|
||||||
msgstr "No podeu deixar la data d’inici en blanc."
|
msgstr "No podeu deixar la data d’inici en blanc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:445
|
#: pkg/season/admin.go:492
|
||||||
msgid "Start date must be a valid date."
|
msgid "Start date must be a valid date."
|
||||||
msgstr "La data d’inici ha de ser una data vàlida."
|
msgstr "La data d’inici ha de ser una data vàlida."
|
||||||
|
|
||||||
#: pkg/season/admin.go:447
|
#: pkg/season/admin.go:494
|
||||||
msgid "End date can not be empty."
|
msgid "End date can not be empty."
|
||||||
msgstr "No podeu deixar la data de fi en blanc."
|
msgstr "No podeu deixar la data de fi en blanc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:448
|
#: pkg/season/admin.go:495
|
||||||
msgid "End date must be a valid date."
|
msgid "End date must be a valid date."
|
||||||
msgstr "La data de fi ha de ser una data vàlida."
|
msgstr "La data de fi ha de ser una data vàlida."
|
||||||
|
|
||||||
|
|
65
po/es.po
65
po/es.po
|
@ -8,7 +8,7 @@ msgid ""
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Project-Id-Version: camper\n"
|
"Project-Id-Version: camper\n"
|
||||||
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
|
||||||
"POT-Creation-Date: 2023-10-01 21:09+0200\n"
|
"POT-Creation-Date: 2023-10-03 21:05+0200\n"
|
||||||
"PO-Revision-Date: 2023-07-22 23:46+0200\n"
|
"PO-Revision-Date: 2023-07-22 23:46+0200\n"
|
||||||
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
|
||||||
"Language-Team: Spanish <es@tp.org.es>\n"
|
"Language-Team: Spanish <es@tp.org.es>\n"
|
||||||
|
@ -205,6 +205,7 @@ msgstr "Traducción de la diapositiva de carrusel a %s"
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:21
|
#: web/templates/admin/carousel/l10n.gohtml:21
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:21
|
#: web/templates/admin/campsite/type/l10n.gohtml:21
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:33
|
#: web/templates/admin/campsite/type/l10n.gohtml:33
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:21
|
||||||
#: web/templates/admin/services/l10n.gohtml:21
|
#: web/templates/admin/services/l10n.gohtml:21
|
||||||
#: web/templates/admin/services/l10n.gohtml:33
|
#: web/templates/admin/services/l10n.gohtml:33
|
||||||
msgid "Source:"
|
msgid "Source:"
|
||||||
|
@ -213,6 +214,7 @@ msgstr "Origen:"
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:23
|
#: web/templates/admin/carousel/l10n.gohtml:23
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:23
|
#: web/templates/admin/campsite/type/l10n.gohtml:23
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:36
|
#: web/templates/admin/campsite/type/l10n.gohtml:36
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:23
|
||||||
#: web/templates/admin/services/l10n.gohtml:23
|
#: web/templates/admin/services/l10n.gohtml:23
|
||||||
#: web/templates/admin/services/l10n.gohtml:36
|
#: web/templates/admin/services/l10n.gohtml:36
|
||||||
msgctxt "input"
|
msgctxt "input"
|
||||||
|
@ -221,6 +223,7 @@ msgstr "Traducción"
|
||||||
|
|
||||||
#: web/templates/admin/carousel/l10n.gohtml:32
|
#: web/templates/admin/carousel/l10n.gohtml:32
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:45
|
#: web/templates/admin/campsite/type/l10n.gohtml:45
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:32
|
||||||
#: web/templates/admin/services/l10n.gohtml:45
|
#: web/templates/admin/services/l10n.gohtml:45
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Translate"
|
msgid "Translate"
|
||||||
|
@ -282,13 +285,13 @@ msgstr "Tipo"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/index.gohtml:28
|
#: web/templates/admin/campsite/index.gohtml:28
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:35
|
#: web/templates/admin/campsite/type/index.gohtml:35
|
||||||
#: web/templates/admin/season/index.gohtml:31
|
#: web/templates/admin/season/index.gohtml:39
|
||||||
msgid "Yes"
|
msgid "Yes"
|
||||||
msgstr "Sí"
|
msgstr "Sí"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/index.gohtml:28
|
#: web/templates/admin/campsite/index.gohtml:28
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:35
|
#: web/templates/admin/campsite/type/index.gohtml:35
|
||||||
#: web/templates/admin/season/index.gohtml:31
|
#: web/templates/admin/season/index.gohtml:39
|
||||||
msgid "No"
|
msgid "No"
|
||||||
msgstr "No"
|
msgstr "No"
|
||||||
|
|
||||||
|
@ -317,6 +320,7 @@ msgstr "Activo"
|
||||||
#: web/templates/admin/campsite/type/form.gohtml:46
|
#: web/templates/admin/campsite/type/form.gohtml:46
|
||||||
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
#: web/templates/admin/campsite/type/l10n.gohtml:20
|
||||||
#: web/templates/admin/season/form.gohtml:46
|
#: web/templates/admin/season/form.gohtml:46
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:20
|
||||||
#: web/templates/admin/services/form.gohtml:52
|
#: web/templates/admin/services/form.gohtml:52
|
||||||
#: web/templates/admin/services/l10n.gohtml:20
|
#: web/templates/admin/services/l10n.gohtml:20
|
||||||
#: web/templates/admin/profile.gohtml:26
|
#: web/templates/admin/profile.gohtml:26
|
||||||
|
@ -371,6 +375,7 @@ msgid "Name"
|
||||||
msgstr "Nombre"
|
msgstr "Nombre"
|
||||||
|
|
||||||
#: web/templates/admin/campsite/type/index.gohtml:18
|
#: web/templates/admin/campsite/type/index.gohtml:18
|
||||||
|
#: web/templates/admin/season/index.gohtml:19
|
||||||
#: web/templates/admin/services/index.gohtml:19
|
#: web/templates/admin/services/index.gohtml:19
|
||||||
#: web/templates/admin/services/index.gohtml:60
|
#: web/templates/admin/services/index.gohtml:60
|
||||||
#: web/templates/admin/home/index.gohtml:19
|
#: web/templates/admin/home/index.gohtml:19
|
||||||
|
@ -401,7 +406,7 @@ msgid "New Season"
|
||||||
msgstr "Nueva temporada"
|
msgstr "Nueva temporada"
|
||||||
|
|
||||||
#: web/templates/admin/season/form.gohtml:37
|
#: web/templates/admin/season/form.gohtml:37
|
||||||
#: web/templates/admin/season/index.gohtml:19
|
#: web/templates/admin/season/index.gohtml:20
|
||||||
msgctxt "season"
|
msgctxt "season"
|
||||||
msgid "Active"
|
msgid "Active"
|
||||||
msgstr "Activa"
|
msgstr "Activa"
|
||||||
|
@ -428,15 +433,21 @@ msgctxt "header"
|
||||||
msgid "Color"
|
msgid "Color"
|
||||||
msgstr "Color"
|
msgstr "Color"
|
||||||
|
|
||||||
#: web/templates/admin/season/index.gohtml:37
|
#: web/templates/admin/season/index.gohtml:45
|
||||||
msgid "No seasons added yet."
|
msgid "No seasons added yet."
|
||||||
msgstr "No se ha añadido ninguna temporada todavía."
|
msgstr "No se ha añadido ninguna temporada todavía."
|
||||||
|
|
||||||
#: web/templates/admin/season/index.gohtml:40
|
#: web/templates/admin/season/index.gohtml:48
|
||||||
msgctxt "title"
|
msgctxt "title"
|
||||||
msgid "Calendar"
|
msgid "Calendar"
|
||||||
msgstr "Calendario"
|
msgstr "Calendario"
|
||||||
|
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:7
|
||||||
|
#: web/templates/admin/season/l10n.gohtml:14
|
||||||
|
msgctxt "title"
|
||||||
|
msgid "Translate Season to %s"
|
||||||
|
msgstr "Traducción de la temporada a %s"
|
||||||
|
|
||||||
#: web/templates/admin/season/calendar.gohtml:16
|
#: web/templates/admin/season/calendar.gohtml:16
|
||||||
msgctxt "day"
|
msgctxt "day"
|
||||||
msgid "Mon"
|
msgid "Mon"
|
||||||
|
@ -836,8 +847,8 @@ msgid "Automatic"
|
||||||
msgstr "Automático"
|
msgstr "Automático"
|
||||||
|
|
||||||
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
|
#: pkg/app/user.go:249 pkg/campsite/types/l10n.go:82
|
||||||
#: pkg/campsite/types/admin.go:387 pkg/season/admin.go:335
|
#: pkg/campsite/types/admin.go:387 pkg/season/l10n.go:69
|
||||||
#: pkg/services/l10n.go:73 pkg/services/admin.go:266
|
#: pkg/season/admin.go:382 pkg/services/l10n.go:73 pkg/services/admin.go:266
|
||||||
msgid "Name can not be empty."
|
msgid "Name can not be empty."
|
||||||
msgstr "No podéis dejar el nombre en blanco."
|
msgstr "No podéis dejar el nombre en blanco."
|
||||||
|
|
||||||
|
@ -923,92 +934,92 @@ msgstr "El tipo de alojamiento escogido no es válido."
|
||||||
msgid "Label can not be empty."
|
msgid "Label can not be empty."
|
||||||
msgstr "No podéis dejar la etiqueta en blanco."
|
msgstr "No podéis dejar la etiqueta en blanco."
|
||||||
|
|
||||||
#: pkg/season/admin.go:155
|
#: pkg/season/admin.go:202
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "January"
|
msgid "January"
|
||||||
msgstr "enero"
|
msgstr "enero"
|
||||||
|
|
||||||
#: pkg/season/admin.go:156
|
#: pkg/season/admin.go:203
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "February"
|
msgid "February"
|
||||||
msgstr "febrero"
|
msgstr "febrero"
|
||||||
|
|
||||||
#: pkg/season/admin.go:157
|
#: pkg/season/admin.go:204
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "March"
|
msgid "March"
|
||||||
msgstr "marzo"
|
msgstr "marzo"
|
||||||
|
|
||||||
#: pkg/season/admin.go:158
|
#: pkg/season/admin.go:205
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "April"
|
msgid "April"
|
||||||
msgstr "abril"
|
msgstr "abril"
|
||||||
|
|
||||||
#: pkg/season/admin.go:159
|
#: pkg/season/admin.go:206
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "May"
|
msgid "May"
|
||||||
msgstr "mayo"
|
msgstr "mayo"
|
||||||
|
|
||||||
#: pkg/season/admin.go:160
|
#: pkg/season/admin.go:207
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "June"
|
msgid "June"
|
||||||
msgstr "junio"
|
msgstr "junio"
|
||||||
|
|
||||||
#: pkg/season/admin.go:161
|
#: pkg/season/admin.go:208
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "July"
|
msgid "July"
|
||||||
msgstr "julio"
|
msgstr "julio"
|
||||||
|
|
||||||
#: pkg/season/admin.go:162
|
#: pkg/season/admin.go:209
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "August"
|
msgid "August"
|
||||||
msgstr "agosto"
|
msgstr "agosto"
|
||||||
|
|
||||||
#: pkg/season/admin.go:163
|
#: pkg/season/admin.go:210
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "September"
|
msgid "September"
|
||||||
msgstr "septiembre"
|
msgstr "septiembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:164
|
#: pkg/season/admin.go:211
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "October"
|
msgid "October"
|
||||||
msgstr "octubre"
|
msgstr "octubre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:165
|
#: pkg/season/admin.go:212
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "November"
|
msgid "November"
|
||||||
msgstr "noviembre"
|
msgstr "noviembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:166
|
#: pkg/season/admin.go:213
|
||||||
msgctxt "month"
|
msgctxt "month"
|
||||||
msgid "December"
|
msgid "December"
|
||||||
msgstr "diciembre"
|
msgstr "diciembre"
|
||||||
|
|
||||||
#: pkg/season/admin.go:336
|
#: pkg/season/admin.go:383
|
||||||
msgid "Color can not be empty."
|
msgid "Color can not be empty."
|
||||||
msgstr "No podéis dejar el color en blanco."
|
msgstr "No podéis dejar el color en blanco."
|
||||||
|
|
||||||
#: pkg/season/admin.go:337
|
#: pkg/season/admin.go:384
|
||||||
msgid "This color is not valid. It must be like #123abc."
|
msgid "This color is not valid. It must be like #123abc."
|
||||||
msgstr "Este color no es válido. Tiene que ser parecido a #123abc."
|
msgstr "Este color no es válido. Tiene que ser parecido a #123abc."
|
||||||
|
|
||||||
#: pkg/season/admin.go:413
|
#: pkg/season/admin.go:460
|
||||||
msgctxt "action"
|
msgctxt "action"
|
||||||
msgid "Unset"
|
msgid "Unset"
|
||||||
msgstr "Desasignar"
|
msgstr "Desasignar"
|
||||||
|
|
||||||
#: pkg/season/admin.go:444
|
#: pkg/season/admin.go:491
|
||||||
msgid "Start date can not be empty."
|
msgid "Start date can not be empty."
|
||||||
msgstr "No podéis dejar la fecha de inicio en blanco."
|
msgstr "No podéis dejar la fecha de inicio en blanco."
|
||||||
|
|
||||||
#: pkg/season/admin.go:445
|
#: pkg/season/admin.go:492
|
||||||
msgid "Start date must be a valid date."
|
msgid "Start date must be a valid date."
|
||||||
msgstr "La fecha de inicio tiene que ser una fecha válida."
|
msgstr "La fecha de inicio tiene que ser una fecha válida."
|
||||||
|
|
||||||
#: pkg/season/admin.go:447
|
#: pkg/season/admin.go:494
|
||||||
msgid "End date can not be empty."
|
msgid "End date can not be empty."
|
||||||
msgstr "No podéis dejar la fecha final en blanco."
|
msgstr "No podéis dejar la fecha final en blanco."
|
||||||
|
|
||||||
#: pkg/season/admin.go:448
|
#: pkg/season/admin.go:495
|
||||||
msgid "End date must be a valid date."
|
msgid "End date must be a valid date."
|
||||||
msgstr "La fecha final tiene que ser una fecha válida."
|
msgstr "La fecha final tiene que ser una fecha válida."
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Revert camper:season_i18n from pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
drop table if exists camper.season_i18n;
|
||||||
|
|
||||||
|
commit;
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Revert camper:translate_season from pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
drop function if exists camper.translate_season(uuid, text, text);
|
||||||
|
|
||||||
|
commit;
|
|
@ -88,3 +88,5 @@ campsite_type_cost [roles schema_camper campsite_type season user_profile] 2023-
|
||||||
parse_price [roles schema_camper] 2023-10-01T16:27:50Z jordi fita mas <jordi@tandem.blog> # Add function to format cents to prices
|
parse_price [roles schema_camper] 2023-10-01T16:27:50Z jordi fita mas <jordi@tandem.blog> # Add function to format cents to prices
|
||||||
to_price [roles schema_camper] 2023-10-01T16:30:40Z jordi fita mas <jordi@tandem.blog> # Add function to format cents to prices
|
to_price [roles schema_camper] 2023-10-01T16:30:40Z jordi fita mas <jordi@tandem.blog> # Add function to format cents to prices
|
||||||
set_campsite_type_cost [roles schema_camper campsite_type_cost parse_price] 2023-10-01T17:51:23Z jordi fita mas <jordi@tandem.blog> # Add function to set the cost of a campsite type for a given season
|
set_campsite_type_cost [roles schema_camper campsite_type_cost parse_price] 2023-10-01T17:51:23Z jordi fita mas <jordi@tandem.blog> # Add function to set the cost of a campsite type for a given season
|
||||||
|
season_i18n [roles schema_camper season language] 2023-10-03T18:30:42Z jordi fita mas <jordi@tandem.blog> # Add relation for season translations
|
||||||
|
translate_season [roles schema_camper season season_i18n] 2023-10-03T18:37:19Z jordi fita mas <jordi@tandem.blog> # Add function to translate seasons
|
||||||
|
|
|
@ -0,0 +1,44 @@
|
||||||
|
-- Test season_i18n
|
||||||
|
set client_min_messages to warning;
|
||||||
|
create extension if not exists pgtap;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select plan(23);
|
||||||
|
|
||||||
|
set search_path to camper, public;
|
||||||
|
|
||||||
|
select has_table('season_i18n');
|
||||||
|
select has_pk('season_i18n');
|
||||||
|
select col_is_pk('season_i18n', array['season_id', 'lang_tag']);
|
||||||
|
select table_privs_are('season_i18n', 'guest', array['SELECT']);
|
||||||
|
select table_privs_are('season_i18n', 'employee', array['SELECT']);
|
||||||
|
select table_privs_are('season_i18n', 'admin', array['SELECT', 'INSERT', 'UPDATE', 'DELETE']);
|
||||||
|
select table_privs_are('season_i18n', 'authenticator', array[]::text[]);
|
||||||
|
|
||||||
|
select has_column('season_i18n', 'season_id');
|
||||||
|
select col_is_fk('season_i18n', 'season_id');
|
||||||
|
select fk_ok('season_i18n', 'season_id', 'season', 'season_id');
|
||||||
|
select col_type_is('season_i18n', 'season_id', 'integer');
|
||||||
|
select col_not_null('season_i18n', 'season_id');
|
||||||
|
select col_hasnt_default('season_i18n', 'season_id');
|
||||||
|
|
||||||
|
select has_column('season_i18n', 'lang_tag');
|
||||||
|
select col_is_fk('season_i18n', 'lang_tag');
|
||||||
|
select fk_ok('season_i18n', 'lang_tag', 'language', 'lang_tag');
|
||||||
|
select col_type_is('season_i18n', 'lang_tag', 'text');
|
||||||
|
select col_not_null('season_i18n', 'lang_tag');
|
||||||
|
select col_hasnt_default('season_i18n', 'lang_tag');
|
||||||
|
|
||||||
|
select has_column('season_i18n', 'name');
|
||||||
|
select col_type_is('season_i18n', 'name', 'text');
|
||||||
|
select col_not_null('season_i18n', 'name');
|
||||||
|
select col_hasnt_default('season_i18n', 'name');
|
||||||
|
|
||||||
|
|
||||||
|
select *
|
||||||
|
from finish();
|
||||||
|
|
||||||
|
rollback;
|
||||||
|
|
|
@ -0,0 +1,68 @@
|
||||||
|
-- Test translate_season
|
||||||
|
set client_min_messages to warning;
|
||||||
|
create extension if not exists pgtap;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select plan(13);
|
||||||
|
|
||||||
|
set search_path to camper, public;
|
||||||
|
|
||||||
|
select has_function('camper', 'translate_season', array['uuid', 'text', 'text']);
|
||||||
|
select function_lang_is('camper', 'translate_season', array['uuid', 'text', 'text'], 'sql');
|
||||||
|
select function_returns('camper', 'translate_season', array['uuid', 'text', 'text'], 'void');
|
||||||
|
select isnt_definer('camper', 'translate_season', array['uuid', 'text', 'text']);
|
||||||
|
select volatility_is('camper', 'translate_season', array['uuid', 'text', 'text'], 'volatile');
|
||||||
|
select function_privs_are('camper', 'translate_season', array['uuid', 'text', 'text'], 'guest', array[]::text[]);
|
||||||
|
select function_privs_are('camper', 'translate_season', array['uuid', 'text', 'text'], 'employee', array[]::text[]);
|
||||||
|
select function_privs_are('camper', 'translate_season', array['uuid', 'text', 'text'], 'admin', array['EXECUTE']);
|
||||||
|
select function_privs_are('camper', 'translate_season', array['uuid', 'text', 'text'], 'authenticator', array[]::text[]);
|
||||||
|
|
||||||
|
set client_min_messages to warning;
|
||||||
|
truncate season_i18n cascade;
|
||||||
|
truncate season cascade;
|
||||||
|
truncate company cascade;
|
||||||
|
reset client_min_messages;
|
||||||
|
|
||||||
|
insert into company (company_id, business_name, vatin, trade_name, phone, email, web, address, city, province, postal_code, country_code, currency_code, default_lang_tag)
|
||||||
|
values (1, 'Company 2', 'XX123', '', '555-555-555', 'a@a', '', '', '', '', '', 'ES', 'EUR', 'ca')
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into season (season_id, company_id, slug, name, color, active)
|
||||||
|
values (2, 1, '87452b88-b48f-48d3-bb6c-0296de64164e', 'High', to_integer('#232323'), true)
|
||||||
|
, (3, 1, '9b6370f7-f941-46f2-bc6e-de455675bd0a', 'Low', to_integer('#323232'), false)
|
||||||
|
;
|
||||||
|
|
||||||
|
insert into season_i18n (season_id, lang_tag, name)
|
||||||
|
values (3, 'ca', 'baixa')
|
||||||
|
;
|
||||||
|
|
||||||
|
|
||||||
|
select lives_ok(
|
||||||
|
$$ select translate_season('87452b88-b48f-48d3-bb6c-0296de64164e', 'ca', 'Alta') $$,
|
||||||
|
'Should be able to translate the first season'
|
||||||
|
);
|
||||||
|
|
||||||
|
select lives_ok(
|
||||||
|
$$ select translate_season('9b6370f7-f941-46f2-bc6e-de455675bd0a', 'es', 'Baja') $$,
|
||||||
|
'Should be able to translate the second season'
|
||||||
|
);
|
||||||
|
|
||||||
|
select lives_ok(
|
||||||
|
$$ select translate_season('9b6370f7-f941-46f2-bc6e-de455675bd0a', 'ca', 'Baixa') $$,
|
||||||
|
'Should be able to overwrite the catalan translation of the second season'
|
||||||
|
);
|
||||||
|
|
||||||
|
select bag_eq(
|
||||||
|
$$ select slug::text, lang_tag, i18n.name from season_i18n as i18n join season using (season_id) $$,
|
||||||
|
$$ values ('87452b88-b48f-48d3-bb6c-0296de64164e', 'ca', 'Alta')
|
||||||
|
, ('9b6370f7-f941-46f2-bc6e-de455675bd0a', 'ca', 'Baixa')
|
||||||
|
, ('9b6370f7-f941-46f2-bc6e-de455675bd0a', 'es', 'Baja')
|
||||||
|
$$,
|
||||||
|
'Should have added and updated all translations.'
|
||||||
|
);
|
||||||
|
select *
|
||||||
|
from finish();
|
||||||
|
|
||||||
|
rollback;
|
|
@ -0,0 +1,11 @@
|
||||||
|
-- Verify camper:season_i18n on pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select season_id
|
||||||
|
, lang_tag
|
||||||
|
, name
|
||||||
|
from camper.season_i18n
|
||||||
|
where false;
|
||||||
|
|
||||||
|
rollback;
|
|
@ -0,0 +1,7 @@
|
||||||
|
-- Verify camper:translate_season on pg
|
||||||
|
|
||||||
|
begin;
|
||||||
|
|
||||||
|
select has_function_privilege('camper.translate_season(uuid, text, text)', 'execute');
|
||||||
|
|
||||||
|
rollback;
|
|
@ -48,7 +48,7 @@
|
||||||
<footer>
|
<footer>
|
||||||
<button type="submit"><span class="sr-only">{{( pgettext "Cancel" "action" )}}</span></button>
|
<button type="submit"><span class="sr-only">{{( pgettext "Cancel" "action" )}}</span></button>
|
||||||
{{ range .Seasons -}}
|
{{ range .Seasons -}}
|
||||||
<button type="submit" name="season_id" value="{{ .Slug }}">
|
<button type="submit" name="season_id" value="{{ .ID }}">
|
||||||
<svg width="20px" height="20px">
|
<svg width="20px" height="20px">
|
||||||
<circle cx="50%" cy="50%" r="49%" fill="{{ .Color }}" stroke="#000"
|
<circle cx="50%" cy="50%" r="49%" fill="{{ .Color }}" stroke="#000"
|
||||||
stroke-width=".5"/>
|
stroke-width=".5"/>
|
||||||
|
|
|
@ -16,6 +16,7 @@
|
||||||
<tr>
|
<tr>
|
||||||
<th scope="col">{{( pgettext "Color" "header" )}}</th>
|
<th scope="col">{{( pgettext "Color" "header" )}}</th>
|
||||||
<th scope="col">{{( pgettext "Name" "header" )}}</th>
|
<th scope="col">{{( pgettext "Name" "header" )}}</th>
|
||||||
|
<th scope="col">{{( pgettext "Translations" "campsite type" )}}</th>
|
||||||
<th scope="col">{{( pgettext "Active" "season" )}}</th>
|
<th scope="col">{{( pgettext "Active" "season" )}}</th>
|
||||||
</tr>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
|
@ -27,7 +28,14 @@
|
||||||
<circle cx="50%" cy="50%" r="49%" fill="{{ .Color }}" stroke="#000" stroke-width=".5"/>
|
<circle cx="50%" cy="50%" r="49%" fill="{{ .Color }}" stroke="#000" stroke-width=".5"/>
|
||||||
</svg>
|
</svg>
|
||||||
</td>
|
</td>
|
||||||
<td><a href="/admin/seasons/{{ .Slug }}">{{ .Name }}</a></td>
|
<td><a href="{{ .URL }}">{{ .Name }}</a></td>
|
||||||
|
<td>
|
||||||
|
{{ range .Translations }}
|
||||||
|
<a
|
||||||
|
{{ if .Missing }}class="missing-translation"{{ end }}
|
||||||
|
href="{{ .URL }}">{{ .Endonym }}</a>
|
||||||
|
{{ end }}
|
||||||
|
</td>
|
||||||
<td>{{ if .Active }}{{( gettext "Yes" )}}{{ else }}{{( gettext "No" )}}{{ end }}</td>
|
<td>{{ if .Active }}{{( gettext "Yes" )}}{{ else }}{{( gettext "No" )}}{{ end }}</td>
|
||||||
</tr>
|
</tr>
|
||||||
{{- end }}
|
{{- end }}
|
||||||
|
|
|
@ -0,0 +1,35 @@
|
||||||
|
<!--
|
||||||
|
SPDX-FileCopyrightText: 2023 jordi fita mas <jordi@tandem.blog>
|
||||||
|
SPDX-License-Identifier: AGPL-3.0-only
|
||||||
|
-->
|
||||||
|
{{ define "title" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/season.seasonL10nForm*/ -}}
|
||||||
|
{{printf (pgettext "Translate Season to %s" "title") .Locale.Endonym }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{ define "content" -}}
|
||||||
|
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/season.seasonL10nForm*/ -}}
|
||||||
|
<form data-hx-put="/admin/seasons/{{ .Slug }}/{{ .Locale.Language }}">
|
||||||
|
<h2>
|
||||||
|
{{printf (pgettext "Translate Season to %s" "title") .Locale.Endonym }}
|
||||||
|
</h2>
|
||||||
|
{{ CSRFInput }}
|
||||||
|
<fieldset>
|
||||||
|
{{ with .Name -}}
|
||||||
|
<fieldset>
|
||||||
|
<legend>{{( pgettext "Name" "input")}}</legend>
|
||||||
|
{{( gettext "Source:" )}} {{ .Source }}<br>
|
||||||
|
<label>
|
||||||
|
{{( pgettext "Translation:" "input" )}}
|
||||||
|
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
|
||||||
|
required {{ template "error-attrs" . }}><br>
|
||||||
|
</label>
|
||||||
|
{{ template "error-message" . }}
|
||||||
|
</fieldset>
|
||||||
|
{{- end }}
|
||||||
|
</fieldset>
|
||||||
|
<footer>
|
||||||
|
<button type="submit">{{( pgettext "Translate" "action" )}}</button>
|
||||||
|
</footer>
|
||||||
|
</form>
|
||||||
|
{{- end }}
|
Loading…
Reference in New Issue