Use I18nInput instead of L10nInput to translate carousels

This commit is contained in:
jordi fita mas 2024-01-12 19:33:44 +01:00
parent 3d0f7b0dc1
commit b6cd2f7693
9 changed files with 226 additions and 381 deletions

View File

@ -53,7 +53,7 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
case "new":
switch r.Method {
case http.MethodGet:
f := newSlideForm(h.name)
f := newSlideForm(h.name, company)
f.MustRender(w, r, user, company)
default:
httplib.MethodNotAllowed(w, r, http.MethodGet)
@ -71,7 +71,7 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
http.NotFound(w, r)
return
}
f := newSlideForm(h.name)
f := newSlideForm(h.name, company)
if err := f.FillFromDatabase(r.Context(), conn, id); err != nil {
if database.ErrorIsNotFound(err) {
http.NotFound(w, r)
@ -80,10 +80,9 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
panic(err)
}
var langTag string
langTag, r.URL.Path = httplib.ShiftPath(r.URL.Path)
head, r.URL.Path = httplib.ShiftPath(r.URL.Path)
switch langTag {
switch head {
case "":
switch r.Method {
case http.MethodGet:
@ -96,23 +95,7 @@ func (h *AdminHandler) Handler(user *auth.User, company *auth.Company, conn *dat
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut, http.MethodDelete)
}
default:
loc, ok := h.locales.Get(langTag)
if !ok {
http.NotFound(w, r)
return
}
l10n := newSlideL10nForm(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:
editSlideL10n(w, r, user, company, conn, l10n)
default:
httplib.MethodNotAllowed(w, r, http.MethodGet, http.MethodPut)
}
http.NotFound(w, r)
}
}
})
@ -183,14 +166,7 @@ func MustCollectSlides(ctx context.Context, company *auth.Company, conn *databas
type SlideEntry struct {
Slide
ID int
Translations []*Translation
}
type Translation struct {
Language string
Endonym string
Missing bool
ID int
}
func CollectSlideEntries(ctx context.Context, company *auth.Company, conn *database.Conn, carouselName string) ([]*SlideEntry, error) {
@ -198,20 +174,11 @@ func CollectSlideEntries(ctx context.Context, company *auth.Company, conn *datab
select media_id
, media.path
, caption
, array_agg((lang_tag, endonym, not exists (select 1 from %[1]s_carousel_i18n as i18n where i18n.media_id = carousel.media_id and i18n.lang_tag = language.lang_tag)) order by endonym)
from %[1]s_carousel as carousel
join media using (media_id)
join company using (company_id)
, language
where lang_tag <> default_lang_tag
and language.selectable
and media.company_id = $1
group by media_id
, media.path
, position
, caption
where media.company_id = $1
order by position, caption
`, carouselName), pgx.QueryResultFormats{pgx.BinaryFormatCode}, company.ID)
`, carouselName), company.ID)
if err != nil {
return nil, err
}
@ -220,17 +187,9 @@ func CollectSlideEntries(ctx context.Context, company *auth.Company, conn *datab
var slides []*SlideEntry
for rows.Next() {
slide := &SlideEntry{}
var translations database.RecordArray
if err = rows.Scan(&slide.ID, &slide.Media, &slide.Caption, &translations); err != nil {
if err = rows.Scan(&slide.ID, &slide.Media, &slide.Caption); err != nil {
return nil, err
}
for _, el := range translations.Elements {
slide.Translations = append(slide.Translations, &Translation{
el.Fields[0].Get().(string),
el.Fields[1].Get().(string),
el.Fields[2].Get().(bool),
})
}
slides = append(slides, slide)
}
@ -238,24 +197,47 @@ func CollectSlideEntries(ctx context.Context, company *auth.Company, conn *datab
}
func addSlide(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, carouselName string) {
f := newSlideForm(carouselName)
f.process(w, r, user, company, conn, func(ctx context.Context) {
conn.MustExec(ctx, fmt.Sprintf("select add_%s_carousel_slide($1, $2)", f.CarouselName), f.Media, f.Caption)
f := newSlideForm(carouselName, company)
f.process(w, r, user, company, conn, func(ctx context.Context, tx *database.Tx) error {
var err error
if f.ID, err = tx.GetInt(ctx, fmt.Sprintf("select add_%s_carousel_slide($1, $2)", f.CarouselName), f.Media, f.Caption[f.DefaultLang]); err != nil {
return err
}
return translateSlide(ctx, tx, company, f)
})
}
func editSlide(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *slideForm) {
f.process(w, r, user, company, conn, func(ctx context.Context) {
if f.ID == f.Media.Int() {
conn.MustExec(ctx, fmt.Sprintf("select add_%s_carousel_slide($1, $2)", f.CarouselName), f.Media, f.Caption)
} else {
tx := conn.MustBegin(ctx)
tx.MustExec(ctx, fmt.Sprintf("select add_%s_carousel_slide($1, $2)", f.CarouselName), f.Media, f.Caption)
tx.MustExec(ctx, fmt.Sprintf("update %[1]s_carousel set position = (select position from %[1]s_carousel where media_id = $2) where media_id = $1", f.CarouselName), f.Media, f.ID)
tx.MustExec(ctx, fmt.Sprintf("update %s_carousel_i18n set media_id = $1 where media_id = $2", f.CarouselName), f.Media, f.ID)
tx.MustExec(ctx, fmt.Sprintf("select remove_%s_carousel_slide($1)", f.CarouselName), f.ID)
tx.MustCommit(ctx)
func translateSlide(ctx context.Context, tx *database.Tx, company *auth.Company, f *slideForm) error {
for lang := range company.Locales {
l := lang.String()
if l == f.DefaultLang {
continue
}
if _, err := tx.Exec(ctx, fmt.Sprintf("select translate_%s_carousel_slide($1, $2, $3)", f.CarouselName), f.ID, l, f.Caption[l]); err != nil {
return err
}
}
return nil
}
func editSlide(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, f *slideForm) {
f.process(w, r, user, company, conn, func(ctx context.Context, tx *database.Tx) error {
if _, err := tx.Exec(ctx, fmt.Sprintf("select add_%s_carousel_slide($1, $2)", f.CarouselName), f.Media, f.Caption[f.DefaultLang]); err != nil {
return err
}
if f.ID != f.Media.Int() {
if _, err := tx.Exec(ctx, fmt.Sprintf("update %[1]s_carousel set position = (select position from %[1]s_carousel where media_id = $2) where media_id = $1", f.CarouselName), f.Media, f.ID); err != nil {
return err
}
if _, err := tx.Exec(ctx, fmt.Sprintf("update %s_carousel_i18n set media_id = $1 where media_id = $2", f.CarouselName), f.Media, f.ID); err != nil {
return err
}
if _, err := tx.Exec(ctx, fmt.Sprintf("select remove_%s_carousel_slide($1)", f.CarouselName), f.ID); err != nil {
return err
}
}
return translateSlide(ctx, tx, company, f)
})
}
@ -269,14 +251,16 @@ func (h *AdminHandler) deleteSlide(w http.ResponseWriter, r *http.Request, user
}
type slideForm struct {
DefaultLang string
CarouselName string
ID int
Media *form.Media
Caption *form.Input
Caption form.I18nInput
}
func newSlideForm(carouselName string) *slideForm {
func newSlideForm(carouselName string, company *auth.Company) *slideForm {
return &slideForm{
DefaultLang: company.DefaultLanguage.String(),
CarouselName: carouselName,
Media: &form.Media{
Input: &form.Input{
@ -285,24 +269,33 @@ func newSlideForm(carouselName string) *slideForm {
Label: locale.PgettextNoop("Slide image", "input"),
Prompt: locale.PgettextNoop("Set slide image", "action"),
},
Caption: &form.Input{
Name: "caption",
},
Caption: form.NewI18nInput(company.Locales, "caption"),
}
}
func (f *slideForm) FillFromDatabase(ctx context.Context, conn *database.Conn, id int) error {
f.ID = id
var caption database.RecordArray
row := conn.QueryRow(ctx, fmt.Sprintf(`
select caption
select slide.caption
, media_id::text
from %s_carousel
, array_agg((lang_tag, i18n.caption))
from %[1]s_carousel as slide
left join %[1]s_carousel_i18n as i18n using (media_id)
where media_id = $1
`, f.CarouselName), id)
return row.Scan(&f.Caption.Val, &f.Media.Val)
group by slide.caption
, media_id
`, f.CarouselName), pgx.QueryResultFormats{pgx.BinaryFormatCode}, id)
if err := row.Scan(&f.Caption[f.DefaultLang].Val, &f.Media.Val, &caption); err != nil {
return err
}
if err := f.Caption.FillArray(caption); err != nil {
return err
}
return nil
}
func (f *slideForm) process(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, act func(ctx context.Context)) {
func (f *slideForm) process(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, act func(ctx context.Context, tx *database.Tx) error) {
if err := f.Parse(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
@ -320,7 +313,15 @@ func (f *slideForm) process(w http.ResponseWriter, r *http.Request, user *auth.U
f.MustRender(w, r, user, company)
return
}
act(r.Context())
tx := conn.MustBegin(r.Context())
if err := act(r.Context(), tx); err == nil {
tx.MustCommit(r.Context())
} else {
if rErr := tx.Rollback(r.Context()); rErr != nil {
err = rErr
}
panic(err)
}
httplib.Redirect(w, r, "/admin/"+f.CarouselName, http.StatusSeeOther)
}

View File

@ -1,82 +0,0 @@
/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* SPDX-License-Identifier: AGPL-3.0-only
*/
package carousel
import (
"context"
"fmt"
"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 slideL10nForm struct {
Locale *locale.Locale
CarouselName string
ID int
Caption *form.L10nInput
}
func newSlideL10nForm(f *slideForm, loc *locale.Locale) *slideL10nForm {
return &slideL10nForm{
Locale: loc,
CarouselName: f.CarouselName,
ID: f.ID,
Caption: f.Caption.L10nInput(),
}
}
func (l10n *slideL10nForm) FillFromDatabase(ctx context.Context, conn *database.Conn) error {
row := conn.QueryRow(ctx, fmt.Sprintf(`
select coalesce(i18n.caption, '') as l10n_caption
from %[1]s_carousel as carousel
left join %[1]s_carousel_i18n as i18n on carousel.media_id = i18n.media_id and i18n.lang_tag = $1
where carousel.media_id = $2
`, l10n.CarouselName), l10n.Locale.Language, l10n.ID)
return row.Scan(&l10n.Caption.Val)
}
func (l10n *slideL10nForm) MustRender(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company) {
template.MustRenderAdmin(w, r, user, company, "carousel/l10n.gohtml", l10n)
}
func editSlideL10n(w http.ResponseWriter, r *http.Request, user *auth.User, company *auth.Company, conn *database.Conn, l10n *slideL10nForm) {
if err := l10n.Parse(r); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
return
}
if err := user.VerifyCSRFToken(r); err != nil {
http.Error(w, err.Error(), http.StatusForbidden)
return
}
if !l10n.Valid(user.Locale) {
if !httplib.IsHTMxRequest(r) {
w.WriteHeader(http.StatusUnprocessableEntity)
}
l10n.MustRender(w, r, user, company)
return
}
conn.MustExec(r.Context(), fmt.Sprintf("select translate_%s_carousel_slide($1, $2, $3)", l10n.CarouselName), l10n.ID, l10n.Locale.Language, l10n.Caption)
httplib.Redirect(w, r, "/admin/"+l10n.CarouselName, http.StatusSeeOther)
}
func (l10n *slideL10nForm) Parse(r *http.Request) error {
if err := r.ParseForm(); err != nil {
return err
}
l10n.Caption.FillValue(r)
return nil
}
func (l10n *slideL10nForm) Valid(l *locale.Locale) bool {
v := form.NewValidator(l)
return v.AllOK
}

100
po/ca.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-01-10 21:49+0100\n"
"POT-Creation-Date: 2024-01-12 19:19+0100\n"
"PO-Revision-Date: 2023-07-22 23:45+0200\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Catalan <ca@dodds.net>\n"
@ -44,7 +44,7 @@ msgstr "Ha fallat el pagament"
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
#: web/templates/admin/services/index.gohtml:66
#: web/templates/admin/services/index.gohtml:56
msgctxt "title"
msgid "Services"
msgstr "Serveis"
@ -436,7 +436,7 @@ msgid "Content"
msgstr "Contingut"
#: web/templates/admin/legal/form.gohtml:84
#: web/templates/admin/carousel/form.gohtml:47
#: web/templates/admin/carousel/form.gohtml:52
#: web/templates/admin/campsite/feature/form.gohtml:67
#: web/templates/admin/campsite/carousel/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:70
@ -450,7 +450,7 @@ msgid "Update"
msgstr "Actualitza"
#: web/templates/admin/legal/form.gohtml:86
#: web/templates/admin/carousel/form.gohtml:49
#: web/templates/admin/carousel/form.gohtml:54
#: web/templates/admin/campsite/feature/form.gohtml:69
#: web/templates/admin/campsite/carousel/form.gohtml:54
#: web/templates/admin/campsite/form.gohtml:72
@ -500,40 +500,11 @@ msgid "New Carousel Slide"
msgstr "Nova diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:20
#: web/templates/admin/campsite/carousel/form.gohtml:37
msgctxt "input"
msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/carousel/l10n.gohtml:7
#: web/templates/admin/carousel/l10n.gohtml:14
msgctxt "title"
msgid "Translate Carousel Slide to %s"
msgstr "Traducció de la diapositiva del carrusel a %s"
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/carousel/l10n.gohtml:23
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducció:"
#: web/templates/admin/carousel/l10n.gohtml:32
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Tradueix"
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
msgctxt "title"
msgid "Location Settings"
@ -634,30 +605,30 @@ msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/campsite/carousel/index.gohtml:27
#: web/templates/admin/services/index.gohtml:28
#: web/templates/admin/services/index.gohtml:74
#: web/templates/admin/home/index.gohtml:28
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:64
#: web/templates/admin/home/index.gohtml:27
msgctxt "header"
msgid "Actions"
msgstr "Accions"
#: web/templates/admin/campsite/carousel/index.gohtml:31
#: web/templates/admin/services/index.gohtml:32
#: web/templates/admin/home/index.gohtml:32
#: web/templates/admin/services/index.gohtml:31
#: web/templates/admin/home/index.gohtml:31
msgid "Are you sure you wish to delete this slide?"
msgstr "Esteu segur de voler esborrar aquesta diapositiva?"
#: web/templates/admin/campsite/carousel/index.gohtml:45
#: web/templates/admin/services/index.gohtml:54
#: web/templates/admin/services/index.gohtml:93
#: web/templates/admin/home/index.gohtml:54
#: web/templates/admin/services/index.gohtml:44
#: web/templates/admin/services/index.gohtml:83
#: web/templates/admin/home/index.gohtml:44
msgctxt "action"
msgid "Delete"
msgstr "Esborra"
#: web/templates/admin/campsite/carousel/index.gohtml:54
#: web/templates/admin/services/index.gohtml:63
#: web/templates/admin/home/index.gohtml:63
#: web/templates/admin/services/index.gohtml:53
#: web/templates/admin/home/index.gohtml:53
msgid "No slides added yet."
msgstr "No sha afegit cap diapositiva encara."
@ -909,9 +880,7 @@ msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:27
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:73
#: web/templates/admin/home/index.gohtml:27
#: web/templates/admin/services/index.gohtml:63
msgctxt "header"
msgid "Translations"
msgstr "Traduccions"
@ -926,6 +895,25 @@ msgctxt "title"
msgid "Translate Season to %s"
msgstr "Traducció de la temporada a %s"
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducció:"
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Tradueix"
#: web/templates/admin/season/calendar.gohtml:49
#: web/templates/admin/media/picker.gohtml:61
msgctxt "action"
@ -1013,21 +1001,21 @@ msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/services/index.gohtml:67
#: web/templates/admin/services/index.gohtml:57
msgctxt "action"
msgid "Add service"
msgstr "Afegeix servei"
#: web/templates/admin/services/index.gohtml:72
#: web/templates/admin/services/index.gohtml:62
msgctxt "header"
msgid "Service"
msgstr "Servei"
#: web/templates/admin/services/index.gohtml:78
#: web/templates/admin/services/index.gohtml:68
msgid "Are you sure you wish to delete this service?"
msgstr "Esteu segur de voler esborrar aquest servei?"
#: web/templates/admin/services/index.gohtml:101
#: web/templates/admin/services/index.gohtml:91
msgid "No services added yet."
msgstr "No sha afegit cap servei encara."
@ -1234,21 +1222,21 @@ msgstr "No podeu deixar el nom en blanc."
msgid "Name must have at least one letter."
msgstr "El nom ha de tenir com a mínim una lletra."
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:223
#: pkg/carousel/admin.go:269 pkg/campsite/types/carousel.go:223
msgctxt "input"
msgid "Slide image"
msgstr "Imatge de la diapositiva"
#: pkg/carousel/admin.go:286 pkg/campsite/types/carousel.go:224
#: pkg/carousel/admin.go:270 pkg/campsite/types/carousel.go:224
msgctxt "action"
msgid "Set slide image"
msgstr "Estableix la imatge de la diapositiva"
#: pkg/carousel/admin.go:338 pkg/campsite/types/carousel.go:297
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:297
msgid "Slide image can not be empty."
msgstr "No podeu deixar la imatge de la diapositiva en blanc."
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:298
#: pkg/carousel/admin.go:340 pkg/campsite/types/carousel.go:298
msgid "Slide image must be an image media type."
msgstr "La imatge de la diapositiva ha de ser un mèdia de tipus imatge."
@ -1650,6 +1638,10 @@ msgstr "El valor de %s ha de ser com a mínim %d."
msgid "%s must be at most %d."
msgstr "El valor de %s ha de ser com a màxim %d."
#~ msgctxt "title"
#~ msgid "Translate Carousel Slide to %s"
#~ msgstr "Traducció de la diapositiva del carrusel a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Feature to %s"
#~ msgstr "Traducció de la característica del tipus dallotjament a %s"

100
po/es.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-01-10 21:49+0100\n"
"POT-Creation-Date: 2024-01-12 19:19+0100\n"
"PO-Revision-Date: 2023-07-22 23:46+0200\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
@ -44,7 +44,7 @@ msgstr "Pago fallido"
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
#: web/templates/admin/services/index.gohtml:66
#: web/templates/admin/services/index.gohtml:56
msgctxt "title"
msgid "Services"
msgstr "Servicios"
@ -436,7 +436,7 @@ msgid "Content"
msgstr "Contenido"
#: web/templates/admin/legal/form.gohtml:84
#: web/templates/admin/carousel/form.gohtml:47
#: web/templates/admin/carousel/form.gohtml:52
#: web/templates/admin/campsite/feature/form.gohtml:67
#: web/templates/admin/campsite/carousel/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:70
@ -450,7 +450,7 @@ msgid "Update"
msgstr "Actualizar"
#: web/templates/admin/legal/form.gohtml:86
#: web/templates/admin/carousel/form.gohtml:49
#: web/templates/admin/carousel/form.gohtml:54
#: web/templates/admin/campsite/feature/form.gohtml:69
#: web/templates/admin/campsite/carousel/form.gohtml:54
#: web/templates/admin/campsite/form.gohtml:72
@ -500,40 +500,11 @@ msgid "New Carousel Slide"
msgstr "Nueva diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:20
#: web/templates/admin/campsite/carousel/form.gohtml:37
msgctxt "input"
msgid "Caption"
msgstr "Leyenda"
#: web/templates/admin/carousel/l10n.gohtml:7
#: web/templates/admin/carousel/l10n.gohtml:14
msgctxt "title"
msgid "Translate Carousel Slide to %s"
msgstr "Traducción de la diapositiva de carrusel a %s"
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/carousel/l10n.gohtml:23
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducción"
#: web/templates/admin/carousel/l10n.gohtml:32
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Traducir"
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
msgctxt "title"
msgid "Location Settings"
@ -634,30 +605,30 @@ msgid "Caption"
msgstr "Leyenda"
#: web/templates/admin/campsite/carousel/index.gohtml:27
#: web/templates/admin/services/index.gohtml:28
#: web/templates/admin/services/index.gohtml:74
#: web/templates/admin/home/index.gohtml:28
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:64
#: web/templates/admin/home/index.gohtml:27
msgctxt "header"
msgid "Actions"
msgstr "Acciones"
#: web/templates/admin/campsite/carousel/index.gohtml:31
#: web/templates/admin/services/index.gohtml:32
#: web/templates/admin/home/index.gohtml:32
#: web/templates/admin/services/index.gohtml:31
#: web/templates/admin/home/index.gohtml:31
msgid "Are you sure you wish to delete this slide?"
msgstr "¿Estáis seguro de querer borrar esta diapositiva?"
#: web/templates/admin/campsite/carousel/index.gohtml:45
#: web/templates/admin/services/index.gohtml:54
#: web/templates/admin/services/index.gohtml:93
#: web/templates/admin/home/index.gohtml:54
#: web/templates/admin/services/index.gohtml:44
#: web/templates/admin/services/index.gohtml:83
#: web/templates/admin/home/index.gohtml:44
msgctxt "action"
msgid "Delete"
msgstr "Borrar"
#: web/templates/admin/campsite/carousel/index.gohtml:54
#: web/templates/admin/services/index.gohtml:63
#: web/templates/admin/home/index.gohtml:63
#: web/templates/admin/services/index.gohtml:53
#: web/templates/admin/home/index.gohtml:53
msgid "No slides added yet."
msgstr "No se ha añadido ninguna diapositiva todavía."
@ -909,9 +880,7 @@ msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:27
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:73
#: web/templates/admin/home/index.gohtml:27
#: web/templates/admin/services/index.gohtml:63
msgctxt "header"
msgid "Translations"
msgstr "Traducciones"
@ -926,6 +895,25 @@ msgctxt "title"
msgid "Translate Season to %s"
msgstr "Traducción de la temporada a %s"
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Origen:"
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traducción"
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Traducir"
#: web/templates/admin/season/calendar.gohtml:49
#: web/templates/admin/media/picker.gohtml:61
msgctxt "action"
@ -1013,21 +1001,21 @@ msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/services/index.gohtml:67
#: web/templates/admin/services/index.gohtml:57
msgctxt "action"
msgid "Add service"
msgstr "Añadir servicio"
#: web/templates/admin/services/index.gohtml:72
#: web/templates/admin/services/index.gohtml:62
msgctxt "header"
msgid "Service"
msgstr "Servicio"
#: web/templates/admin/services/index.gohtml:78
#: web/templates/admin/services/index.gohtml:68
msgid "Are you sure you wish to delete this service?"
msgstr "¿Estáis seguro de querer borrar este servicio?"
#: web/templates/admin/services/index.gohtml:101
#: web/templates/admin/services/index.gohtml:91
msgid "No services added yet."
msgstr "No se ha añadido ningún servicio todavía."
@ -1234,21 +1222,21 @@ msgstr "No podéis dejar el nombre en blanco."
msgid "Name must have at least one letter."
msgstr "El nombre tiene que tener como mínimo una letra."
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:223
#: pkg/carousel/admin.go:269 pkg/campsite/types/carousel.go:223
msgctxt "input"
msgid "Slide image"
msgstr "Imagen de la diapositiva"
#: pkg/carousel/admin.go:286 pkg/campsite/types/carousel.go:224
#: pkg/carousel/admin.go:270 pkg/campsite/types/carousel.go:224
msgctxt "action"
msgid "Set slide image"
msgstr "Establecer la imagen de la diapositiva"
#: pkg/carousel/admin.go:338 pkg/campsite/types/carousel.go:297
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:297
msgid "Slide image can not be empty."
msgstr "No podéis dejar la imagen de la diapositiva en blanco."
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:298
#: pkg/carousel/admin.go:340 pkg/campsite/types/carousel.go:298
msgid "Slide image must be an image media type."
msgstr "La imagen de la diapositiva tiene que ser un medio de tipo imagen."
@ -1650,6 +1638,10 @@ msgstr "%s tiene que ser como mínimo %d."
msgid "%s must be at most %d."
msgstr "%s tiene que ser como máximo %d"
#~ msgctxt "title"
#~ msgid "Translate Carousel Slide to %s"
#~ msgstr "Traducción de la diapositiva de carrusel a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Feature to %s"
#~ msgstr "Traducción de la característica del tipo de alojamiento a %s"

100
po/fr.po
View File

@ -8,7 +8,7 @@ msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-01-10 21:49+0100\n"
"POT-Creation-Date: 2024-01-12 19:19+0100\n"
"PO-Revision-Date: 2023-12-20 10:13+0100\n"
"Last-Translator: Oriol Carbonell <info@oriolcarbonell.cat>\n"
"Language-Team: French <traduc@traduc.org>\n"
@ -45,7 +45,7 @@ msgstr "Le paiement a échoué"
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
#: web/templates/admin/services/index.gohtml:66
#: web/templates/admin/services/index.gohtml:56
msgctxt "title"
msgid "Services"
msgstr "Services"
@ -437,7 +437,7 @@ msgid "Content"
msgstr "Contenu"
#: web/templates/admin/legal/form.gohtml:84
#: web/templates/admin/carousel/form.gohtml:47
#: web/templates/admin/carousel/form.gohtml:52
#: web/templates/admin/campsite/feature/form.gohtml:67
#: web/templates/admin/campsite/carousel/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:70
@ -451,7 +451,7 @@ msgid "Update"
msgstr "Mettre à jour"
#: web/templates/admin/legal/form.gohtml:86
#: web/templates/admin/carousel/form.gohtml:49
#: web/templates/admin/carousel/form.gohtml:54
#: web/templates/admin/campsite/feature/form.gohtml:69
#: web/templates/admin/campsite/carousel/form.gohtml:54
#: web/templates/admin/campsite/form.gohtml:72
@ -501,40 +501,11 @@ msgid "New Carousel Slide"
msgstr "Nouveau toboggan carrousel"
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/carousel/l10n.gohtml:20
#: web/templates/admin/campsite/carousel/form.gohtml:37
msgctxt "input"
msgid "Caption"
msgstr "Légende"
#: web/templates/admin/carousel/l10n.gohtml:7
#: web/templates/admin/carousel/l10n.gohtml:14
msgctxt "title"
msgid "Translate Carousel Slide to %s"
msgstr "Traduire la diapositive Carousel en %s"
#: web/templates/admin/carousel/l10n.gohtml:21
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Source :"
#: web/templates/admin/carousel/l10n.gohtml:23
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traduction :"
#: web/templates/admin/carousel/l10n.gohtml:32
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Traduire"
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
msgctxt "title"
msgid "Location Settings"
@ -635,30 +606,30 @@ msgid "Caption"
msgstr "Légende"
#: web/templates/admin/campsite/carousel/index.gohtml:27
#: web/templates/admin/services/index.gohtml:28
#: web/templates/admin/services/index.gohtml:74
#: web/templates/admin/home/index.gohtml:28
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:64
#: web/templates/admin/home/index.gohtml:27
msgctxt "header"
msgid "Actions"
msgstr "Actions"
#: web/templates/admin/campsite/carousel/index.gohtml:31
#: web/templates/admin/services/index.gohtml:32
#: web/templates/admin/home/index.gohtml:32
#: web/templates/admin/services/index.gohtml:31
#: web/templates/admin/home/index.gohtml:31
msgid "Are you sure you wish to delete this slide?"
msgstr "Êtes-vous sûr de vouloir supprimer cette diapositive ?"
#: web/templates/admin/campsite/carousel/index.gohtml:45
#: web/templates/admin/services/index.gohtml:54
#: web/templates/admin/services/index.gohtml:93
#: web/templates/admin/home/index.gohtml:54
#: web/templates/admin/services/index.gohtml:44
#: web/templates/admin/services/index.gohtml:83
#: web/templates/admin/home/index.gohtml:44
msgctxt "action"
msgid "Delete"
msgstr "Supprimer"
#: web/templates/admin/campsite/carousel/index.gohtml:54
#: web/templates/admin/services/index.gohtml:63
#: web/templates/admin/home/index.gohtml:63
#: web/templates/admin/services/index.gohtml:53
#: web/templates/admin/home/index.gohtml:53
msgid "No slides added yet."
msgstr "Aucune diapositive na encore été ajoutée."
@ -910,9 +881,7 @@ msgid "Color"
msgstr "Couleur"
#: web/templates/admin/season/index.gohtml:27
#: web/templates/admin/services/index.gohtml:27
#: web/templates/admin/services/index.gohtml:73
#: web/templates/admin/home/index.gohtml:27
#: web/templates/admin/services/index.gohtml:63
msgctxt "header"
msgid "Translations"
msgstr "Traductions"
@ -927,6 +896,25 @@ msgctxt "title"
msgid "Translate Season to %s"
msgstr "Traduire Season en %s"
#: web/templates/admin/season/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:21
#: web/templates/admin/services/l10n.gohtml:33
msgid "Source:"
msgstr "Source :"
#: web/templates/admin/season/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:23
#: web/templates/admin/services/l10n.gohtml:36
msgctxt "input"
msgid "Translation:"
msgstr "Traduction :"
#: web/templates/admin/season/l10n.gohtml:32
#: web/templates/admin/services/l10n.gohtml:45
msgctxt "action"
msgid "Translate"
msgstr "Traduire"
#: web/templates/admin/season/calendar.gohtml:49
#: web/templates/admin/media/picker.gohtml:61
msgctxt "action"
@ -1014,21 +1002,21 @@ msgctxt "title"
msgid "Carousel"
msgstr "Carrousel"
#: web/templates/admin/services/index.gohtml:67
#: web/templates/admin/services/index.gohtml:57
msgctxt "action"
msgid "Add service"
msgstr "Ajouter un service"
#: web/templates/admin/services/index.gohtml:72
#: web/templates/admin/services/index.gohtml:62
msgctxt "header"
msgid "Service"
msgstr "Service"
#: web/templates/admin/services/index.gohtml:78
#: web/templates/admin/services/index.gohtml:68
msgid "Are you sure you wish to delete this service?"
msgstr "Êtes-vous sûr de vouloir supprimer ce service ?"
#: web/templates/admin/services/index.gohtml:101
#: web/templates/admin/services/index.gohtml:91
msgid "No services added yet."
msgstr "Aucun service na encore été ajouté."
@ -1235,21 +1223,21 @@ msgstr "Le nom ne peut pas être laissé vide."
msgid "Name must have at least one letter."
msgstr "Le nom doit comporter au moins une lettre."
#: pkg/carousel/admin.go:285 pkg/campsite/types/carousel.go:223
#: pkg/carousel/admin.go:269 pkg/campsite/types/carousel.go:223
msgctxt "input"
msgid "Slide image"
msgstr "Image du diaporama"
#: pkg/carousel/admin.go:286 pkg/campsite/types/carousel.go:224
#: pkg/carousel/admin.go:270 pkg/campsite/types/carousel.go:224
msgctxt "action"
msgid "Set slide image"
msgstr "Définir limage de la diapositive"
#: pkg/carousel/admin.go:338 pkg/campsite/types/carousel.go:297
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:297
msgid "Slide image can not be empty."
msgstr "Limage de la diapositive ne peut pas être vide."
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:298
#: pkg/carousel/admin.go:340 pkg/campsite/types/carousel.go:298
msgid "Slide image must be an image media type."
msgstr "Limage de la diapositive doit être de type média dimage."
@ -1651,6 +1639,10 @@ msgstr "%s doit être %d ou plus."
msgid "%s must be at most %d."
msgstr "%s doit être tout au plus %d."
#~ msgctxt "title"
#~ msgid "Translate Carousel Slide to %s"
#~ msgstr "Traduire la diapositive Carousel en %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Feature to %s"
#~ msgstr "Traduire Caractéristique de type de camping en %s"

View File

@ -28,17 +28,22 @@
{{ end }}
</h2>
{{ CSRFInput }}
<fieldset>
<fieldset x-data="{ lang: '{{ .DefaultLang }}' }">
{{ with .Media -}}
{{ template "media-picker" . }}
{{- end }}
{{ with .Caption -}}
<label>
{{( pgettext "Caption" "input")}}<br>
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
{{ template "error-attrs" . }}><br>
</label>
{{ template "error-message" . }}
<fieldset>
<legend>{{( pgettext "Caption" "input")}}</legend>
{{ template "lang-selector" . }}
{{ range $lang, $input := . -}}
<label x-cloak x-show="lang === '{{ $lang }}'"><span>{{ $lang }}</span><br>
<input type="text" name="{{ $input.Name }}" value="{{ $input.Val }}"
{{ template "error-attrs" . }}><br>
</label>
{{- end }}
{{ template "error-message" . }}
</fieldset>
{{- end }}
</fieldset>
<footer>

View File

@ -1,35 +0,0 @@
<!--
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/carousel.slideL10nForm*/ -}}
{{printf (pgettext "Translate Carousel Slide to %s" "title") .Locale.Endonym }}
{{- end }}
{{ define "content" -}}
{{- /*gotype: dev.tandem.ws/tandem/camper/pkg/carousel.slideL10nForm*/ -}}
<form data-hx-put="/admin/home/slides/{{ .ID }}/{{ .Locale.Language }}">
<h2>
{{printf (pgettext "Translate Carousel Slide to %s" "title") .Locale.Endonym }}
</h2>
{{ CSRFInput }}
<fieldset>
{{ with .Caption -}}
<fieldset>
<legend>{{( pgettext "Caption" "input")}}</legend>
{{( gettext "Source:" )}} {{ .Source }}<br>
<label>
{{( pgettext "Translation:" "input" )}}
<input type="text" name="{{ .Name }}" value="{{ .Val }}"
{{ template "error-attrs" . }}><br>
</label>
{{ template "error-message" . }}
</fieldset>
{{- end }}
</fieldset>
<footer>
<button type="submit">{{( pgettext "Translate" "action" )}}</button>
</footer>
</form>
{{- end }}

View File

@ -24,7 +24,6 @@
<tr>
<th scope="col">{{( pgettext "Image" "header" )}}</th>
<th scope="col">{{( pgettext "Caption" "header" )}}</th>
<th scope="col">{{( pgettext "Translations" "header" )}}</th>
<th scope="col">{{( pgettext "Actions" "header" )}}</th>
</tr>
</thead>
@ -38,15 +37,6 @@
<a href="/admin/home/slides/{{ .ID }}"><img src="{{ .Media }}" alt=""></a>
</td>
<td><a href="/admin/home/slides/{{ .ID }}">{{ .Caption }}</a></td>
<td>
{{ range .Translations }}
<a
{{ if .Missing }}
class="missing-translation"
{{ end }}
href="/admin/home/slides/{{ $slide.ID }}/{{ .Language }}">{{ .Endonym }}</a>
{{ end }}
</td>
<td>
<form data-hx-delete="/admin/home/slides/{{ .ID }}"
data-hx-confirm="{{ $confirm }}"

View File

@ -24,7 +24,6 @@
<tr>
<th scope="col">{{( pgettext "Image" "header" )}}</th>
<th scope="col">{{( pgettext "Caption" "header" )}}</th>
<th scope="col">{{( pgettext "Translations" "header" )}}</th>
<th scope="col">{{( pgettext "Actions" "header" )}}</th>
</tr>
</thead>
@ -38,15 +37,6 @@
<a href="/admin/services/slides/{{ .ID }}"><img src="{{ .Media }}" alt=""></a>
</td>
<td><a href="/admin/services/slides/{{ .ID }}">{{ .Caption }}</a></td>
<td>
{{ range .Translations }}
<a
{{ if .Missing }}
class="missing-translation"
{{ end }}
href="/admin/services/slides/{{ $slide.ID }}/{{ .Language }}">{{ .Endonym }}</a>
{{ end }}
</td>
<td>
<form data-hx-delete="/admin/services/slides/{{ .ID }}"
data-hx-confirm="{{ $confirm }}"