camper/po/ca.po

2319 lines
67 KiB
Plaintext
Raw Normal View History

Add the skeleton of the web application It does nothing more than to server a single page that does nothing interesting. This time i do not use a router. Instead, i am trying out a technique i have seen in an article[0] that i have tried in other, smaller, projects and seems to work surprisingly well: it just “cuts off” the URI path by path, passing the request from handler to handler until it finds its way to a handler that actually serves the request. That helps to loosen the coupling between the application and lower handlers, and makes dependencies explicit, because i need to pass the locale, company, etc. down instead of storing them in contexts. Let’s see if i do not regret it on a later date. I also made a lot more packages that in Numerus. In Numerus i actually only have the single pkg package, and it works, kind of, but i notice how i name my methods to avoid clashing instead of using packages for that. That is, instead of pkg.NewApp i now have app.New. Initially i thought that Locale should be inside app, but then there was a circular dependency between app and template. That is why i created a separate package, but now i am wondering if template should be inside app too, but then i would have app.MustRenderTemplate instead of template.MustRender. The CSS is the most bare-bones file i could write because i am focusing in markup right now; Oriol will fill in the file once the application is working. [0]: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/
2023-07-22 22:11:00 +00:00
# Catalan translations for camper package
# Traduccions al català del paquet «camper».
# Copyright (C) 2023 THE camper'S COPYRIGHT HOLDER
# This file is distributed under the same license as the camper package.
# jordi fita mas <jordi@tandem.blog>, 2023.
#
msgid ""
msgstr ""
"Project-Id-Version: camper\n"
"Report-Msgid-Bugs-To: jordi@tandem.blog\n"
"POT-Creation-Date: 2024-01-27 22:29+0100\n"
Add the skeleton of the web application It does nothing more than to server a single page that does nothing interesting. This time i do not use a router. Instead, i am trying out a technique i have seen in an article[0] that i have tried in other, smaller, projects and seems to work surprisingly well: it just “cuts off” the URI path by path, passing the request from handler to handler until it finds its way to a handler that actually serves the request. That helps to loosen the coupling between the application and lower handlers, and makes dependencies explicit, because i need to pass the locale, company, etc. down instead of storing them in contexts. Let’s see if i do not regret it on a later date. I also made a lot more packages that in Numerus. In Numerus i actually only have the single pkg package, and it works, kind of, but i notice how i name my methods to avoid clashing instead of using packages for that. That is, instead of pkg.NewApp i now have app.New. Initially i thought that Locale should be inside app, but then there was a circular dependency between app and template. That is why i created a separate package, but now i am wondering if template should be inside app too, but then i would have app.MustRenderTemplate instead of template.MustRender. The CSS is the most bare-bones file i could write because i am focusing in markup right now; Oriol will fill in the file once the application is working. [0]: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/
2023-07-22 22:11:00 +00:00
"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"
"Language: ca\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: web/templates/public/payment/success.gohtml:6
#: web/templates/public/payment/success.gohtml:11
msgctxt "title"
msgid "Payment Successful"
msgstr "Pagament amb èxit"
#: web/templates/public/payment/request.gohtml:6
#: web/templates/public/payment/request.gohtml:11
msgctxt "title"
msgid "Payment"
msgstr "Pagament"
#: web/templates/public/payment/request.gohtml:23
msgctxt "action"
msgid "Pay"
msgstr "Paga"
#: web/templates/public/payment/failure.gohtml:6
#: web/templates/public/payment/failure.gohtml:11
msgctxt "title"
msgid "Payment Failed"
msgstr "Ha fallat el pagament"
#: web/templates/public/services.gohtml:7
#: web/templates/public/services.gohtml:16
#: web/templates/public/layout.gohtml:67 web/templates/public/layout.gohtml:95
#: web/templates/admin/services/index.gohtml:59
msgctxt "title"
msgid "Services"
msgstr "Serveis"
#: web/templates/public/services.gohtml:19
msgid "The campsite offers many different services."
msgstr "El càmping disposa de diversos serveis."
#: web/templates/public/amenity.gohtml:39
#: web/templates/public/campsite/type.gohtml:112
#: web/templates/public/campsite/page.gohtml:39
msgctxt "title"
msgid "Features"
msgstr "Característiques"
#: web/templates/public/location.gohtml:7
#: web/templates/public/location.gohtml:13
#: web/templates/public/layout.gohtml:69 web/templates/public/layout.gohtml:97
#: web/templates/admin/layout.gohtml:64
msgctxt "title"
msgid "Location"
msgstr "Com arribar"
#: web/templates/public/home.gohtml:7 web/templates/public/layout.gohtml:53
#: web/templates/public/layout.gohtml:93
Split templates and handlers into admin and public I need to check that the user is an employee (or admin) in administration handlers, but i do not want to do it for each handler, because i am bound to forget it. Thus, i added the /admin sub-path for these resources. The public-facing web is the rest of the resources outside /admin, but for now there is only home, to test whether it works as expected or not. The public-facing web can not relay on the user’s language settings, as the guest user has no way to set that. I would be happy to just use the Accept-Language header for that, but apparently Google does not use that header[0], and they give four alternatives: a country-specific domain, a subdomain with a generic top-level domain (gTLD), subdirectories with a gTLD, or URL parameters (e.g., site.com?loc=de). Of the four, Google does not recommend URL parameters, and the customer is already using subdirectories with the current site, therefor that’s what i have chosen. Google also tells me that it is a very good idea to have links between localized version of the same resources, either with <link> elements, Link HTTP response headers, or a sitemap file[1]; they are all equivalent in the eyes of Google. I have choosen the Link response headers way, because for that i can simply “augment” ResponseHeader to automatically add these headers when the response status is 2xx, otherwise i would need to pass down the original URL path until it reaches the template. Even though Camper is supposed to be a “generic”, multi-company application, i think i will stick to the easiest route and write the templates for just the “first” customer. [0]: https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites [1]: https://developers.google.com/search/docs/specialty/international/localized-versions
2023-08-05 01:42:37 +00:00
msgctxt "title"
msgid "Home"
msgstr "Inici"
#: web/templates/public/home.gohtml:25
msgctxt "link"
msgid "Booking"
msgstr "Reserva"
#: web/templates/public/home.gohtml:28
msgid "The pleasure of camping in the middle of nature…"
msgstr "El plaer dacampar en plena natura…"
#: web/templates/public/home.gohtml:40
msgid "Our services"
msgstr "Els nostres serveis"
#: web/templates/public/home.gohtml:44
#: web/templates/public/surroundings.gohtml:7
#: web/templates/public/surroundings.gohtml:12
#: web/templates/public/layout.gohtml:68 web/templates/public/layout.gohtml:96
#: web/templates/admin/surroundings/form.gohtml:15
#: web/templates/admin/layout.gohtml:67
msgctxt "title"
msgid "Surroundings"
msgstr "Lentorn"
#: web/templates/public/home.gohtml:47
msgid "Located in <strong>Alta Garrotxa</strong>, between the <strong>Pyrenees</strong> and the <strong>Costa Brava</strong>."
msgstr "Situats a l<strong>Alta Garrotxa</strong>, entre els <strong>Pirineus</strong> i la <strong>Costa Brava</strong>."
#: web/templates/public/home.gohtml:48
msgid "Nearby there are the <strong>gorges of Sadernes</strong>, <strong>volcanoes</strong>, <strong>La Fageda den Jordà</strong>, the Jewish quarter of <strong>Besalú</strong>, the basaltic cliff of <strong>Castellfollit de la Roca</strong>… much to see and much to do."
msgstr "A prop teniu els <strong>gorgs de Sadernes</strong>, <strong>volcans</strong>, <strong>La Fageda den Jordà</strong>, el call jueu de <strong>Besalú</strong>, la cinglera basàltica de <strong>Castellfollit de la Roca</strong>… molt per veure i molt per fer."
#: web/templates/public/home.gohtml:49
msgid "Less than an hour from <strong>Girona</strong>, one from <strong>La Bisbal dEmpordà</strong>, and two from <strong>Barcelona</strong>."
msgstr "A menys duna hora de <strong>Girona</strong>, a una de <strong>La Bisbal dEmpordà</strong> i a dues de <strong>Barcelona</strong>."
#: web/templates/public/home.gohtml:50
msgid "Discover the surroundings"
msgstr "Descobreix lentorn"
#: web/templates/public/campsite/type.gohtml:41
msgctxt "input"
msgid "Check-in Date"
msgstr "Data dentrada"
#: web/templates/public/campsite/type.gohtml:47
msgctxt "input"
msgid "Check-out Date"
msgstr "Data de sortida"
#: web/templates/public/campsite/type.gohtml:54
#: web/templates/public/booking.gohtml:164
msgctxt "action"
msgid "Book"
msgstr "Reserva"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:62
#: web/templates/admin/season/index.gohtml:54
2023-12-22 02:32:40 +00:00
msgctxt "title"
msgid "Calendar"
msgstr "Calendari"
#: web/templates/public/campsite/type.gohtml:73
#: web/templates/admin/campsite/type/form.gohtml:109
#: web/templates/admin/campsite/type/option/form.gohtml:70
2023-10-01 19:14:39 +00:00
msgctxt "title"
msgid "Prices"
msgstr "Preus"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:85
#: web/templates/public/campsite/type.gohtml:91
2023-12-22 02:32:40 +00:00
msgid "%s: %s €/night"
msgstr "%s: %s €/nit"
#: web/templates/public/campsite/type.gohtml:87
msgid "%s €/night"
msgstr "%s €/nit"
#: web/templates/public/campsite/type.gohtml:94
2023-10-01 19:14:39 +00:00
msgid "*Minimum %d nights per stay"
msgstr "*Mínim %d nits per estada"
#: web/templates/public/campsite/type.gohtml:99
msgid "10 % VAT included."
msgstr "IVA del 10 % inclòs."
#: web/templates/public/campsite/type.gohtml:100
msgid "Tourist tax: %s/night per person aged 17 or older."
msgstr "Impost turístic: %s/nit per persona major de 16 anys."
#: web/templates/public/campsite/type.gohtml:102
msgid "Dogs: %s/night, tied, accompanied, and minimal barking."
msgstr "Gossos: %s/night, lligats, acompanyats i el mínim de lladrucs."
#: web/templates/public/campsite/type.gohtml:104
msgid "No dogs allowed."
msgstr "No es permeten gossos."
#: web/templates/public/campsite/type.gohtml:123
msgctxt "title"
msgid "Info"
msgstr "Informació"
#: web/templates/public/campsite/type.gohtml:127
msgctxt "title"
msgid "Facilities"
msgstr "Equipaments"
#: web/templates/public/campsite/type.gohtml:131
msgctxt "title"
msgid "Description"
msgstr "Descripció"
#: web/templates/public/campsite/type.gohtml:135
msgctxt "title"
msgid "Additional Information"
msgstr "Informació addicional"
#: web/templates/public/campsite/type.gohtml:138
msgctxt "time"
msgid "Check-in"
msgstr "Entrada"
#: web/templates/public/campsite/type.gohtml:142
msgctxt "time"
msgid "Check-out"
msgstr "Sortida"
#: web/templates/public/campsite/calendar.gohtml:18
#: web/templates/admin/season/calendar.gohtml:16
msgctxt "day"
msgid "Mon"
msgstr "dl"
#: web/templates/public/campsite/calendar.gohtml:19
#: web/templates/admin/season/calendar.gohtml:17
msgctxt "day"
msgid "Tue"
msgstr "dt"
#: web/templates/public/campsite/calendar.gohtml:20
#: web/templates/admin/season/calendar.gohtml:18
msgctxt "day"
msgid "Wed"
msgstr "dc"
#: web/templates/public/campsite/calendar.gohtml:21
#: web/templates/admin/season/calendar.gohtml:19
msgctxt "day"
msgid "Thu"
msgstr "dj"
#: web/templates/public/campsite/calendar.gohtml:22
#: web/templates/admin/season/calendar.gohtml:20
msgctxt "day"
msgid "Fri"
msgstr "dv"
#: web/templates/public/campsite/calendar.gohtml:23
#: web/templates/admin/season/calendar.gohtml:21
msgctxt "day"
msgid "Sat"
msgstr "ds"
#: web/templates/public/campsite/calendar.gohtml:24
#: web/templates/admin/season/calendar.gohtml:22
msgctxt "day"
msgid "Sun"
msgstr "dg"
#: web/templates/public/surroundings.gohtml:30
msgctxt "title"
msgid "What to Do Outside the Campsite?"
msgstr "Què fer des del càmping?"
#: web/templates/public/surroundings.gohtml:50
msgctxt "title"
msgid "Once at the Campsite, We Can Inform You about What Activities are Available"
msgstr "Un cop en el càmping, us podem informar de quines activitats fer"
#: web/templates/public/surroundings.gohtml:53
msgid "Cycle routes"
msgstr "Rutes amb bicicleta"
#: web/templates/public/surroundings.gohtml:54
msgid "There are many bicycle rental companies in Olot."
msgstr "A Olot podeu trobar empreses de lloguer de bicicletes."
#: web/templates/public/surroundings.gohtml:58
msgid "Routes"
msgstr "Rutes"
#: web/templates/public/surroundings.gohtml:59
msgid "Routes of all kinds, climbing, mountain passes, for all levels."
msgstr "Rutes de tota mena, escalada, ports de muntanya, per a tots els nivells."
#: web/templates/public/surroundings.gohtml:63
msgid "Family outing"
msgstr "Excursions familiars"
#: web/templates/public/surroundings.gohtml:64
msgid "Many outing possibilities, for all ages."
msgstr "Múltiples excursions per a totes les edats."
#: web/templates/public/surroundings.gohtml:68
msgid "Kayak"
msgstr "Caiac"
#: web/templates/public/surroundings.gohtml:69
msgid "There are several points where you can go by kayak, from sections of the Ter river as well as on the coast…."
msgstr "Hi ha diversos punts on poder anar amb caiac, des de trams del riu Ter com també a la costa…."
#: web/templates/public/campground.gohtml:7
#: web/templates/public/campground.gohtml:16
#: web/templates/public/layout.gohtml:54 web/templates/public/layout.gohtml:94
msgctxt "title"
msgid "Campground"
msgstr "El càmping"
#: web/templates/public/booking.gohtml:7 web/templates/public/booking.gohtml:12
#: web/templates/public/layout.gohtml:70
msgctxt "title"
msgid "Booking"
msgstr "Reserva"
#: web/templates/public/booking.gohtml:16
msgctxt "title"
msgid "Customer Details"
msgstr "Detalls del client"
#: web/templates/public/booking.gohtml:19
msgctxt "input"
msgid "Full name"
msgstr "Nom i cognoms"
#: web/templates/public/booking.gohtml:28
msgctxt "input"
msgid "Address (optional)"
msgstr "Adreça (opcional)"
#: web/templates/public/booking.gohtml:37
msgctxt "input"
msgid "Postcode (optional)"
msgstr "Codi postal (opcional)"
#: web/templates/public/booking.gohtml:46
msgctxt "input"
msgid "Town or village (optional)"
msgstr "Població (opcional)"
#: web/templates/public/booking.gohtml:55
#: web/templates/admin/taxDetails.gohtml:101
msgctxt "input"
msgid "Country"
msgstr "País"
#: web/templates/public/booking.gohtml:58
msgid "Choose a country"
msgstr "Esculli un país"
#: web/templates/public/booking.gohtml:66 web/templates/admin/login.gohtml:27
#: web/templates/admin/profile.gohtml:38
#: web/templates/admin/taxDetails.gohtml:53
msgctxt "input"
msgid "Email"
msgstr "Correu-e"
#: web/templates/public/booking.gohtml:75
#: web/templates/admin/taxDetails.gohtml:45
msgctxt "input"
msgid "Phone"
msgstr "Telèfon"
#: web/templates/public/booking.gohtml:84
msgctxt "title"
msgid "Accommodation"
msgstr "Allotjaments"
#: web/templates/public/booking.gohtml:99
msgctxt "input"
msgid "Area preferences (optional)"
msgstr "Preferències dàrea (opcional)"
#: web/templates/public/booking.gohtml:121
msgctxt "title"
msgid "Booking Period"
msgstr "Període de reserva"
#: web/templates/public/booking.gohtml:124
msgctxt "input"
msgid "Arrival date"
msgstr "Data darribada"
#: web/templates/public/booking.gohtml:133
msgctxt "input"
msgid "Departure date"
msgstr "Data de sortida"
#: web/templates/public/booking.gohtml:144
msgctxt "input"
msgid "ACSI card? (optional)"
msgstr "Targeta ACSI? (opcional)"
#: web/templates/public/booking.gohtml:151
msgctxt "input"
msgid "I have read and I accept %[1]sthe reservation conditions%[2]s"
msgstr "He llegit i accepto %[1]sles condicions de reserves%[2]s"
#: web/templates/public/layout.gohtml:12 web/templates/public/layout.gohtml:48
#: web/templates/public/layout.gohtml:131
Split templates and handlers into admin and public I need to check that the user is an employee (or admin) in administration handlers, but i do not want to do it for each handler, because i am bound to forget it. Thus, i added the /admin sub-path for these resources. The public-facing web is the rest of the resources outside /admin, but for now there is only home, to test whether it works as expected or not. The public-facing web can not relay on the user’s language settings, as the guest user has no way to set that. I would be happy to just use the Accept-Language header for that, but apparently Google does not use that header[0], and they give four alternatives: a country-specific domain, a subdomain with a generic top-level domain (gTLD), subdirectories with a gTLD, or URL parameters (e.g., site.com?loc=de). Of the four, Google does not recommend URL parameters, and the customer is already using subdirectories with the current site, therefor that’s what i have chosen. Google also tells me that it is a very good idea to have links between localized version of the same resources, either with <link> elements, Link HTTP response headers, or a sitemap file[1]; they are all equivalent in the eyes of Google. I have choosen the Link response headers way, because for that i can simply “augment” ResponseHeader to automatically add these headers when the response status is 2xx, otherwise i would need to pass down the original URL path until it reaches the template. Even though Camper is supposed to be a “generic”, multi-company application, i think i will stick to the easiest route and write the templates for just the “first” customer. [0]: https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites [1]: https://developers.google.com/search/docs/specialty/international/localized-versions
2023-08-05 01:42:37 +00:00
msgid "Campsite Montagut"
msgstr "Càmping Montagut"
#: web/templates/public/layout.gohtml:24 web/templates/admin/layout.gohtml:21
Split templates and handlers into admin and public I need to check that the user is an employee (or admin) in administration handlers, but i do not want to do it for each handler, because i am bound to forget it. Thus, i added the /admin sub-path for these resources. The public-facing web is the rest of the resources outside /admin, but for now there is only home, to test whether it works as expected or not. The public-facing web can not relay on the user’s language settings, as the guest user has no way to set that. I would be happy to just use the Accept-Language header for that, but apparently Google does not use that header[0], and they give four alternatives: a country-specific domain, a subdomain with a generic top-level domain (gTLD), subdirectories with a gTLD, or URL parameters (e.g., site.com?loc=de). Of the four, Google does not recommend URL parameters, and the customer is already using subdirectories with the current site, therefor that’s what i have chosen. Google also tells me that it is a very good idea to have links between localized version of the same resources, either with <link> elements, Link HTTP response headers, or a sitemap file[1]; they are all equivalent in the eyes of Google. I have choosen the Link response headers way, because for that i can simply “augment” ResponseHeader to automatically add these headers when the response status is 2xx, otherwise i would need to pass down the original URL path until it reaches the template. Even though Camper is supposed to be a “generic”, multi-company application, i think i will stick to the easiest route and write the templates for just the “first” customer. [0]: https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites [1]: https://developers.google.com/search/docs/specialty/international/localized-versions
2023-08-05 01:42:37 +00:00
msgid "Skip to main content"
msgstr "Salta al contingut principal"
#: web/templates/public/layout.gohtml:50
msgid "Menu"
msgstr "Menú"
#: web/templates/public/layout.gohtml:58 web/templates/public/layout.gohtml:104
#: web/templates/admin/campsite/feature/form.gohtml:16
#: web/templates/admin/campsite/feature/index.gohtml:10
#: web/templates/admin/campsite/carousel/form.gohtml:16
#: web/templates/admin/campsite/carousel/index.gohtml:10
#: web/templates/admin/campsite/form.gohtml:15
#: web/templates/admin/campsite/index.gohtml:6
#: web/templates/admin/campsite/index.gohtml:15
#: web/templates/admin/campsite/type/feature/form.gohtml:16
#: web/templates/admin/campsite/type/feature/index.gohtml:10
#: web/templates/admin/campsite/type/carousel/form.gohtml:16
#: web/templates/admin/campsite/type/carousel/index.gohtml:10
#: web/templates/admin/campsite/type/form.gohtml:15
#: web/templates/admin/campsite/type/option/form.gohtml:16
#: web/templates/admin/campsite/type/option/index.gohtml:10
#: web/templates/admin/campsite/type/index.gohtml:10
#: web/templates/admin/layout.gohtml:46 web/templates/admin/layout.gohtml:95
msgctxt "title"
msgid "Campsites"
msgstr "Allotjaments"
#: web/templates/public/layout.gohtml:91
msgctxt "title"
msgid "Sections"
msgstr "Apartats"
#: web/templates/public/layout.gohtml:115
msgctxt "title"
msgid "Opening"
msgstr "Obertura"
#: web/templates/public/layout.gohtml:122
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
msgstr "<abbr title=\"Número\">Núm.</abbr> <abbr title=\"Registre de Turisme de Catalunya\">RTC</abbr> %s"
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:8
#: web/templates/admin/legal/form.gohtml:29
msgctxt "title"
2023-12-22 01:23:18 +00:00
msgid "Edit Legal Text"
msgstr "Edició del text legal"
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:10
#: web/templates/admin/legal/form.gohtml:31
msgctxt "title"
2023-12-22 01:23:18 +00:00
msgid "New Legal Text"
msgstr "Nou text legal"
#: web/templates/admin/legal/form.gohtml:15
#: web/templates/admin/legal/index.gohtml:6
#: web/templates/admin/legal/index.gohtml:15
#: web/templates/admin/layout.gohtml:70
msgctxt "title"
msgid "Legal Texts"
msgstr "Texts legals"
#: web/templates/admin/legal/form.gohtml:41
msgctxt "input"
2023-12-22 01:23:18 +00:00
msgid "Slug"
msgstr "Àlies"
#: web/templates/admin/legal/form.gohtml:50
#: web/templates/admin/campsite/feature/form.gohtml:50
#: web/templates/admin/campsite/type/feature/form.gohtml:59
#: web/templates/admin/campsite/type/form.gohtml:51
#: web/templates/admin/campsite/type/option/form.gohtml:41
#: web/templates/admin/season/form.gohtml:50
#: web/templates/admin/services/form.gohtml:53
#: web/templates/admin/profile.gohtml:29
#: web/templates/admin/surroundings/form.gohtml:41
#: web/templates/admin/amenity/feature/form.gohtml:50
#: web/templates/admin/amenity/form.gohtml:50
2023-12-22 01:23:18 +00:00
msgctxt "input"
msgid "Name"
msgstr "Nom"
#: web/templates/admin/legal/form.gohtml:68
2023-12-22 01:23:18 +00:00
msgctxt "input"
msgid "Content"
msgstr "Contingut"
#: web/templates/admin/legal/form.gohtml:88
#: web/templates/admin/carousel/form.gohtml:55
#: web/templates/admin/campsite/feature/form.gohtml:65
#: web/templates/admin/campsite/carousel/form.gohtml:50
#: web/templates/admin/campsite/form.gohtml:92
#: web/templates/admin/campsite/type/feature/form.gohtml:74
#: web/templates/admin/campsite/type/carousel/form.gohtml:59
#: web/templates/admin/campsite/type/form.gohtml:202
#: web/templates/admin/campsite/type/option/form.gohtml:90
#: web/templates/admin/season/form.gohtml:73
#: web/templates/admin/services/form.gohtml:81
#: web/templates/admin/surroundings/form.gohtml:69
#: web/templates/admin/surroundings/index.gohtml:58
#: web/templates/admin/amenity/feature/form.gohtml:65
#: web/templates/admin/amenity/carousel/form.gohtml:50
#: web/templates/admin/amenity/form.gohtml:91
#: web/templates/admin/home/index.gohtml:34
#: web/templates/admin/media/form.gohtml:39
msgctxt "action"
msgid "Update"
msgstr "Actualitza"
#: web/templates/admin/legal/form.gohtml:90
#: web/templates/admin/carousel/form.gohtml:57
#: web/templates/admin/campsite/feature/form.gohtml:67
#: web/templates/admin/campsite/carousel/form.gohtml:52
#: web/templates/admin/campsite/form.gohtml:94
#: web/templates/admin/campsite/type/feature/form.gohtml:76
#: web/templates/admin/campsite/type/carousel/form.gohtml:61
#: web/templates/admin/campsite/type/form.gohtml:204
#: web/templates/admin/campsite/type/option/form.gohtml:92
#: web/templates/admin/season/form.gohtml:75
#: web/templates/admin/services/form.gohtml:83
#: web/templates/admin/surroundings/form.gohtml:71
#: web/templates/admin/amenity/feature/form.gohtml:67
#: web/templates/admin/amenity/carousel/form.gohtml:52
#: web/templates/admin/amenity/form.gohtml:93
msgctxt "action"
msgid "Add"
msgstr "Afegeix"
#: web/templates/admin/legal/index.gohtml:14
2023-12-22 01:23:18 +00:00
msgctxt "action"
msgid "Add Legal Text"
msgstr "Afegeix text legal"
#: web/templates/admin/legal/index.gohtml:20
#: web/templates/admin/campsite/feature/index.gohtml:30
#: web/templates/admin/campsite/type/feature/index.gohtml:31
#: web/templates/admin/campsite/type/option/index.gohtml:30
#: web/templates/admin/campsite/type/index.gohtml:29
#: web/templates/admin/season/index.gohtml:29
#: web/templates/admin/user/index.gohtml:20
#: web/templates/admin/surroundings/index.gohtml:83
#: web/templates/admin/amenity/feature/index.gohtml:30
#: web/templates/admin/amenity/index.gohtml:21
2023-12-22 01:23:18 +00:00
msgctxt "header"
msgid "Name"
msgstr "Nom"
#: web/templates/admin/legal/index.gohtml:32
2023-12-22 01:23:18 +00:00
msgid "No legal texts added yet."
msgstr "No sha afegit cap text legal encara."
#: web/templates/admin/carousel/form.gohtml:8
#: web/templates/admin/carousel/form.gohtml:28
2023-12-22 01:23:18 +00:00
msgctxt "title"
msgid "Edit Carousel Slide"
msgstr "Edició de la diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:10
#: web/templates/admin/carousel/form.gohtml:30
2023-12-22 01:23:18 +00:00
msgctxt "title"
msgid "New Carousel Slide"
msgstr "Nova diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:40
#: web/templates/admin/campsite/carousel/form.gohtml:35
#: web/templates/admin/campsite/type/carousel/form.gohtml:44
#: web/templates/admin/amenity/carousel/form.gohtml:35
2023-12-22 01:23:18 +00:00
msgctxt "input"
msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:15
msgctxt "title"
msgid "Location Settings"
msgstr "Paràmetres de com arribar"
#: web/templates/admin/location.gohtml:20
msgctxt "input"
msgid "Directions"
msgstr "Instruccions"
#: web/templates/admin/location.gohtml:33
msgctxt "input"
msgid "Opening Dates"
msgstr "Data dobertura"
#: web/templates/admin/location.gohtml:46
msgctxt "input"
msgid "Map Embed"
msgstr "Incrustació del mapa"
#: web/templates/admin/location.gohtml:53 web/templates/admin/profile.gohtml:78
#: web/templates/admin/taxDetails.gohtml:170
#: web/templates/admin/booking/payment.gohtml:65
msgctxt "action"
msgid "Save changes"
msgstr "Desa els canvis"
#: web/templates/admin/campsite/feature/form.gohtml:8
msgctxt "title"
msgid "Edit Campsite Feature"
msgstr "Edició de les característiques de lallotjament"
#: web/templates/admin/campsite/feature/form.gohtml:10
msgctxt "title"
msgid "New Campsite Feature"
msgstr "Nova característica de lallotjament"
#: web/templates/admin/campsite/feature/form.gohtml:17
#: web/templates/admin/campsite/feature/index.gohtml:6
msgctxt "title"
msgid "Campsite Features"
msgstr "Característiques de lallotjament"
#: web/templates/admin/campsite/feature/form.gohtml:32
#: web/templates/admin/campsite/type/feature/form.gohtml:41
#: web/templates/admin/services/form.gohtml:35
#: web/templates/admin/amenity/feature/form.gohtml:32
msgctxt "input"
msgid "Icon"
msgstr "Icona"
#: web/templates/admin/campsite/feature/index.gohtml:15
#: web/templates/admin/campsite/type/feature/index.gohtml:16
#: web/templates/admin/amenity/feature/index.gohtml:15
msgctxt "action"
msgid "Add Feature"
msgstr "Afegeix característica"
#: web/templates/admin/campsite/feature/index.gohtml:31
#: web/templates/admin/campsite/carousel/index.gohtml:31
#: web/templates/admin/campsite/type/feature/index.gohtml:32
#: web/templates/admin/campsite/type/carousel/index.gohtml:32
#: web/templates/admin/campsite/type/option/index.gohtml:31
#: web/templates/admin/services/index.gohtml:30
#: web/templates/admin/services/index.gohtml:75
#: web/templates/admin/user/index.gohtml:23
#: web/templates/admin/surroundings/index.gohtml:84
#: web/templates/admin/amenity/feature/index.gohtml:31
#: web/templates/admin/amenity/carousel/index.gohtml:31
#: web/templates/admin/home/index.gohtml:54
#: web/templates/admin/home/index.gohtml:99
msgctxt "header"
msgid "Actions"
msgstr "Accions"
#: web/templates/admin/campsite/feature/index.gohtml:35
#: web/templates/admin/campsite/type/feature/index.gohtml:36
#: web/templates/admin/amenity/feature/index.gohtml:35
msgid "Are you sure you wish to delete this feature?"
msgstr "Esteu segur de voler esborrar aquesta característica?"
#: web/templates/admin/campsite/feature/index.gohtml:47
#: web/templates/admin/campsite/carousel/index.gohtml:49
#: web/templates/admin/campsite/type/feature/index.gohtml:48
#: web/templates/admin/campsite/type/carousel/index.gohtml:50
#: web/templates/admin/campsite/type/option/index.gohtml:47
#: web/templates/admin/services/index.gohtml:47
#: web/templates/admin/services/index.gohtml:91
#: web/templates/admin/user/index.gohtml:37
#: web/templates/admin/surroundings/index.gohtml:63
#: web/templates/admin/surroundings/index.gohtml:101
#: web/templates/admin/amenity/feature/index.gohtml:47
#: web/templates/admin/amenity/carousel/index.gohtml:49
#: web/templates/admin/home/index.gohtml:71
#: web/templates/admin/home/index.gohtml:116
msgctxt "action"
msgid "Delete"
msgstr "Esborra"
#: web/templates/admin/campsite/feature/index.gohtml:56
msgid "No campsite features added yet."
msgstr "No sha afegit cap característica a lallotjament encara."
#: web/templates/admin/campsite/carousel/form.gohtml:8
msgctxt "title"
msgid "Edit Campsite Carousel Slide"
msgstr "Edició de la diapositiva del carrusel de lallotjament"
#: web/templates/admin/campsite/carousel/form.gohtml:10
msgctxt "title"
msgid "New Campsite Carousel Slide"
msgstr "Nova diapositiva del carrusel de lallotjament"
#: web/templates/admin/campsite/carousel/form.gohtml:17
#: web/templates/admin/campsite/carousel/index.gohtml:6
msgctxt "title"
msgid "Campsite Carousel"
msgstr "Carrusel de lallotjament"
#: web/templates/admin/campsite/carousel/index.gohtml:16
#: web/templates/admin/campsite/type/carousel/index.gohtml:17
#: web/templates/admin/services/index.gohtml:15
#: web/templates/admin/amenity/carousel/index.gohtml:16
#: web/templates/admin/home/index.gohtml:84
msgctxt "action"
msgid "Add slide"
msgstr "Afegeix diapositiva"
#: web/templates/admin/campsite/carousel/index.gohtml:29
#: web/templates/admin/campsite/type/carousel/index.gohtml:30
#: web/templates/admin/services/index.gohtml:28
#: web/templates/admin/surroundings/index.gohtml:82
#: web/templates/admin/amenity/carousel/index.gohtml:29
#: web/templates/admin/home/index.gohtml:52
#: web/templates/admin/home/index.gohtml:97
msgctxt "header"
msgid "Image"
msgstr "Imatge"
#: web/templates/admin/campsite/carousel/index.gohtml:30
#: web/templates/admin/campsite/type/carousel/index.gohtml:31
#: web/templates/admin/services/index.gohtml:29
#: web/templates/admin/amenity/carousel/index.gohtml:30
#: web/templates/admin/home/index.gohtml:53
#: web/templates/admin/home/index.gohtml:98
msgctxt "header"
msgid "Caption"
msgstr "Llegenda"
#: web/templates/admin/campsite/carousel/index.gohtml:35
#: web/templates/admin/campsite/type/carousel/index.gohtml:36
#: web/templates/admin/services/index.gohtml:34
#: web/templates/admin/amenity/carousel/index.gohtml:35
#: web/templates/admin/home/index.gohtml:103
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:58
#: web/templates/admin/campsite/type/carousel/index.gohtml:59
#: web/templates/admin/services/index.gohtml:56
#: web/templates/admin/amenity/carousel/index.gohtml:58
#: web/templates/admin/home/index.gohtml:125
msgid "No slides added yet."
msgstr "No sha afegit cap diapositiva encara."
#: web/templates/admin/campsite/form.gohtml:8
msgctxt "title"
msgid "Edit Campsite"
msgstr "Edició de lallotjament"
#: web/templates/admin/campsite/form.gohtml:10
msgctxt "title"
msgid "New Campsite"
msgstr "Nou allotjament"
#: web/templates/admin/campsite/form.gohtml:33
#: web/templates/admin/campsite/index.gohtml:27
msgctxt "campsite"
msgid "Active"
msgstr "Actiu"
#: web/templates/admin/campsite/form.gohtml:42
msgctxt "input"
msgid "Campsite Type"
msgstr "Tipus dallotjament"
#: web/templates/admin/campsite/form.gohtml:47
msgid "Select campsite type"
msgstr "Escolliu un tipus dallotjament"
#: web/templates/admin/campsite/form.gohtml:56
#: web/templates/admin/amenity/form.gohtml:42
msgctxt "input"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/form.gohtml:64
#: web/templates/admin/amenity/form.gohtml:63
msgctxt "input"
msgid "Info (First Column)"
msgstr "Informació (primera columna)"
#: web/templates/admin/campsite/form.gohtml:77
#: web/templates/admin/amenity/form.gohtml:76
msgctxt "input"
msgid "Info (Second Column)"
msgstr "Informació (segona columna)"
#: web/templates/admin/campsite/index.gohtml:14
msgctxt "action"
msgid "Add Campsite"
msgstr "Afegeix allotjament"
#: web/templates/admin/campsite/index.gohtml:23
#: web/templates/admin/amenity/index.gohtml:20
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
#: web/templates/admin/campsite/index.gohtml:24
msgctxt "header"
msgid "Type"
msgstr "Tipus"
#: web/templates/admin/campsite/index.gohtml:25
#: web/templates/admin/campsite/type/index.gohtml:30
#: web/templates/admin/amenity/index.gohtml:22
msgctxt "header"
msgid "Features"
msgstr "Característiques"
#: web/templates/admin/campsite/index.gohtml:26
#: web/templates/admin/campsite/type/index.gohtml:32
#: web/templates/admin/amenity/index.gohtml:23
msgctxt "header"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/campsite/index.gohtml:36
#: web/templates/admin/campsite/type/index.gohtml:45
#: web/templates/admin/amenity/index.gohtml:33
msgctxt "action"
msgid "Edit Features"
msgstr "Edita les característiques"
#: web/templates/admin/campsite/index.gohtml:39
#: web/templates/admin/campsite/type/index.gohtml:51
#: web/templates/admin/amenity/index.gohtml:36
msgctxt "action"
msgid "Edit Carousel"
msgstr "Edita el carrusel"
#: web/templates/admin/campsite/index.gohtml:41
#: web/templates/admin/campsite/type/index.gohtml:53
#: web/templates/admin/season/index.gohtml:44
#: web/templates/admin/user/login-attempts.gohtml:31
#: web/templates/admin/amenity/index.gohtml:38
msgid "Yes"
msgstr "Sí"
#: web/templates/admin/campsite/index.gohtml:41
#: web/templates/admin/campsite/type/index.gohtml:53
#: web/templates/admin/season/index.gohtml:44
#: web/templates/admin/user/login-attempts.gohtml:31
#: web/templates/admin/amenity/index.gohtml:38
msgid "No"
msgstr "No"
#: web/templates/admin/campsite/index.gohtml:47
msgid "No campsites added yet."
msgstr "No sha afegit cap allotjament encara."
#: web/templates/admin/campsite/type/feature/form.gohtml:8
#: web/templates/admin/campsite/type/feature/form.gohtml:32
msgctxt "title"
msgid "Edit Campsite Type Feature"
msgstr "Edició de les característiques del tipus dallotjament"
#: web/templates/admin/campsite/type/feature/form.gohtml:10
#: web/templates/admin/campsite/type/feature/form.gohtml:34
msgctxt "title"
msgid "New Campsite Type Feature"
msgstr "Nova característica de tipus dallotjament"
#: web/templates/admin/campsite/type/feature/form.gohtml:17
#: web/templates/admin/campsite/type/feature/index.gohtml:11
#: web/templates/admin/campsite/type/carousel/form.gohtml:17
#: web/templates/admin/campsite/type/carousel/index.gohtml:11
#: web/templates/admin/campsite/type/form.gohtml:16
#: web/templates/admin/campsite/type/option/form.gohtml:17
#: web/templates/admin/campsite/type/option/index.gohtml:11
#: web/templates/admin/campsite/type/index.gohtml:6
#: web/templates/admin/campsite/type/index.gohtml:16
#: web/templates/admin/layout.gohtml:43
msgctxt "title"
msgid "Campsite Types"
msgstr "Tipus dallotjaments"
#: web/templates/admin/campsite/type/feature/form.gohtml:18
#: web/templates/admin/campsite/type/feature/index.gohtml:6
#: web/templates/admin/campsite/type/feature/index.gohtml:17
msgctxt "title"
msgid "Campsite Type Features"
msgstr "Característiques del tipus dallotjaments"
#: web/templates/admin/campsite/type/feature/index.gohtml:57
msgid "No campsite type features added yet."
msgstr "No sha afegit cap característica al tipus dallotjament encara."
#: web/templates/admin/campsite/type/carousel/form.gohtml:8
#: web/templates/admin/campsite/type/carousel/form.gohtml:32
msgctxt "title"
msgid "Edit Campsite Type Carousel Slide"
msgstr "Edició de la diapositiva del carrusel del tipus dallotjament"
#: web/templates/admin/campsite/type/carousel/form.gohtml:10
#: web/templates/admin/campsite/type/carousel/form.gohtml:34
msgctxt "title"
msgid "New Campsite Type Carousel Slide"
msgstr "Nova diapositiva del carrusel del tipus dallotjament"
#: web/templates/admin/campsite/type/carousel/form.gohtml:18
#: web/templates/admin/campsite/type/carousel/index.gohtml:6
#: web/templates/admin/campsite/type/carousel/index.gohtml:16
msgctxt "title"
msgid "Campsite Type Carousel"
msgstr "Carrusel del tipus dallotjament"
#: web/templates/admin/campsite/type/form.gohtml:8
#: web/templates/admin/campsite/type/form.gohtml:30
msgctxt "title"
msgid "Edit Campsite Type"
msgstr "Edició del tipus dallotjament"
#: web/templates/admin/campsite/type/form.gohtml:10
#: web/templates/admin/campsite/type/form.gohtml:32
msgctxt "title"
msgid "New Campsite Type"
msgstr "Nou tipus dallotjament"
#: web/templates/admin/campsite/type/form.gohtml:42
#: web/templates/admin/campsite/type/index.gohtml:33
msgctxt "campsite type"
msgid "Active"
msgstr "Actiu"
#: web/templates/admin/campsite/type/form.gohtml:67
msgctxt "input"
msgid "Check-in"
msgstr "Entrada"
#: web/templates/admin/campsite/type/form.gohtml:80
msgctxt "input"
msgid "Check-out"
msgstr "Sortida"
#: web/templates/admin/campsite/type/form.gohtml:93
msgctxt "input"
msgid "Maximum number of campers"
msgstr "Número màxim de persones"
#: web/templates/admin/campsite/type/form.gohtml:103
msgctxt "input"
msgid "Dogs allowed"
msgstr "Es permeten gossos"
#: web/templates/admin/campsite/type/form.gohtml:115
#: web/templates/admin/campsite/type/option/form.gohtml:76
msgctxt "input"
msgid "Price per night"
msgstr "Preu per nit"
#: web/templates/admin/campsite/type/form.gohtml:123
2023-10-01 19:14:39 +00:00
msgctxt "input"
msgid "Minimum number of nights"
msgstr "Número mínim de nits"
#: web/templates/admin/campsite/type/form.gohtml:135
msgctxt "input"
msgid "Spiel"
msgstr "Introducció"
#: web/templates/admin/campsite/type/form.gohtml:148
msgctxt "input"
msgid "Info"
msgstr "Informació"
#: web/templates/admin/campsite/type/form.gohtml:161
msgctxt "input"
msgid "Facilities"
msgstr "Equipaments"
#: web/templates/admin/campsite/type/form.gohtml:174
#: web/templates/admin/services/form.gohtml:66
#: web/templates/admin/surroundings/form.gohtml:54
msgctxt "input"
msgid "Description"
msgstr "Descripció"
#: web/templates/admin/campsite/type/form.gohtml:187
msgctxt "input"
msgid "Additional Information"
msgstr "Informació addicional"
#: web/templates/admin/campsite/type/option/form.gohtml:8
#: web/templates/admin/campsite/type/option/form.gohtml:32
msgctxt "title"
msgid "Edit Campsite Type Option"
msgstr "Edició de lopció del tipus dallotjament"
#: web/templates/admin/campsite/type/option/form.gohtml:10
#: web/templates/admin/campsite/type/option/form.gohtml:34
msgctxt "title"
msgid "New Campsite Type Option"
msgstr "Nova opció del tipus dallotjament"
#: web/templates/admin/campsite/type/option/form.gohtml:18
#: web/templates/admin/campsite/type/option/index.gohtml:6
#: web/templates/admin/campsite/type/option/index.gohtml:17
msgctxt "title"
msgid "Campsite Type Options"
msgstr "Opcions del tipus dallotjament"
#: web/templates/admin/campsite/type/option/form.gohtml:54
msgctxt "input"
msgid "Minimum"
msgstr "Mínim"
#: web/templates/admin/campsite/type/option/form.gohtml:62
msgctxt "input"
msgid "Maximum"
msgstr "Màxim"
#: web/templates/admin/campsite/type/option/index.gohtml:16
msgctxt "action"
msgid "Add Option"
msgstr "Afegeix opció"
#: web/templates/admin/campsite/type/option/index.gohtml:35
msgid "Are you sure you wish to delete this option?"
msgstr "Esteu segur de voler esborrar aquesta opció?"
#: web/templates/admin/campsite/type/option/index.gohtml:56
msgid "No campsite type options added yet."
msgstr "No sha afegit cap opció al tipus dallotjament encara."
#: web/templates/admin/campsite/type/index.gohtml:15
msgctxt "action"
msgid "Add Type"
msgstr "Afegeix tipus"
#: web/templates/admin/campsite/type/index.gohtml:31
msgctxt "header"
msgid "Options"
msgstr "Opcions"
#: web/templates/admin/campsite/type/index.gohtml:48
msgctxt "action"
msgid "Edit Options"
msgstr "Edita les opcions"
#: web/templates/admin/campsite/type/index.gohtml:60
msgid "No campsite types added yet."
msgstr "No sha afegit cap tipus dallotjament encara."
#: web/templates/admin/season/form.gohtml:8
#: web/templates/admin/season/form.gohtml:29
msgctxt "title"
msgid "Edit Season"
msgstr "Edició de la temporada"
#: web/templates/admin/season/form.gohtml:10
#: web/templates/admin/season/form.gohtml:31
msgctxt "title"
msgid "New Season"
msgstr "Nova temporada"
#: web/templates/admin/season/form.gohtml:15
#: web/templates/admin/season/index.gohtml:6
#: web/templates/admin/season/index.gohtml:15
#: web/templates/admin/layout.gohtml:52
msgctxt "title"
msgid "Seasons"
msgstr "Temporades"
#: web/templates/admin/season/form.gohtml:41
#: web/templates/admin/season/index.gohtml:30
msgctxt "season"
msgid "Active"
msgstr "Activa"
#: web/templates/admin/season/form.gohtml:63
msgctxt "input"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:14
msgctxt "action"
msgid "Add Season"
msgstr "Afegeix temporada"
#: web/templates/admin/season/index.gohtml:28
msgctxt "header"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:51
msgid "No seasons added yet."
msgstr "No sha afegit cap temporada encara."
#: web/templates/admin/season/calendar.gohtml:49
#: web/templates/admin/media/picker.gohtml:61
msgctxt "action"
msgid "Cancel"
msgstr "Canceŀla"
Split templates and handlers into admin and public I need to check that the user is an employee (or admin) in administration handlers, but i do not want to do it for each handler, because i am bound to forget it. Thus, i added the /admin sub-path for these resources. The public-facing web is the rest of the resources outside /admin, but for now there is only home, to test whether it works as expected or not. The public-facing web can not relay on the user’s language settings, as the guest user has no way to set that. I would be happy to just use the Accept-Language header for that, but apparently Google does not use that header[0], and they give four alternatives: a country-specific domain, a subdomain with a generic top-level domain (gTLD), subdirectories with a gTLD, or URL parameters (e.g., site.com?loc=de). Of the four, Google does not recommend URL parameters, and the customer is already using subdirectories with the current site, therefor that’s what i have chosen. Google also tells me that it is a very good idea to have links between localized version of the same resources, either with <link> elements, Link HTTP response headers, or a sitemap file[1]; they are all equivalent in the eyes of Google. I have choosen the Link response headers way, because for that i can simply “augment” ResponseHeader to automatically add these headers when the response status is 2xx, otherwise i would need to pass down the original URL path until it reaches the template. Even though Camper is supposed to be a “generic”, multi-company application, i think i will stick to the easiest route and write the templates for just the “first” customer. [0]: https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites [1]: https://developers.google.com/search/docs/specialty/international/localized-versions
2023-08-05 01:42:37 +00:00
#: web/templates/admin/dashboard.gohtml:6
#: web/templates/admin/dashboard.gohtml:13 web/templates/admin/layout.gohtml:89
msgctxt "title"
msgid "Dashboard"
msgstr "Tauler"
#: web/templates/admin/login.gohtml:6 web/templates/admin/login.gohtml:18
Add the skeleton of the web application It does nothing more than to server a single page that does nothing interesting. This time i do not use a router. Instead, i am trying out a technique i have seen in an article[0] that i have tried in other, smaller, projects and seems to work surprisingly well: it just “cuts off” the URI path by path, passing the request from handler to handler until it finds its way to a handler that actually serves the request. That helps to loosen the coupling between the application and lower handlers, and makes dependencies explicit, because i need to pass the locale, company, etc. down instead of storing them in contexts. Let’s see if i do not regret it on a later date. I also made a lot more packages that in Numerus. In Numerus i actually only have the single pkg package, and it works, kind of, but i notice how i name my methods to avoid clashing instead of using packages for that. That is, instead of pkg.NewApp i now have app.New. Initially i thought that Locale should be inside app, but then there was a circular dependency between app and template. That is why i created a separate package, but now i am wondering if template should be inside app too, but then i would have app.MustRenderTemplate instead of template.MustRender. The CSS is the most bare-bones file i could write because i am focusing in markup right now; Oriol will fill in the file once the application is working. [0]: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/
2023-07-22 22:11:00 +00:00
msgctxt "title"
msgid "Login"
msgstr "Entrada"
#: web/templates/admin/login.gohtml:36 web/templates/admin/profile.gohtml:49
Add the skeleton of the web application It does nothing more than to server a single page that does nothing interesting. This time i do not use a router. Instead, i am trying out a technique i have seen in an article[0] that i have tried in other, smaller, projects and seems to work surprisingly well: it just “cuts off” the URI path by path, passing the request from handler to handler until it finds its way to a handler that actually serves the request. That helps to loosen the coupling between the application and lower handlers, and makes dependencies explicit, because i need to pass the locale, company, etc. down instead of storing them in contexts. Let’s see if i do not regret it on a later date. I also made a lot more packages that in Numerus. In Numerus i actually only have the single pkg package, and it works, kind of, but i notice how i name my methods to avoid clashing instead of using packages for that. That is, instead of pkg.NewApp i now have app.New. Initially i thought that Locale should be inside app, but then there was a circular dependency between app and template. That is why i created a separate package, but now i am wondering if template should be inside app too, but then i would have app.MustRenderTemplate instead of template.MustRender. The CSS is the most bare-bones file i could write because i am focusing in markup right now; Oriol will fill in the file once the application is working. [0]: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/
2023-07-22 22:11:00 +00:00
msgctxt "input"
msgid "Password"
msgstr "Contrasenya"
#: web/templates/admin/login.gohtml:45
Add the skeleton of the web application It does nothing more than to server a single page that does nothing interesting. This time i do not use a router. Instead, i am trying out a technique i have seen in an article[0] that i have tried in other, smaller, projects and seems to work surprisingly well: it just “cuts off” the URI path by path, passing the request from handler to handler until it finds its way to a handler that actually serves the request. That helps to loosen the coupling between the application and lower handlers, and makes dependencies explicit, because i need to pass the locale, company, etc. down instead of storing them in contexts. Let’s see if i do not regret it on a later date. I also made a lot more packages that in Numerus. In Numerus i actually only have the single pkg package, and it works, kind of, but i notice how i name my methods to avoid clashing instead of using packages for that. That is, instead of pkg.NewApp i now have app.New. Initially i thought that Locale should be inside app, but then there was a circular dependency between app and template. That is why i created a separate package, but now i am wondering if template should be inside app too, but then i would have app.MustRenderTemplate instead of template.MustRender. The CSS is the most bare-bones file i could write because i am focusing in markup right now; Oriol will fill in the file once the application is working. [0]: https://blog.merovius.de/posts/2017-06-18-how-not-to-use-an-http-router/
2023-07-22 22:11:00 +00:00
msgctxt "action"
msgid "Login"
msgstr "Entra"
#: web/templates/admin/services/form.gohtml:8
#: web/templates/admin/services/form.gohtml:26
msgctxt "title"
msgid "Edit Service"
msgstr "Edició de servei"
#: web/templates/admin/services/form.gohtml:10
#: web/templates/admin/services/form.gohtml:28
msgctxt "title"
msgid "New Service"
msgstr "Nou servei"
#: web/templates/admin/services/form.gohtml:15
#: web/templates/admin/services/index.gohtml:6
#: web/templates/admin/layout.gohtml:61
msgctxt "title"
msgid "Services Page"
msgstr "Pàgina de serveis"
#: web/templates/admin/services/index.gohtml:14
#: web/templates/admin/home/index.gohtml:83
msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
#: web/templates/admin/services/index.gohtml:60
2023-09-26 14:51:35 +00:00
msgctxt "action"
msgid "Add service"
msgstr "Afegeix servei"
#: web/templates/admin/services/index.gohtml:73
msgctxt "header"
msgid "Order"
msgstr "Ordre"
#: web/templates/admin/services/index.gohtml:74
msgctxt "header"
msgid "Service"
msgstr "Servei"
#: web/templates/admin/services/index.gohtml:79
msgid "Are you sure you wish to delete this service?"
msgstr "Esteu segur de voler esborrar aquest servei?"
#: web/templates/admin/services/index.gohtml:100
msgid "No services added yet."
msgstr "No sha afegit cap servei encara."
#: web/templates/admin/profile.gohtml:6 web/templates/admin/profile.gohtml:15
#: web/templates/admin/layout.gohtml:33
msgctxt "title"
msgid "Profile"
msgstr "Perfil"
#: web/templates/admin/profile.gohtml:20
msgctxt "inut"
msgid "Profile Image"
msgstr "Imatge del perfil"
#: web/templates/admin/profile.gohtml:46
msgctxt "legend"
msgid "Change password"
msgstr "Canvi de contrasenya"
#: web/templates/admin/profile.gohtml:58
msgctxt "input"
msgid "Password Confirmation"
msgstr "Confirmació de la contrasenya"
#: web/templates/admin/profile.gohtml:68
msgctxt "input"
msgid "Language"
msgstr "Idioma"
#: web/templates/admin/user/login-attempts.gohtml:6
#: web/templates/admin/user/login-attempts.gohtml:15
msgctxt "title"
msgid "Login Attempts"
msgstr "Intents dentrada"
#: web/templates/admin/user/login-attempts.gohtml:10
#: web/templates/admin/user/index.gohtml:6
#: web/templates/admin/user/index.gohtml:16
#: web/templates/admin/layout.gohtml:73
msgctxt "title"
msgid "Users"
msgstr "Usuaris"
#: web/templates/admin/user/login-attempts.gohtml:19
msgctxt "header"
msgid "Date"
msgstr "Data"
#: web/templates/admin/user/login-attempts.gohtml:20
#: web/templates/admin/user/index.gohtml:21
msgctxt "header"
msgid "Email"
msgstr "Correu-e"
#: web/templates/admin/user/login-attempts.gohtml:21
msgctxt "header"
msgid "IP Address"
msgstr "Adreça IP"
#: web/templates/admin/user/login-attempts.gohtml:22
msgctxt "header"
msgid "Success"
msgstr "Èxit"
#: web/templates/admin/user/index.gohtml:14
msgctxt "action"
msgid "Add User"
msgstr "Afegeix usuari"
#: web/templates/admin/user/index.gohtml:15
msgctxt "action"
msgid "Logs"
msgstr "Registres"
#: web/templates/admin/user/index.gohtml:22
msgctxt "header"
msgid "Role"
msgstr "Rol"
#: web/templates/admin/user/index.gohtml:27
msgid "Are you sure you wish to delete this user?"
msgstr "Esteu segur de voler esborrar aquest usuari?"
#: web/templates/admin/taxDetails.gohtml:6
#: web/templates/admin/taxDetails.gohtml:15
msgctxt "title"
msgid "Tax Details"
msgstr "Configuració fiscal"
#: web/templates/admin/taxDetails.gohtml:20
#: web/templates/admin/taxDetails.gohtml:61
msgctxt "input"
msgid "Business Name"
msgstr "Nom de lempresa"
#: web/templates/admin/taxDetails.gohtml:29
msgctxt "input"
msgid "VAT Number"
msgstr "NIF"
#: web/templates/admin/taxDetails.gohtml:37
msgctxt "input"
msgid "Trade Name"
msgstr "Nom comercial"
#: web/templates/admin/taxDetails.gohtml:69
msgctxt "input"
msgid "Address"
msgstr "Adreça"
#: web/templates/admin/taxDetails.gohtml:77
msgctxt "input"
msgid "City"
msgstr "Població"
#: web/templates/admin/taxDetails.gohtml:85
msgctxt "input"
msgid "Province"
msgstr "Província"
#: web/templates/admin/taxDetails.gohtml:93
msgctxt "input"
msgid "Postcode"
msgstr "Codi postal"
#: web/templates/admin/taxDetails.gohtml:111
msgctxt "input"
msgid "Currency"
msgstr "Moneda"
#: web/templates/admin/taxDetails.gohtml:121
msgctxt "input"
msgid "Default Language"
msgstr "Idioma per defecte"
#: web/templates/admin/taxDetails.gohtml:130
msgctxt "title"
msgid "Tourism"
msgstr "Turisme"
#: web/templates/admin/taxDetails.gohtml:133
msgctxt "input"
msgid "RTC number"
msgstr "Número RTC"
#: web/templates/admin/taxDetails.gohtml:141
msgctxt "input"
msgid "Tourist Tax"
msgstr "Impost turístic"
#: web/templates/admin/taxDetails.gohtml:150
msgctxt "title"
msgid "Invoicing"
msgstr "Facturació"
#: web/templates/admin/taxDetails.gohtml:153
msgctxt "input"
msgid "Invoice Number Format"
msgstr "Format del número de factura"
#: web/templates/admin/taxDetails.gohtml:161
msgctxt "input"
msgid "Legal Disclaimer"
msgstr "Nota legal"
#: web/templates/admin/surroundings/form.gohtml:8
#: web/templates/admin/surroundings/form.gohtml:29
msgctxt "title"
msgid "Edit Highlight"
msgstr "Edició del punt dinterès"
#: web/templates/admin/surroundings/form.gohtml:10
#: web/templates/admin/surroundings/form.gohtml:31
msgctxt "title"
msgid "New Highlight"
msgstr "Nou punt dinterès"
#: web/templates/admin/surroundings/index.gohtml:6
msgctxt "title"
msgid "Surroundings Page"
msgstr "Pàgina de lentorn"
#: web/templates/admin/surroundings/index.gohtml:14
msgctxt "title"
msgid "Ad"
msgstr "Anunci"
#: web/templates/admin/surroundings/index.gohtml:21
msgctxt "input"
msgid "Title"
msgstr "Títol"
#: web/templates/admin/surroundings/index.gohtml:37
msgctxt "input"
msgid "Link Text"
msgstr "Text de lenllaç"
#: web/templates/admin/surroundings/index.gohtml:50
msgctxt "input"
msgid "Link URL"
msgstr "Adreça de lenllaç"
#: web/templates/admin/surroundings/index.gohtml:59
msgid "Are you sure you wish to delete the ad?"
msgstr "Esteu segur de voler esborrar aquest anunci?"
#: web/templates/admin/surroundings/index.gohtml:68
msgctxt "title"
msgid "Highlights"
msgstr "Punts dinterès"
#: web/templates/admin/surroundings/index.gohtml:69
msgctxt "action"
msgid "Add highlight"
msgstr "Afegeix punt dinterès"
#: web/templates/admin/surroundings/index.gohtml:88
msgid "Are you sure you wish to delete this highlight?"
msgstr "Esteu segur de voler esborrar aquest punt dinterès?"
#: web/templates/admin/surroundings/index.gohtml:110
msgid "No highlights added yet."
msgstr "No sha afegit cap punt dinterès encara."
#: web/templates/admin/amenity/feature/form.gohtml:8
msgctxt "title"
msgid "Edit Amenity Feature"
msgstr "Edició de les característiques de la instaŀlació"
#: web/templates/admin/amenity/feature/form.gohtml:10
msgctxt "title"
msgid "New Amenity Feature"
msgstr "Nova característica de la instaŀlació"
#: web/templates/admin/amenity/feature/form.gohtml:16
#: web/templates/admin/amenity/feature/index.gohtml:10
#: web/templates/admin/amenity/carousel/form.gohtml:16
#: web/templates/admin/amenity/carousel/index.gohtml:10
#: web/templates/admin/amenity/form.gohtml:15
#: web/templates/admin/amenity/index.gohtml:6
#: web/templates/admin/layout.gohtml:49
msgctxt "title"
msgid "Amenities"
msgstr "Instaŀlacions"
#: web/templates/admin/amenity/feature/form.gohtml:17
#: web/templates/admin/amenity/feature/index.gohtml:6
msgctxt "title"
msgid "Amenity Features"
msgstr "Característiques de la instaŀlació"
#: web/templates/admin/amenity/feature/index.gohtml:56
msgid "No amenity features added yet."
msgstr "No sha afegit cap característica a la instaŀlació encara."
#: web/templates/admin/amenity/carousel/form.gohtml:8
msgctxt "title"
msgid "Edit Amenity Carousel Slide"
msgstr "Edició de la diapositiva del carrusel de la instaŀlació"
#: web/templates/admin/amenity/carousel/form.gohtml:10
msgctxt "title"
msgid "New Amenity Carousel Slide"
msgstr "Nova diapositiva del carrusel de la instaŀlació"
#: web/templates/admin/amenity/carousel/form.gohtml:17
#: web/templates/admin/amenity/carousel/index.gohtml:6
msgctxt "title"
msgid "Amenity Carousel"
msgstr "Carrusel de la instaŀlació"
#: web/templates/admin/amenity/form.gohtml:8
msgctxt "title"
msgid "Edit Amenity"
msgstr "Edició de la instaŀlació"
#: web/templates/admin/amenity/form.gohtml:10
msgctxt "title"
msgid "New Amenity"
msgstr "Nova instaŀlació"
#: web/templates/admin/amenity/form.gohtml:33
#: web/templates/admin/amenity/index.gohtml:24
msgctxt "amenity"
msgid "Active"
msgstr "Activa"
#: web/templates/admin/amenity/index.gohtml:14
msgctxt "action"
msgid "Add Amenity"
msgstr "Afegeix instaŀlació"
#: web/templates/admin/amenity/index.gohtml:44
msgid "No amenities added yet."
msgstr "No sha afegit cap instaŀlació encara."
#: web/templates/admin/layout.gohtml:29
msgctxt "title"
msgid "User Menu"
msgstr "Menú dusuari"
#: web/templates/admin/layout.gohtml:37
msgctxt "title"
msgid "Company Settings"
msgstr "Paràmetres de lempresa"
#: web/templates/admin/layout.gohtml:40
#: web/templates/admin/booking/payment.gohtml:6
#: web/templates/admin/booking/payment.gohtml:15
msgctxt "title"
msgid "Payment Settings"
msgstr "Paràmetres de pagament"
#: web/templates/admin/layout.gohtml:55
#: web/templates/admin/media/form.gohtml:10
#: web/templates/admin/media/index.gohtml:6
#: web/templates/admin/media/index.gohtml:14
#: web/templates/admin/media/upload.gohtml:10
msgctxt "title"
msgid "Media"
msgstr "Mèdia"
Add the logout button Conceptually, to logout we have to “delete the session”, thus the best HTTP verb would be `DELETE`. However, there is no way to send a `DELETE` request with a regular HTML form, and it seems that never will be[0]. I could use a POST, optionally with a “method override” technique, but i was planing to use HTMx anyway, so this was as good an opportunity to include it as any. In this application i am not concerned with people not having JavaScript enabled, because it is for a customer that has a known environment, and we do not have much time anyway. Therefore, i opted to forgo progressive enhancement in cases like this: if `DELETE` is needed, use `hx-delete`. Unfortunately, i can not use a <form> with a hidden <input> for the CSRF token, because `DELETE` requests do not have body and the value should be added as query parameters, like a form with GET method, but HTMx does the incorrect thing here: sends the values in the request’s body. That’s why i have to use a custom header and the `hx-header` directive to include the CSRF token. Then, by default HTMx targets the triggered element for swap with the response from the server, but after a logout i want to redirect the user to the login form again. I could set the hx-target to button to replace the whole body, or tell the client to redirect to the new location. I actually do not know which one is “better”. Maybe the hx-target is best because then everything is handled by the client, but in the case of logout, since it is possible that i might want to load scripts only for logged-in users in the future, i opted for the full page reload. However, HTMx does not want to reload a page that return HTTP 401, hence i had to include the GET method to /login in order to return the login form with a response of HTTP 200, which also helps when reloading in the browser after a failed login attempt. I am not worried with the HTTP 401 when attempting to load a page as guest, because this request most probably comes from the browser, not HTMx, and it will show the login form as intended—even though it is not compliant, since it does not return the WWW-Authenticate header, but this is the best i can do given that no cookie-based authentication method has been accepted[1]. [0]: https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671#c16 [1]: https://datatracker.ietf.org/doc/id/draft-broyer-http-cookie-auth-00.html
2023-07-26 11:49:47 +00:00
#: web/templates/admin/layout.gohtml:58 web/templates/admin/home/index.gohtml:6
Make home page’s carousel manageable via the database I debated with myself whether to create the home_carousel relation or rather if it would be better to have a single carousel relation for all pages. However, i thought that it would be actually harder to maintain a single relation because i would need an additional column to tell one carrousel from another, and what would that column be? An enum? A foreign key to another relation? home_carousel carries no such issues. I was starting to duplicate logic all over the packages, such as the way to encode media paths or “localization” (l10n) input fields. Therefore, i refactorized them. In the case of media path, i added a function that accepts rows of media, because always need the same columns from the row, and it was yet another repetition if i needed to pass them all the time. Plus, these kind of functions can be called as `table.function`, that make them look like columns from the table; if PostgreSQL implemented virtual generated columns, i would have used that instead. I am not sure whether that media_path function can be immutable. An immutable function is “guaranteed to return the same results given the same arguments forever”, which would be true if the inputs where the hash and the original_filename columns, instead of the whole rows, but i left it as static because i did not know whether PostgreSQL interprets the “same row but with different values” as a different input. That is, whether PostgreSQL’s concept of row is the actual tuple or the space that has a rowid, irrespective of contents; in the latter case, the function can not be immutable. Just to be in the safe side, i left it stable. The home page was starting to grow a bit too much inside the app package, new that it has its own admin handler, and moved it all to a separate package.
2023-09-14 23:05:38 +00:00
msgctxt "title"
msgid "Home Page"
msgstr "Pàgina dinici"
Make home page’s carousel manageable via the database I debated with myself whether to create the home_carousel relation or rather if it would be better to have a single carousel relation for all pages. However, i thought that it would be actually harder to maintain a single relation because i would need an additional column to tell one carrousel from another, and what would that column be? An enum? A foreign key to another relation? home_carousel carries no such issues. I was starting to duplicate logic all over the packages, such as the way to encode media paths or “localization” (l10n) input fields. Therefore, i refactorized them. In the case of media path, i added a function that accepts rows of media, because always need the same columns from the row, and it was yet another repetition if i needed to pass them all the time. Plus, these kind of functions can be called as `table.function`, that make them look like columns from the table; if PostgreSQL implemented virtual generated columns, i would have used that instead. I am not sure whether that media_path function can be immutable. An immutable function is “guaranteed to return the same results given the same arguments forever”, which would be true if the inputs where the hash and the original_filename columns, instead of the whole rows, but i left it as static because i did not know whether PostgreSQL interprets the “same row but with different values” as a different input. That is, whether PostgreSQL’s concept of row is the actual tuple or the space that has a rowid, irrespective of contents; in the latter case, the function can not be immutable. Just to be in the safe side, i left it stable. The home page was starting to grow a bit too much inside the app package, new that it has its own admin handler, and moved it all to a separate package.
2023-09-14 23:05:38 +00:00
#: web/templates/admin/layout.gohtml:78
msgctxt "action"
msgid "Logout"
msgstr "Surt"
#: web/templates/admin/layout.gohtml:92
#: web/templates/admin/booking/index.gohtml:6
#: web/templates/admin/booking/index.gohtml:16
msgctxt "title"
msgid "Bookings"
msgstr "Reserves"
#: web/templates/admin/layout.gohtml:101
msgid "Breadcrumb"
msgstr "Fil dAriadna"
#: web/templates/admin/layout.gohtml:113
msgid "Camper Version: %s"
msgstr "Camper versió: %s"
#: web/templates/admin/home/index.gohtml:15
msgctxt "title"
msgid "Slogan"
msgstr "Eslògan"
#: web/templates/admin/home/index.gohtml:21
msgctxt "input"
msgid "Slogan"
msgstr "Eslògan"
#: web/templates/admin/home/index.gohtml:38
msgctxt "title"
msgid "Cover"
msgstr "Portada"
#: web/templates/admin/home/index.gohtml:39
msgctxt "action"
msgid "Add cover image"
msgstr "Afegeix imatge de portada"
#: web/templates/admin/home/index.gohtml:58
msgid "Are you sure you wish to delete this cover image?"
msgstr "Esteu segur de voler esborrar aquesta imatge de portada?"
#: web/templates/admin/home/index.gohtml:80
msgid "No images added to the cover yet."
msgstr "No sha afegit cap imatge de portada encara."
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
#: web/templates/admin/media/picker.gohtml:8
msgctxt "title"
msgid "Media Picker"
msgstr "Selector de mèdia"
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
#: web/templates/admin/media/picker.gohtml:19
msgctxt "title"
msgid "Upload New Media"
msgstr "Pujada de nou mèdia"
#: web/templates/admin/media/picker.gohtml:22
#: web/templates/admin/media/upload.gohtml:21
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
msgctxt "input"
msgid "File"
msgstr "Fitxer"
#: web/templates/admin/media/picker.gohtml:26
#: web/templates/admin/media/form.gohtml:26
#: web/templates/admin/media/upload.gohtml:25
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
msgid "Maximum upload file size: %s"
msgstr "Mida màxima del fitxer a pujar: %s"
#: web/templates/admin/media/picker.gohtml:31
#: web/templates/admin/media/upload.gohtml:30
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
msgctxt "action"
msgid "Upload"
msgstr "Puja"
#: web/templates/admin/media/picker.gohtml:47
Add the upload form to the media picker It makes easier to upload new images from the place where we need it, instead of having to go to the media section each time. It was a little messy, this one. First of all, I realized that POSTint to /admin/media/picker to get the new media field was wrong: i was not asking the server to “accept an entity”, but only requesting a new HTML value, just like a GET to /admin/media/upload requests the form to upload a new media, thus here i should do the same, except i needed the query parameters to change the field, which is fine—it is actually a different resource, thus a different URL. Then, i thought that i could not POST the upload to /admin/media, because i returned a different HTML —the media field—, so i reused the recently unused POST to /admin/media/picker to upload that file and return the HTML for the field. It was wrong, because i was not requesting the server to put the file as a subordinate of /admin/media/picker, only /admin/media, but i did not come up with any other solution. Since i had two different upload functions now, i created uploadForm’s Handle method to refactorize the duplicated logic to a single place. Unfortunately, i did not work as i expected because uploadForm’s and mediaPicker’s MustRender methods are different, and mediaPicker has to embed uploadForm to render the form in the picker. That made me change Handle’s output to a boolean and error in order for the HTTP handler function know when to render the form with the error messages with the proper MustRender handler. However, I saw the opportunity of reusing that Handler method for editMedia, that was doing mostly the same job, but had to call a different Validate than uploadForm’s, because editMedia does not require the uploaded file. That’s when i realized that i could use an interface and that this interface could be reused not only within media but throughout the application, and added HandleMultipart in form. Had to create a different interface for multipart forms because they need different parameters in Parse that non-multipart form, when i add that interface, hence had to also change Parse to ParseForm to account for the difference in signature; not a big deal. After all that, i realized that i **could** POST to /admin/media in both cases, because i always return “an HTML entity”, it just happens that for the media section it is empty with a redirect, and for the picker is the field. That made the whole Handle method a bit redundant, but i left it nevertheless, as i find it slightly easier to read the uploadMedia function now.
2023-09-21 23:40:22 +00:00
msgctxt "title"
msgid "Choose Existing Media"
msgstr "Elecció dun mèdia existent"
#: web/templates/admin/media/picker.gohtml:58
#: web/templates/admin/media/index.gohtml:23
msgid "No media uploaded yet."
msgstr "No sha pujat cap mèdia encara."
#: web/templates/admin/media/form.gohtml:6
#: web/templates/admin/media/form.gohtml:16
msgctxt "title"
msgid "Edit Media"
msgstr "Edició de mèdia"
#: web/templates/admin/media/form.gohtml:22
msgctxt "input"
msgid "Updated file"
msgstr "Fitxer actualitzat"
#: web/templates/admin/media/form.gohtml:31
msgctxt "input"
msgid "Filename"
msgstr "Nom del fitxer"
#: web/templates/admin/media/index.gohtml:15
msgctxt "action"
msgid "Upload media"
msgstr "Puja mèdia"
#: web/templates/admin/media/upload.gohtml:6
#: web/templates/admin/media/upload.gohtml:16
msgctxt "title"
msgid "Upload Media"
msgstr "Pujada de mèdia"
#: web/templates/admin/booking/payment.gohtml:20
msgctxt "input"
msgid "Merchant Code"
msgstr "Codi del comerç"
#: web/templates/admin/booking/payment.gohtml:29
msgctxt "input"
msgid "Terminal Number"
msgstr "Número de terminal"
#: web/templates/admin/booking/payment.gohtml:39
msgctxt "input"
msgid "Merchant Key (only if must change it)"
msgstr "Clau del comerç (només si sha de canviar)"
#: web/templates/admin/booking/payment.gohtml:41
msgctxt "input"
msgid "Merchant Key"
msgstr "Clau del comerç"
#: web/templates/admin/booking/payment.gohtml:51
msgctxt "title"
msgid "Environment"
msgstr "Entorn"
#: web/templates/admin/booking/payment.gohtml:58
msgctxt "title"
msgid "Integration"
msgstr "Integració"
#: web/templates/admin/booking/index.gohtml:14
msgctxt "action"
msgid "Add Booking"
msgstr "Afegeix reserva"
#: web/templates/admin/booking/index.gohtml:15
msgctxt "action"
msgid "Export Bookings"
msgstr "Exporta reserves"
#: web/templates/admin/booking/index.gohtml:21
msgctxt "header"
msgid "Reference"
msgstr "Referència"
#: web/templates/admin/booking/index.gohtml:22
msgctxt "header"
msgid "Arrival Date"
msgstr "Data darribada"
#: web/templates/admin/booking/index.gohtml:23
msgctxt "header"
msgid "Departure Date"
msgstr "Data de sortida"
#: web/templates/admin/booking/index.gohtml:24
msgctxt "header"
msgid "Holder Name"
msgstr "Nom del titular"
#: web/templates/admin/booking/index.gohtml:25
msgctxt "header"
msgid "Status"
msgstr "Estat"
#: web/templates/admin/booking/index.gohtml:41
msgid "No booking found."
msgstr "No sha trobat cap reserva."
#: pkg/legal/admin.go:258 pkg/app/user.go:249 pkg/campsite/types/option.go:357
#: pkg/campsite/types/feature.go:272 pkg/campsite/types/admin.go:483
#: pkg/campsite/feature.go:269 pkg/season/admin.go:412
#: pkg/services/admin.go:316 pkg/surroundings/admin.go:340
#: pkg/amenity/feature.go:269 pkg/amenity/admin.go:270
2023-12-22 01:23:18 +00:00
msgid "Name can not be empty."
msgstr "No podeu deixar el nom en blanc."
#: pkg/legal/admin.go:259 pkg/campsite/types/option.go:358
#: pkg/campsite/types/feature.go:273 pkg/campsite/types/admin.go:484
#: pkg/campsite/feature.go:270 pkg/amenity/feature.go:270
2023-12-22 01:23:18 +00:00
msgid "Name must have at least one letter."
msgstr "El nom ha de tenir com a mínim una lletra."
#: pkg/carousel/admin.go:276 pkg/campsite/types/carousel.go:225
#: pkg/campsite/carousel.go:227 pkg/amenity/carousel.go:227
msgctxt "input"
msgid "Slide image"
msgstr "Imatge de la diapositiva"
#: pkg/carousel/admin.go:277 pkg/campsite/types/carousel.go:226
#: pkg/campsite/carousel.go:228 pkg/amenity/carousel.go:228
msgctxt "action"
msgid "Set slide image"
msgstr "Estableix la imatge de la diapositiva"
#: pkg/carousel/admin.go:346 pkg/campsite/types/carousel.go:299
#: pkg/campsite/carousel.go:302 pkg/surroundings/admin.go:335
#: pkg/amenity/carousel.go:302
msgid "Slide image can not be empty."
msgstr "No podeu deixar la imatge de la diapositiva en blanc."
#: pkg/carousel/admin.go:347 pkg/campsite/types/carousel.go:300
#: pkg/campsite/carousel.go:303 pkg/surroundings/admin.go:336
#: pkg/amenity/carousel.go:303
msgid "Slide image must be an image media type."
msgstr "La imatge de la diapositiva ha de ser un mèdia de tipus imatge."
#: pkg/app/login.go:56 pkg/app/user.go:246 pkg/company/admin.go:217
#: pkg/booking/public.go:269
msgid "Email can not be empty."
msgstr "No podeu deixar el correu-e en blanc."
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/company/admin.go:218
#: pkg/booking/public.go:270
msgid "This email is not valid. It should be like name@domain.com."
msgstr "Aquest correu-e no és vàlid. Hauria de ser similar a nom@domini.com."
Add the logout button Conceptually, to logout we have to “delete the session”, thus the best HTTP verb would be `DELETE`. However, there is no way to send a `DELETE` request with a regular HTML form, and it seems that never will be[0]. I could use a POST, optionally with a “method override” technique, but i was planing to use HTMx anyway, so this was as good an opportunity to include it as any. In this application i am not concerned with people not having JavaScript enabled, because it is for a customer that has a known environment, and we do not have much time anyway. Therefore, i opted to forgo progressive enhancement in cases like this: if `DELETE` is needed, use `hx-delete`. Unfortunately, i can not use a <form> with a hidden <input> for the CSRF token, because `DELETE` requests do not have body and the value should be added as query parameters, like a form with GET method, but HTMx does the incorrect thing here: sends the values in the request’s body. That’s why i have to use a custom header and the `hx-header` directive to include the CSRF token. Then, by default HTMx targets the triggered element for swap with the response from the server, but after a logout i want to redirect the user to the login form again. I could set the hx-target to button to replace the whole body, or tell the client to redirect to the new location. I actually do not know which one is “better”. Maybe the hx-target is best because then everything is handled by the client, but in the case of logout, since it is possible that i might want to load scripts only for logged-in users in the future, i opted for the full page reload. However, HTMx does not want to reload a page that return HTTP 401, hence i had to include the GET method to /login in order to return the login form with a response of HTTP 200, which also helps when reloading in the browser after a failed login attempt. I am not worried with the HTTP 401 when attempting to load a page as guest, because this request most probably comes from the browser, not HTMx, and it will show the login form as intended—even though it is not compliant, since it does not return the WWW-Authenticate header, but this is the best i can do given that no cookie-based authentication method has been accepted[1]. [0]: https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671#c16 [1]: https://datatracker.ietf.org/doc/id/draft-broyer-http-cookie-auth-00.html
2023-07-26 11:49:47 +00:00
#: pkg/app/login.go:59
msgid "Password can not be empty."
msgstr "No podeu deixar la contrasenya en blanc."
#: pkg/app/login.go:86
msgid "Invalid user or password."
msgstr "Nom dusuari o contrasenya incorrectes."
Add the logout button Conceptually, to logout we have to “delete the session”, thus the best HTTP verb would be `DELETE`. However, there is no way to send a `DELETE` request with a regular HTML form, and it seems that never will be[0]. I could use a POST, optionally with a “method override” technique, but i was planing to use HTMx anyway, so this was as good an opportunity to include it as any. In this application i am not concerned with people not having JavaScript enabled, because it is for a customer that has a known environment, and we do not have much time anyway. Therefore, i opted to forgo progressive enhancement in cases like this: if `DELETE` is needed, use `hx-delete`. Unfortunately, i can not use a <form> with a hidden <input> for the CSRF token, because `DELETE` requests do not have body and the value should be added as query parameters, like a form with GET method, but HTMx does the incorrect thing here: sends the values in the request’s body. That’s why i have to use a custom header and the `hx-header` directive to include the CSRF token. Then, by default HTMx targets the triggered element for swap with the response from the server, but after a logout i want to redirect the user to the login form again. I could set the hx-target to button to replace the whole body, or tell the client to redirect to the new location. I actually do not know which one is “better”. Maybe the hx-target is best because then everything is handled by the client, but in the case of logout, since it is possible that i might want to load scripts only for logged-in users in the future, i opted for the full page reload. However, HTMx does not want to reload a page that return HTTP 401, hence i had to include the GET method to /login in order to return the login form with a response of HTTP 200, which also helps when reloading in the browser after a failed login attempt. I am not worried with the HTTP 401 when attempting to load a page as guest, because this request most probably comes from the browser, not HTMx, and it will show the login form as intended—even though it is not compliant, since it does not return the WWW-Authenticate header, but this is the best i can do given that no cookie-based authentication method has been accepted[1]. [0]: https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671#c16 [1]: https://datatracker.ietf.org/doc/id/draft-broyer-http-cookie-auth-00.html
2023-07-26 11:49:47 +00:00
#: pkg/app/user.go:197
msgctxt "language option"
msgid "Automatic"
msgstr "Automàtic"
#: pkg/app/user.go:250
msgid "Confirmation does not match password."
msgstr "La confirmació no es correspon amb la contrasenya."
#: pkg/app/user.go:251 pkg/company/admin.go:238
msgid "Selected language is not valid."
msgstr "Lidioma escollit no és vàlid."
#: pkg/app/user.go:253
msgid "File must be a valid PNG or JPEG image."
msgstr "El fitxer has de ser una imatge PNG o JPEG vàlida."
#: pkg/app/admin.go:70
Split templates and handlers into admin and public I need to check that the user is an employee (or admin) in administration handlers, but i do not want to do it for each handler, because i am bound to forget it. Thus, i added the /admin sub-path for these resources. The public-facing web is the rest of the resources outside /admin, but for now there is only home, to test whether it works as expected or not. The public-facing web can not relay on the user’s language settings, as the guest user has no way to set that. I would be happy to just use the Accept-Language header for that, but apparently Google does not use that header[0], and they give four alternatives: a country-specific domain, a subdomain with a generic top-level domain (gTLD), subdirectories with a gTLD, or URL parameters (e.g., site.com?loc=de). Of the four, Google does not recommend URL parameters, and the customer is already using subdirectories with the current site, therefor that’s what i have chosen. Google also tells me that it is a very good idea to have links between localized version of the same resources, either with <link> elements, Link HTTP response headers, or a sitemap file[1]; they are all equivalent in the eyes of Google. I have choosen the Link response headers way, because for that i can simply “augment” ResponseHeader to automatically add these headers when the response status is 2xx, otherwise i would need to pass down the original URL path until it reaches the template. Even though Camper is supposed to be a “generic”, multi-company application, i think i will stick to the easiest route and write the templates for just the “first” customer. [0]: https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites [1]: https://developers.google.com/search/docs/specialty/international/localized-versions
2023-08-05 01:42:37 +00:00
msgid "Access forbidden"
msgstr "Accés prohibit"
#: pkg/campsite/types/option.go:361
msgid "Minimum can not be empty."
msgstr "No podeu deixar el mínim en blanc."
#: pkg/campsite/types/option.go:362
msgid "Minimum must be an integer number."
msgstr "El valor del mínim ha de ser un número enter."
#: pkg/campsite/types/option.go:364
msgid "Minimum must be zero or greater."
msgstr "El valor del mínim ha de ser com a mínim zero."
#: pkg/campsite/types/option.go:367
msgid "Maximum can not be empty."
msgstr "No podeu deixar el màxim en blanc."
#: pkg/campsite/types/option.go:368
msgid "Maximum must be an integer number."
msgstr "El valor del màxim ha de ser un número enter."
#: pkg/campsite/types/option.go:370
msgid "Maximum must be equal or greater than minimum."
msgstr "El valor del màxim ha de ser igual o superir al del mínim."
#: pkg/campsite/types/option.go:374 pkg/campsite/types/admin.go:499
msgid "Price per night can not be empty."
msgstr "No podeu deixar el preu per nit en blanc."
#: pkg/campsite/types/option.go:375 pkg/campsite/types/admin.go:500
msgid "Price per night must be a decimal number."
msgstr "El preu per nit ha de ser un número decimal."
#: pkg/campsite/types/option.go:376 pkg/campsite/types/admin.go:501
msgid "Price per night must be zero or greater."
msgstr "El preu per nit ha de ser com a mínim zero."
#: pkg/campsite/types/feature.go:271 pkg/campsite/feature.go:268
#: pkg/services/admin.go:315 pkg/amenity/feature.go:268
msgid "Selected icon is not valid."
msgstr "La icona escollida no és vàlida."
#: pkg/campsite/types/admin.go:307
msgctxt "input"
msgid "Cover image"
msgstr "Imatge de portada"
#: pkg/campsite/types/admin.go:308
msgctxt "action"
msgid "Set campsite type cover"
msgstr "Estableix la portada del tipus dallotjament"
#: pkg/campsite/types/admin.go:486
msgid "Check-in can not be empty."
msgstr "No podeu deixar lentrada en blanc."
#: pkg/campsite/types/admin.go:487
msgid "Check-out can not be empty."
msgstr "No podeu deixar la sortida en blanc."
#: pkg/campsite/types/admin.go:488
msgid "Cover image can not be empty."
msgstr "No podeu deixar la imatge de portada en blanc."
#: pkg/campsite/types/admin.go:489
msgid "Cover image must be an image media type."
msgstr "La imatge de portada ha de ser un mèdia de tipus imatge."
#: pkg/campsite/types/admin.go:493
msgid "Maximum number of campers can not be empty."
msgstr "No podeu deixar el número màxim de persones en blanc."
#: pkg/campsite/types/admin.go:494
msgid "Maximum number of campers must be an integer number."
msgstr "El número màxim de persones ha de ser enter."
#: pkg/campsite/types/admin.go:495
msgid "Maximum number of campers must be one or greater."
msgstr "El número màxim de persones no pot ser zero."
#: pkg/campsite/types/admin.go:504
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights can not be empty."
msgstr "No podeu deixar el número mínim de nits en blanc."
#: pkg/campsite/types/admin.go:505
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights must be an integer."
msgstr "El número mínim de nits ha de ser enter."
#: pkg/campsite/types/admin.go:506
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights must be one or greater."
msgstr "El número mínim de nits no pot ser zero."
#: pkg/campsite/admin.go:275 pkg/booking/public.go:278
msgid "Selected campsite type is not valid."
msgstr "El tipus dallotjament escollit no és vàlid."
#: pkg/campsite/admin.go:276 pkg/amenity/admin.go:269
msgid "Label can not be empty."
msgstr "No podeu deixar letiqueta en blanc."
#: pkg/season/admin.go:183
msgctxt "month"
msgid "January"
msgstr "gener"
#: pkg/season/admin.go:184
msgctxt "month"
msgid "February"
msgstr "febrer"
#: pkg/season/admin.go:185
msgctxt "month"
msgid "March"
msgstr "març"
#: pkg/season/admin.go:186
msgctxt "month"
msgid "April"
msgstr "abril"
#: pkg/season/admin.go:187
msgctxt "month"
msgid "May"
msgstr "maig"
#: pkg/season/admin.go:188
msgctxt "month"
msgid "June"
msgstr "juny"
#: pkg/season/admin.go:189
msgctxt "month"
msgid "July"
msgstr "juliol"
#: pkg/season/admin.go:190
msgctxt "month"
msgid "August"
msgstr "agost"
#: pkg/season/admin.go:191
msgctxt "month"
msgid "September"
msgstr "setembre"
#: pkg/season/admin.go:192
msgctxt "month"
msgid "October"
msgstr "octubre"
#: pkg/season/admin.go:193
msgctxt "month"
msgid "November"
msgstr "novembre"
#: pkg/season/admin.go:194
msgctxt "month"
msgid "December"
msgstr "desembre"
#: pkg/season/admin.go:413
msgid "Color can not be empty."
msgstr "No podeu deixar el color en blanc."
#: pkg/season/admin.go:414
msgid "This color is not valid. It must be like #123abc."
msgstr "Aquest color no és vàlid. Hauria de ser similar a #123abc."
#: pkg/season/admin.go:514
msgctxt "action"
msgid "Unset"
msgstr "Desassigna"
#: pkg/season/admin.go:545
msgid "Start date can not be empty."
msgstr "No podeu deixar la data dinici en blanc."
#: pkg/season/admin.go:546
msgid "Start date must be a valid date."
msgstr "La data dinici ha de ser una data vàlida."
#: pkg/season/admin.go:548
msgid "End date can not be empty."
msgstr "No podeu deixar la data de fi en blanc."
#: pkg/season/admin.go:549
msgid "End date must be a valid date."
msgstr "La data de fi ha de ser una data vàlida."
#: pkg/user/admin.go:18
msgctxt "role"
msgid "guest"
msgstr "convidat"
#: pkg/user/admin.go:19
msgctxt "role"
msgid "employee"
msgstr "treballador"
#: pkg/user/admin.go:20
msgctxt "role"
msgid "admin"
msgstr "administrador"
#: pkg/surroundings/admin.go:286
msgctxt "input"
msgid "Highlight image"
msgstr "Imatge del punt dinterès"
#: pkg/surroundings/admin.go:287
msgctxt "action"
msgid "Set highlight image"
msgstr "Estableix la imatge del punt dinterès"
#: pkg/surroundings/admin.go:407
msgctxt "input"
msgid "Ad image"
msgstr "Imatge de lanunci"
#: pkg/surroundings/admin.go:408
msgctxt "action"
msgid "Set ad image"
msgstr "Estableix la imatge de lanunci"
#: pkg/surroundings/admin.go:459
msgid "Ad image can not be empty."
msgstr "No podeu deixar la imatge de lanunci en blanc."
#: pkg/surroundings/admin.go:460
msgid "Ad image must be an image media type."
msgstr "La imatge de lanunci ha de ser un mèdia de tipus imatge."
#: pkg/surroundings/admin.go:464
msgid "The title can not be empty."
msgstr "No podeu deixar el títol en blanc."
#: pkg/surroundings/admin.go:465
msgid "The link text can not be empty."
msgstr "No podeu deixar el text de lenllaç en blanc."
#: pkg/surroundings/admin.go:466
msgid "The ad URL can not be empty"
msgstr "No podeu deixar ladreça de lenllaç en blanc."
#: pkg/surroundings/admin.go:467 pkg/company/admin.go:221
msgid "This web address is not valid. It should be like https://domain.com/."
msgstr "Aquesta adreça web no és vàlida. Hauria de ser similar a https://domini.com/."
#: pkg/company/admin.go:200 pkg/booking/public.go:256
msgid "Selected country is not valid."
msgstr "El país escollit no és vàlid."
#: pkg/company/admin.go:204
msgid "Business name can not be empty."
msgstr "No podeu deixar el nom dempresa en blanc."
#: pkg/company/admin.go:205
msgid "Business name must have at least two letters."
msgstr "El nom dempresa ha de tenir com a mínim dues lletres."
#: pkg/company/admin.go:207
msgid "VAT number can not be empty."
msgstr "No podeu deixar el NIF en blanc."
#: pkg/company/admin.go:208
msgid "This VAT number is not valid."
msgstr "Aquest NIF no és vàlid."
#: pkg/company/admin.go:212 pkg/booking/public.go:272
msgid "Phone can not be empty."
msgstr "No podeu deixar el telèfon en blanc."
#: pkg/company/admin.go:213 pkg/booking/public.go:273
msgid "This phone number is not valid."
msgstr "Aquest número de telèfon no és vàlid."
#: pkg/company/admin.go:223
msgid "Address can not be empty."
msgstr "No podeu deixar ladreça en blanc."
#: pkg/company/admin.go:224
msgid "City can not be empty."
msgstr "No podeu deixar la població en blanc."
#: pkg/company/admin.go:225
msgid "Province can not be empty."
msgstr "No podeu deixar la província en blanc."
#: pkg/company/admin.go:226
msgid "Postal code can not be empty."
msgstr "No podeu deixar el codi postal en blanc."
#: pkg/company/admin.go:227 pkg/booking/public.go:265
msgid "This postal code is not valid."
msgstr "Aquest codi postal no és vàlid."
#: pkg/company/admin.go:231
msgid "RTC number can not be empty."
msgstr "No podeu deixar el número dRTC en blanc."
#: pkg/company/admin.go:232
msgid "Tourist tax can not be empty."
msgstr "No podeu deixar limpost turístic en blanc."
#: pkg/company/admin.go:233
msgid "Tourist tax must be a decimal number."
msgstr "Limpost turístic ha de ser un número decimal."
#: pkg/company/admin.go:234
msgid "Tourist tax must be zero or greater."
msgstr "Limpost turístic ha de ser com a mínim zero."
#: pkg/company/admin.go:237
msgid "Selected currency is not valid."
msgstr "La moneda escollida no és vàlida."
#: pkg/company/admin.go:239
msgid "Invoice number format can not be empty."
msgstr "No podeu deixar el format del número de factura en blanc."
#: pkg/auth/user.go:40
Add the logout button Conceptually, to logout we have to “delete the session”, thus the best HTTP verb would be `DELETE`. However, there is no way to send a `DELETE` request with a regular HTML form, and it seems that never will be[0]. I could use a POST, optionally with a “method override” technique, but i was planing to use HTMx anyway, so this was as good an opportunity to include it as any. In this application i am not concerned with people not having JavaScript enabled, because it is for a customer that has a known environment, and we do not have much time anyway. Therefore, i opted to forgo progressive enhancement in cases like this: if `DELETE` is needed, use `hx-delete`. Unfortunately, i can not use a <form> with a hidden <input> for the CSRF token, because `DELETE` requests do not have body and the value should be added as query parameters, like a form with GET method, but HTMx does the incorrect thing here: sends the values in the request’s body. That’s why i have to use a custom header and the `hx-header` directive to include the CSRF token. Then, by default HTMx targets the triggered element for swap with the response from the server, but after a logout i want to redirect the user to the login form again. I could set the hx-target to button to replace the whole body, or tell the client to redirect to the new location. I actually do not know which one is “better”. Maybe the hx-target is best because then everything is handled by the client, but in the case of logout, since it is possible that i might want to load scripts only for logged-in users in the future, i opted for the full page reload. However, HTMx does not want to reload a page that return HTTP 401, hence i had to include the GET method to /login in order to return the login form with a response of HTTP 200, which also helps when reloading in the browser after a failed login attempt. I am not worried with the HTTP 401 when attempting to load a page as guest, because this request most probably comes from the browser, not HTMx, and it will show the login form as intended—even though it is not compliant, since it does not return the WWW-Authenticate header, but this is the best i can do given that no cookie-based authentication method has been accepted[1]. [0]: https://www.w3.org/Bugs/Public/show_bug.cgi?id=10671#c16 [1]: https://datatracker.ietf.org/doc/id/draft-broyer-http-cookie-auth-00.html
2023-07-26 11:49:47 +00:00
msgid "Cross-site request forgery detected."
msgstr "Sha detectat un intent de falsificació de petició a llocs creuats."
#: pkg/media/admin.go:312
msgid "Uploaded file can not be empty."
msgstr "No podeu deixar el fitxer del mèdia en blanc."
#: pkg/media/admin.go:371
msgid "Filename can not be empty."
msgstr "No podeu deixar el nom del fitxer en blanc."
#: pkg/booking/admin.go:149
msgctxt "filename"
msgid "bookings.ods"
msgstr "reserves.ods"
#: pkg/booking/admin.go:177
msgctxt "redsys environment"
msgid "Test"
msgstr "Proves"
#: pkg/booking/admin.go:181
msgctxt "redsys environment"
msgid "Live"
msgstr "Real"
#: pkg/booking/admin.go:190
msgctxt "redsys integration"
msgid "InSite"
msgstr "InSite"
#: pkg/booking/admin.go:194
msgctxt "redsys integration"
msgid "Redirect"
msgstr "Redirecció"
#: pkg/booking/admin.go:238
msgid "Merchant code can not be empty."
msgstr "No podeu deixar el codi del comerç en blanc."
#: pkg/booking/admin.go:239
msgid "Merchant code must be exactly nine digits long."
msgstr "El codi del comerç ha de ser de nou dígits."
#: pkg/booking/admin.go:240
msgid "Merchant code must be a number."
msgstr "El codi del comerç."
#: pkg/booking/admin.go:244
msgid "Terminal number can not be empty."
msgstr "No podeu deixar el número del terminal en blanc."
#: pkg/booking/admin.go:245
msgid "Terminal number must be a number between 1 and 999."
msgstr "El número del terminal ha de ser entre 1 i 999"
#: pkg/booking/admin.go:253
msgid "Selected environment is not valid."
msgstr "Lentorn escollit no és vàlid."
#: pkg/booking/admin.go:254
msgid "Selected integration is not valid."
msgstr "La integració escollida no és vàlida."
#: pkg/booking/admin.go:257
msgid "The merchant key is not valid."
msgstr "Aquesta clau del comerç no és vàlid."
#: pkg/booking/public.go:260
msgid "Full name can not be empty."
msgstr "No podeu deixar el nom i els cognoms en blanc."
#: pkg/booking/public.go:261
msgid "Full name must have at least one letter."
msgstr "El nom i els cognoms han de tenir com a mínim una lletra."
#: pkg/booking/public.go:279
msgid "Arrival date can not be empty"
msgstr "No podeu deixar la data darribada en blanc."
#: pkg/booking/public.go:280
msgid "Arrival date must be a valid date."
msgstr "La data darribada ha de ser una data vàlida."
#: pkg/booking/public.go:284
msgid "Departure date can not be empty"
msgstr "No podeu deixar la data de sortida en blanc."
#: pkg/booking/public.go:285
msgid "Departure date must be a valid date."
msgstr "La data de sortida ha de ser una data vàlida."
#: pkg/booking/public.go:286
msgid "The departure date must be after the arrival date."
msgstr "La data de sortida ha de ser posterior a la darribada."
#: pkg/booking/public.go:289
msgid "It is mandatory to agree to the reservation conditions."
msgstr "És obligatori acceptar les condicions de reserves."
#: pkg/booking/public.go:292
#, c-format
msgid "%s can not be empty"
msgstr "No podeu deixar %s en blanc."
#: pkg/booking/public.go:293
#, c-format
msgid "%s must be an integer."
msgstr "%s ha de ser un número enter."
#: pkg/booking/public.go:294
#, c-format
msgid "%s must be %d or greater."
msgstr "El valor de %s ha de ser com a mínim %d."
#: pkg/booking/public.go:295
#, c-format
msgid "%s must be at most %d."
msgstr "El valor de %s ha de ser com a màxim %d."
#~ msgid "Campsite Montagut is an ideal starting point for quiet outings, climbing, swimming in the river and gorges, volcanoes, the Fageda den Jordà, cycle tours for all ages…."
#~ msgstr "El Càmping Montagut és ideal com a punt de partida dexcursions tranquil·les, escalada, banyar-se en el riu i gorgues, volcans, la Fageda den Jordà, sortides amb bicicleta per a tots els nivells…."
#~ msgid "Get to the Costa Brava and enjoy the beaches, the gastronomy or go kayaking…."
#~ msgstr "Arribar fins a la costa brava i gaudir de les platges, la gastronomia o anar amb caiac…."
#~ msgid "You will also find museums in Olot, Figures, Girona."
#~ msgstr "També trobareu museus a Olot, Figueres, Girona."
#~ msgid "As well as music festivals, dance, theater…."
#~ msgstr "Com festivals de música, dansa, teatre…."
#~ msgctxt "header"
#~ msgid "Translations"
#~ msgstr "Traduccions"
#~ msgctxt "title"
#~ msgid "Translate Season to %s"
#~ msgstr "Traducció de la temporada a %s"
#~ msgid "Source:"
#~ msgstr "Origen:"
#~ msgctxt "input"
#~ msgid "Translation:"
#~ msgstr "Traducció:"
#~ msgctxt "action"
#~ msgid "Translate"
#~ msgstr "Tradueix"
#~ msgctxt "title"
#~ msgid "Translate Service to %s"
#~ msgstr "Traducció del servei a %s"
#~ 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"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Carousel Slide to %s"
#~ msgstr "Traducció de la diapositiva del carrusel del tipus dallotjament a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Option to %s"
#~ msgstr "Traducció de la opció del tipus dallotjament a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type to %s"
#~ msgstr "Traducció del tipus dallotjament a %s"
2023-12-22 02:32:40 +00:00
#~ msgid "Starting from %s €/night"
#~ msgstr "A partir de %s €/nit"
#~ msgctxt "season"
#~ msgid "Closed"
#~ msgstr "Tancat"
#~ msgctxt "title"
#~ msgid "Party Details"
#~ msgstr "Dades dels visitants"
#~ msgctxt "input"
#~ msgid "Adults"
#~ msgstr "Adults"
#~ msgctxt "input"
#~ msgid "Teenagers (from 11 to 16 years old)"
#~ msgstr "Adolescents (entre 11 i 16 anys)"
#~ msgctxt "input"
#~ msgid "Children (up to 10 years old)"
#~ msgstr "Nens (fins a 10 anys)"
#~ msgctxt "input"
#~ msgid "Dogs"
#~ msgstr "Gossos"
#~ msgid "Number of adults can not be empty"
#~ msgstr "No podeu deixar el número dadults en blanc."
#~ msgid "Number of adults must be an integer."
#~ msgstr "El número dadults ha de ser enter."
#~ msgid "Number of adults must be one or greater."
#~ msgstr "El número dadults no pot ser zero."
#~ msgid "Number of teenagers can not be empty"
#~ msgstr "No podeu deixar el número dadolescents en blanc."
#~ msgid "Number of teenagers must be an integer."
#~ msgstr "El número dadolescents ha de ser enter."
#~ msgid "Number of teenagers must be zero or greater."
#~ msgstr "El número dadolescents ha de ser com a mínim zero."
#~ msgid "Number of children can not be empty"
#~ msgstr "No podeu deixar el número de nens en blanc."
#~ msgid "Number of children must be an integer."
#~ msgstr "El número de nens ha de ser enter."
#~ msgid "Number of children must be zero or greater."
#~ msgstr "El número de nens ha de ser com a mínim zero."
#~ msgid "Number of dogs can not be empty"
#~ msgstr "No podeu deixar el número de gossos en blanc."
#~ msgid "Number of dogs must be an integer."
#~ msgstr "El número de gossos ha de ser enter."
#~ msgid "Number of dogs must be zero or greater."
#~ msgstr "El número de gossos ha de ser com a mínim zero."
#~ msgctxt "input"
#~ msgid "Pricing"
#~ msgstr "Preus"
#~ msgctxt "input"
#~ msgid "Features"
#~ msgstr "Característiques"
#~ msgid "Singular Lodges"
#~ msgstr "Allotjaments singulars"
#~ msgctxt "campsite type"
#~ msgid "Translations"
#~ msgstr "Traduccions"
#~ msgid "Surroundings"
#~ msgstr "Entorn"
Make home page’s carousel manageable via the database I debated with myself whether to create the home_carousel relation or rather if it would be better to have a single carousel relation for all pages. However, i thought that it would be actually harder to maintain a single relation because i would need an additional column to tell one carrousel from another, and what would that column be? An enum? A foreign key to another relation? home_carousel carries no such issues. I was starting to duplicate logic all over the packages, such as the way to encode media paths or “localization” (l10n) input fields. Therefore, i refactorized them. In the case of media path, i added a function that accepts rows of media, because always need the same columns from the row, and it was yet another repetition if i needed to pass them all the time. Plus, these kind of functions can be called as `table.function`, that make them look like columns from the table; if PostgreSQL implemented virtual generated columns, i would have used that instead. I am not sure whether that media_path function can be immutable. An immutable function is “guaranteed to return the same results given the same arguments forever”, which would be true if the inputs where the hash and the original_filename columns, instead of the whole rows, but i left it as static because i did not know whether PostgreSQL interprets the “same row but with different values” as a different input. That is, whether PostgreSQL’s concept of row is the actual tuple or the space that has a rowid, irrespective of contents; in the latter case, the function can not be immutable. Just to be in the safe side, i left it stable. The home page was starting to grow a bit too much inside the app package, new that it has its own admin handler, and moved it all to a separate package.
2023-09-14 23:05:38 +00:00
#~ msgid "Legend"
#~ msgstr "Llegenda"
#~ msgctxt "title"
#~ msgid "Pages"
#~ msgstr "Pàgines"
#~ msgctxt "action"
#~ msgid "Add Page"
#~ msgstr "Afegeix pàgina"
#~ msgctxt "header"
#~ msgid "Title"
#~ msgstr "Títol"