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
# Spanish translations for camper package
# Traducciones al español para el paquete 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"
2024-01-13 00:15:24 +00:00
"POT-Creation-Date: 2024-01-13 01:12+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:46+0200\n"
"Last-Translator: jordi fita mas <jordi@tandem.blog>\n"
"Language-Team: Spanish <es@tp.org.es>\n"
"Language: es\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"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/payment/success.gohtml:6
#: web/templates/public/payment/success.gohtml:11
msgctxt "title"
msgid "Payment Successful"
msgstr "Pago con éxito"
#: web/templates/public/payment/request.gohtml:6
#: web/templates/public/payment/request.gohtml:11
msgctxt "title"
msgid "Payment"
msgstr "Pago"
2023-12-12 22:16:04 +00:00
#: web/templates/public/payment/request.gohtml:23
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "action"
msgid "Pay"
msgstr "Pagar"
#: web/templates/public/payment/failure.gohtml:6
#: web/templates/public/payment/failure.gohtml:11
msgctxt "title"
msgid "Payment Failed"
msgstr "Pago fallido"
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
#: web/templates/public/services.gohtml:6
#: web/templates/public/services.gohtml:15
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:66 web/templates/public/layout.gohtml:94
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:56
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
msgctxt "title"
msgid "Services"
msgstr "Servicios"
#: web/templates/public/services.gohtml:18
msgid "The campsite offers many different services."
msgstr "El camping dispone de varios servicios."
2023-12-21 20:17:04 +00:00
#: web/templates/public/location.gohtml:6
#: web/templates/public/location.gohtml:12
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:68 web/templates/public/layout.gohtml:96
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:60
msgctxt "title"
msgid "Location"
msgstr "Cómo llegar"
2023-12-22 01:23:18 +00:00
#: web/templates/public/home.gohtml:6 web/templates/public/layout.gohtml:52
#: web/templates/public/layout.gohtml:92
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 "Inicio"
Add the sample campsite types to the demo file
Since campsite types need a media, i have to insert also images to the
media relation. The best would be to use PostgreSQL’s
pg_read_binary_file to read the media content from actual files when
inserting the new rows, but the files need to be within the database
cluster directory, or have to use an absolute path when running as a
superuser to read from files outside the cluster directory, which means
that it would depend on the path where i leave the files, that is
different in development that in staging.
To avoid that problem i can simply insert the rows using their base64
strings, with PostgreSQL’s decode. The images are kind of small, but
i was worried that each change in demo.sql would duplicate that data in
git, even if the change is not related to the images, because git stores
the whole file; even if small, soon everything adds up.
I do not care if the _final_ demo.sql is big, as this file is packaged
in a different deb and is only installed in staging, so i’ve chosen to
use m4 to build a single “amalgamated” SQL file from the base .sql
file and the individual image files converted to base64 strings. That
way, each image is individually managed by git and the base .sql file
does not balloon up for each little change.
Changed m4’s quotes to [[ ]] because the default ` ' was interfering
with Intellij’s syntax highlighting.
2023-09-10 01:57:46 +00:00
#: web/templates/public/home.gohtml:17
2023-09-05 02:40:48 +00:00
msgid "The pleasure of camping in the middle of nature…"
msgstr "El placer de acampar en plena naturaleza…"
Add the sample campsite types to the demo file
Since campsite types need a media, i have to insert also images to the
media relation. The best would be to use PostgreSQL’s
pg_read_binary_file to read the media content from actual files when
inserting the new rows, but the files need to be within the database
cluster directory, or have to use an absolute path when running as a
superuser to read from files outside the cluster directory, which means
that it would depend on the path where i leave the files, that is
different in development that in staging.
To avoid that problem i can simply insert the rows using their base64
strings, with PostgreSQL’s decode. The images are kind of small, but
i was worried that each change in demo.sql would duplicate that data in
git, even if the change is not related to the images, because git stores
the whole file; even if small, soon everything adds up.
I do not care if the _final_ demo.sql is big, as this file is packaged
in a different deb and is only installed in staging, so i’ve chosen to
use m4 to build a single “amalgamated” SQL file from the base .sql
file and the individual image files converted to base64 strings. That
way, each image is individually managed by git and the base .sql file
does not balloon up for each little change.
Changed m4’s quotes to [[ ]] because the default ` ' was interfering
with Intellij’s syntax highlighting.
2023-09-10 01:57:46 +00:00
#: web/templates/public/home.gohtml:18
2023-09-05 02:40:48 +00:00
msgctxt "link"
msgid "Booking"
msgstr "Reservar"
Add the sample campsite types to the demo file
Since campsite types need a media, i have to insert also images to the
media relation. The best would be to use PostgreSQL’s
pg_read_binary_file to read the media content from actual files when
inserting the new rows, but the files need to be within the database
cluster directory, or have to use an absolute path when running as a
superuser to read from files outside the cluster directory, which means
that it would depend on the path where i leave the files, that is
different in development that in staging.
To avoid that problem i can simply insert the rows using their base64
strings, with PostgreSQL’s decode. The images are kind of small, but
i was worried that each change in demo.sql would duplicate that data in
git, even if the change is not related to the images, because git stores
the whole file; even if small, soon everything adds up.
I do not care if the _final_ demo.sql is big, as this file is packaged
in a different deb and is only installed in staging, so i’ve chosen to
use m4 to build a single “amalgamated” SQL file from the base .sql
file and the individual image files converted to base64 strings. That
way, each image is individually managed by git and the base .sql file
does not balloon up for each little change.
Changed m4’s quotes to [[ ]] because the default ` ' was interfering
with Intellij’s syntax highlighting.
2023-09-10 01:57:46 +00:00
#: web/templates/public/home.gohtml:31
2023-09-05 02:40:48 +00:00
msgid "Our services"
msgstr "Nuestros servicios"
2023-12-21 16:33:01 +00:00
#: web/templates/public/home.gohtml:33
msgid "Come and enjoy!"
msgstr "¡Ven a disfrutar!"
#: web/templates/public/home.gohtml:35
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
#: web/templates/public/surroundings.gohtml:6
#: web/templates/public/surroundings.gohtml:10
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:67 web/templates/public/layout.gohtml:95
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
msgctxt "title"
2023-09-11 02:20:21 +00:00
msgid "Surroundings"
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
msgstr "El entorno"
2023-09-05 02:40:48 +00:00
2023-12-21 16:33:01 +00:00
#: web/templates/public/home.gohtml:38
2023-09-11 02:20:21 +00:00
msgid "Located in <strong>Alta Garrotxa</strong>, between the <strong>Pyrenees</strong> and the <strong>Costa Brava</strong>."
msgstr "Situados en la <strong>Alta Garrotxa</strong>, entre los <strong>Pirineos</strong> y la <strong>Costa Brava</strong>."
2023-12-21 16:33:01 +00:00
#: web/templates/public/home.gohtml:39
2023-09-11 02:20:21 +00:00
msgid "Nearby there are the <strong>gorges of Sadernes</strong>, <strong>volcanoes</strong>, <strong>La Fageda d’ en 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."
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgstr "Cerca tenéis los <strong>piletones de Sadernes</strong>, <strong>volcanes</strong>, <strong>La Fageda d’ en Jordà</strong>, la judería de <strong>Besalú</strong>, el riscal basáltico de <strong>Castellfollit de la Roca</strong>… mucho por ver y mucho por hacer."
2023-09-11 02:20:21 +00:00
2023-12-21 16:33:01 +00:00
#: web/templates/public/home.gohtml:40
2023-09-11 02:20:21 +00:00
msgid "Less than an hour from <strong>Girona</strong>, one from <strong>La Bisbal d’ Empordà</strong>, and two from <strong>Barcelona</strong>."
msgstr "A menos de una hora de <strong>Girona</strong>, a una de <strong>La Bisbal d’ Empordà</strong> y a dos de <strong>Barcelona</strong>."
2023-12-21 16:33:01 +00:00
#: web/templates/public/home.gohtml:41
2023-09-11 02:20:21 +00:00
msgid "Discover the surroundings"
msgstr "Descubre el entorno"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/campsite/type.gohtml:41
2023-10-13 19:59:45 +00:00
msgctxt "input"
msgid "Check-in Date"
msgstr "Fecha de entrada"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/campsite/type.gohtml:47
2023-10-13 19:59:45 +00:00
msgctxt "input"
msgid "Check-out Date"
msgstr "Fecha de salida"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/campsite/type.gohtml:54
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:155
2023-10-13 19:59:45 +00:00
msgctxt "action"
msgid "Book"
msgstr "Reservar"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:62
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/index.gohtml:51
2023-12-22 02:32:40 +00:00
msgctxt "title"
msgid "Calendar"
msgstr "Calendario"
#: web/templates/public/campsite/type.gohtml:73
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:63
#: web/templates/admin/campsite/type/form.gohtml:78
2023-10-01 19:14:39 +00:00
msgctxt "title"
msgid "Prices"
msgstr "Precios"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:83
2023-10-01 19:14:39 +00:00
msgid "%s €/night"
msgstr "%s €/noche"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:85
msgid "%s: %s €/night"
msgstr "%s: %s €/noche"
#: web/templates/public/campsite/type.gohtml:88
2023-10-01 19:14:39 +00:00
msgid "*Minimum %d nights per stay"
msgstr "*Mínimo %d noches por estancia"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:99
2023-10-13 18:30:31 +00:00
msgctxt "title"
msgid "Features"
msgstr "Características"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:110
2023-10-13 11:40:48 +00:00
msgctxt "title"
msgid "Info"
msgstr "Información"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:114
2023-10-13 11:40:48 +00:00
msgctxt "title"
msgid "Facilities"
msgstr "Equipamento"
2023-12-22 02:32:40 +00:00
#: web/templates/public/campsite/type.gohtml:118
2023-10-13 11:40:48 +00:00
msgctxt "title"
msgid "Description"
msgstr "Descripción"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/campsite/calendar.gohtml:18
#: web/templates/admin/season/calendar.gohtml:16
msgctxt "day"
msgid "Mon"
msgstr "lu"
#: web/templates/public/campsite/calendar.gohtml:19
#: web/templates/admin/season/calendar.gohtml:17
msgctxt "day"
msgid "Tue"
msgstr "ma"
#: web/templates/public/campsite/calendar.gohtml:20
#: web/templates/admin/season/calendar.gohtml:18
msgctxt "day"
msgid "Wed"
msgstr "mi"
#: web/templates/public/campsite/calendar.gohtml:21
#: web/templates/admin/season/calendar.gohtml:19
msgctxt "day"
msgid "Thu"
msgstr "ju"
#: web/templates/public/campsite/calendar.gohtml:22
#: web/templates/admin/season/calendar.gohtml:20
msgctxt "day"
msgid "Fri"
msgstr "vi"
#: web/templates/public/campsite/calendar.gohtml:23
#: web/templates/admin/season/calendar.gohtml:21
msgctxt "day"
msgid "Sat"
msgstr "sá"
#: web/templates/public/campsite/calendar.gohtml:24
#: web/templates/admin/season/calendar.gohtml:22
msgctxt "day"
msgid "Sun"
msgstr "do"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:28
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgctxt "title"
msgid "What to Do Outside the Campsite?"
msgstr "¿Qué hacer desde el camping?"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:31
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Campsite Montagut is an ideal starting point for quiet outings, climbing, swimming in the river and gorges, volcanoes, the Fageda d’ en Jordà, cycle tours for all ages…."
msgstr "El Camping Montagut es ideal como punto de salida de excursiones tranquilas, escalada, bañarse en el río y piletones, volcanes, la Fageda d’ en Jordà, salidas en bicicleta para todos los niveles…."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:38
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Get to the Costa Brava and enjoy the beaches, the gastronomy or go kayaking…."
msgstr "Llegar hasta la Costa Brava y disfrutar de las playas, la gastronomía o ir en kayak…."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:47
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "You will also find museums in Olot, Figures, Girona."
msgstr "También encontraréis museos en Olot, Figueres, Girona."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:48
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "As well as music festivals, dance, theater…."
msgstr "Como festivales de música, danza, teatro…."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:54
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgctxt "title"
msgid "Once at the Campsite, We Can Inform You about What Activities are Available"
msgstr "Una vez en el camping, os podemos informar de qué actividades hacer"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:57
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Cycle routes"
msgstr "Rutas en bicicleta"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:58
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "There are many bicycle rental companies in Olot."
msgstr "A Olot podéis encontrar empresas de alquiler de bicicletas."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:62
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Routes"
msgstr "Rutas"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:63
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Routes of all kinds, climbing, mountain passes, for all levels."
msgstr "Rutas de todo tipo, escalada, puertos de montaña, para todos los niveles."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:67
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Family outing"
msgstr "Excusiones familiares"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:68
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Many outing possibilities, for all ages."
msgstr "Múltiples excursiones para todas las edades."
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:72
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Kayak"
msgstr "Kayak"
2023-12-20 18:52:14 +00:00
#: web/templates/public/surroundings.gohtml:73
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "There are several points where you can go by kayak, from sections of the Ter river as well as on the coast…."
msgstr "Hay diversos puntos dónde podéis ir en kayak, desde tramos del río Ter como también en la costa…."
2023-10-06 20:14:11 +00:00
#: web/templates/public/campground.gohtml:6
#: web/templates/public/campground.gohtml:11
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:53 web/templates/public/layout.gohtml:93
2023-10-06 20:14:11 +00:00
msgctxt "title"
msgid "Campground"
msgstr "El camping"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/public/booking.gohtml:6 web/templates/public/booking.gohtml:11
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:69
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "title"
msgid "Booking"
msgstr "Reserva"
#: web/templates/public/booking.gohtml:15
msgctxt "title"
msgid "Customer Details"
msgstr "Detalles del cliente"
#: web/templates/public/booking.gohtml:18
msgctxt "input"
msgid "Full name"
msgstr "Nombre y apellidos"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:27
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "Address (optional)"
msgstr "Dirección (opcional)"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:36
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "Postcode (optional)"
msgstr "Código postal (opcional)"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:45
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "Town or village (optional)"
msgstr "Población (opcional)"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:54
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/admin/taxDetails.gohtml:98
msgctxt "input"
msgid "Country"
msgstr "País"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:57
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Choose a country"
msgstr "Escoja un país"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:65 web/templates/admin/login.gohtml:22
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/admin/profile.gohtml:35
#: web/templates/admin/taxDetails.gohtml:50
msgctxt "input"
msgid "Email"
msgstr "Correo-e"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:74
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#: web/templates/admin/taxDetails.gohtml:42
msgctxt "input"
msgid "Phone"
msgstr "Teléfono"
2023-10-27 14:04:43 +00:00
#: web/templates/public/booking.gohtml:83
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "title"
2023-12-13 22:45:29 +00:00
msgid "Accommodation"
msgstr "Alojamientos"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:98
msgctxt "input"
msgid "Area preferences (optional)"
msgstr "Preferencias de área (opcional)"
#: web/templates/public/booking.gohtml:120
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "title"
msgid "Booking Period"
msgstr "Periodo de reserva"
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:123
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "Arrival date"
msgstr "Fecha de llegada"
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:132
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "Departure date"
msgstr "Fecha de salida"
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:143
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
msgid "ACSI card? (optional)"
msgstr "¿Tarjeta ACSI? (opcional)"
2023-12-12 22:16:04 +00:00
#: web/templates/public/booking.gohtml:150
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgctxt "input"
2023-12-22 02:32:40 +00:00
msgid "I have read and I accept <a href=\"%s\" target=\"_blank\">the reservation conditions</a>"
msgstr "He leído y acepto <a href=\"%s\" target=\"_blank\">las condiciones de reserva</a>"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:11 web/templates/public/layout.gohtml:47
#: web/templates/public/layout.gohtml:130
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 "Camping Montagut"
2023-12-21 20:17:04 +00:00
#: web/templates/public/layout.gohtml:23 web/templates/admin/layout.gohtml:20
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 "Saltar al contenido principal"
2024-01-10 18:41:57 +00:00
#: web/templates/public/layout.gohtml:49
msgid "Menu"
msgstr "Menú"
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:57 web/templates/public/layout.gohtml:103
2023-10-06 16:58:24 +00:00
#: web/templates/admin/campsite/index.gohtml:6
#: web/templates/admin/campsite/index.gohtml:12
2023-12-22 01:23:18 +00:00
#: web/templates/admin/layout.gohtml:45 web/templates/admin/layout.gohtml:82
2023-10-06 16:58:24 +00:00
msgctxt "title"
msgid "Campsites"
msgstr "Alojamientos"
2023-08-08 00:29:14 +00:00
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:90
2023-10-06 20:02:59 +00:00
msgctxt "title"
msgid "Sections"
msgstr "Apartados"
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:114
2023-12-21 20:17:04 +00:00
msgctxt "title"
msgid "Opening"
msgstr "Apertura"
2023-12-22 01:23:18 +00:00
#: web/templates/public/layout.gohtml:121
2023-10-14 19:59:36 +00:00
msgid "<abbr title=\"Catalonia Tourism Registry\">RTC</abbr> <abbr title=\"Number\">#</abbr>%s"
msgstr "<abbr title=\"Número\">Nº</abbr> <abbr title=\"Registro de Turismo de Cataluña\">RTC</abbr> %s"
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:8
#: web/templates/admin/legal/form.gohtml:25
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "title"
2023-12-22 01:23:18 +00:00
msgid "Edit Legal Text"
msgstr "Edición del texto legal"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:10
#: web/templates/admin/legal/form.gohtml:27
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "title"
2023-12-22 01:23:18 +00:00
msgid "New Legal Text"
msgstr "Nuevo texto legal"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:37
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "input"
2023-12-22 01:23:18 +00:00
msgid "Slug"
msgstr "Álias"
#: web/templates/admin/legal/form.gohtml:46
#: web/templates/admin/campsite/feature/form.gohtml:52
#: web/templates/admin/campsite/option/form.gohtml:34
#: web/templates/admin/campsite/type/form.gohtml:46
#: web/templates/admin/season/form.gohtml:46
#: web/templates/admin/services/form.gohtml:52
#: web/templates/admin/profile.gohtml:26
msgctxt "input"
msgid "Name"
msgstr "Nombre"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:64
msgctxt "input"
msgid "Content"
msgstr "Contenido"
#: web/templates/admin/legal/form.gohtml:84
2024-01-12 18:33:44 +00:00
#: web/templates/admin/carousel/form.gohtml:52
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/feature/form.gohtml:67
#: web/templates/admin/campsite/carousel/form.gohtml:52
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:70
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:83
#: web/templates/admin/campsite/type/form.gohtml:158
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/form.gohtml:69
#: web/templates/admin/services/form.gohtml:80
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/form.gohtml:35
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "action"
msgid "Update"
msgstr "Actualizar"
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/form.gohtml:86
2024-01-12 18:33:44 +00:00
#: web/templates/admin/carousel/form.gohtml:54
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/feature/form.gohtml:69
#: web/templates/admin/campsite/carousel/form.gohtml:54
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:72
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:85
#: web/templates/admin/campsite/type/form.gohtml:160
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/form.gohtml:71
#: web/templates/admin/services/form.gohtml:82
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "action"
msgid "Add"
msgstr "Añadir"
2023-12-22 01:23:18 +00:00
#: web/templates/admin/legal/index.gohtml:6
#: web/templates/admin/legal/index.gohtml:12
#: web/templates/admin/layout.gohtml:63
msgctxt "title"
msgid "Legal Texts"
msgstr "Textos legales"
#: web/templates/admin/legal/index.gohtml:11
msgctxt "action"
msgid "Add Legal Text"
msgstr "Añadir texto legal"
#: web/templates/admin/legal/index.gohtml:17
#: web/templates/admin/campsite/feature/index.gohtml:26
#: web/templates/admin/campsite/option/index.gohtml:25
#: web/templates/admin/campsite/type/index.gohtml:25
#: web/templates/admin/season/index.gohtml:26
msgctxt "header"
msgid "Name"
msgstr "Nombre"
#: web/templates/admin/legal/index.gohtml:29
msgid "No legal texts added yet."
msgstr "No se ha añadido ningún texto legal todavía."
#: web/templates/admin/carousel/form.gohtml:8
#: web/templates/admin/carousel/form.gohtml:25
msgctxt "title"
msgid "Edit Carousel Slide"
msgstr "Edición de la diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:10
#: web/templates/admin/carousel/form.gohtml:27
msgctxt "title"
msgid "New Carousel Slide"
msgstr "Nueva diapositiva del carrusel"
#: web/templates/admin/carousel/form.gohtml:37
#: web/templates/admin/campsite/carousel/form.gohtml:37
msgctxt "input"
msgid "Caption"
msgstr "Leyenda"
2023-12-21 20:17:04 +00:00
#: web/templates/admin/location.gohtml:6 web/templates/admin/location.gohtml:12
msgctxt "title"
msgid "Location Settings"
msgstr "Parámetros de cómo llegar"
#: web/templates/admin/location.gohtml:17
msgctxt "input"
msgid "Directions"
msgstr "Instrucciones"
#: web/templates/admin/location.gohtml:35
msgctxt "input"
msgid "Opening Dates"
msgstr "Fechas de apertura"
#: web/templates/admin/location.gohtml:53
msgctxt "input"
msgid "Map Embed"
msgstr "Incrustación del mapa"
#: web/templates/admin/location.gohtml:60 web/templates/admin/payment.gohtml:62
#: web/templates/admin/profile.gohtml:75
#: web/templates/admin/taxDetails.gohtml:152
msgctxt "action"
msgid "Save changes"
msgstr "Guardar los cambios"
2023-10-13 18:30:31 +00:00
#: web/templates/admin/campsite/feature/form.gohtml:8
#: web/templates/admin/campsite/feature/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite Type Feature"
msgstr "Edición de las características del tipo de alojamiento"
#: web/templates/admin/campsite/feature/form.gohtml:10
#: web/templates/admin/campsite/feature/form.gohtml:27
msgctxt "title"
msgid "New Campsite Type Feature"
msgstr "Nueva característica del tipo de alojamiento"
#: web/templates/admin/campsite/feature/form.gohtml:34
#: web/templates/admin/services/form.gohtml:34
msgctxt "input"
msgid "Icon"
msgstr "Icono"
#: web/templates/admin/campsite/feature/index.gohtml:6
#: web/templates/admin/campsite/feature/index.gohtml:12
msgctxt "title"
msgid "Campsite Type Features"
msgstr "Características del tipo de alojamiento"
#: web/templates/admin/campsite/feature/index.gohtml:11
msgctxt "action"
msgid "Add Feature"
msgstr "Añadir características"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/feature/index.gohtml:43
2023-10-13 18:30:31 +00:00
msgid "No campsite type features added yet."
msgstr "No se ha añadido ninguna característica al tipo de alojamiento todavía."
2023-10-12 14:33:45 +00:00
#: web/templates/admin/campsite/carousel/form.gohtml:8
#: web/templates/admin/campsite/carousel/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite Type Carousel Slide"
msgstr "Edición de la diapositiva del carrusel del tipo de alojamiento"
#: web/templates/admin/campsite/carousel/form.gohtml:10
#: web/templates/admin/campsite/carousel/form.gohtml:27
msgctxt "title"
msgid "New Campsite Type Carousel Slide"
msgstr "Nueva diapositiva del carrusel del tipo de alojamiento"
#: web/templates/admin/campsite/carousel/index.gohtml:6
#: web/templates/admin/campsite/carousel/index.gohtml:11
msgctxt "title"
msgid "Campsite Type Carousel"
msgstr "Carrusel del tipo de alojamiento"
#: web/templates/admin/campsite/carousel/index.gohtml:12
#: web/templates/admin/services/index.gohtml:12
#: web/templates/admin/home/index.gohtml:12
msgctxt "action"
msgid "Add slide"
msgstr "Añadir diapositiva"
2023-12-20 18:52:14 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:25
#: web/templates/admin/services/index.gohtml:25
#: web/templates/admin/home/index.gohtml:25
2023-10-12 14:33:45 +00:00
msgctxt "header"
msgid "Image"
msgstr "Imagen"
2023-12-20 18:52:14 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:26
#: web/templates/admin/services/index.gohtml:26
#: web/templates/admin/home/index.gohtml:26
2023-10-12 14:33:45 +00:00
msgctxt "header"
msgid "Caption"
msgstr "Leyenda"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:27
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:27
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/index.gohtml:72
2024-01-12 18:33:44 +00:00
#: web/templates/admin/home/index.gohtml:27
2023-10-12 14:33:45 +00:00
msgctxt "header"
msgid "Actions"
msgstr "Acciones"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:31
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:31
#: web/templates/admin/home/index.gohtml:31
2023-10-12 14:33:45 +00:00
msgid "Are you sure you wish to delete this slide?"
msgstr "¿Estáis seguro de querer borrar esta diapositiva?"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:45
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:44
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/index.gohtml:88
2024-01-12 18:33:44 +00:00
#: web/templates/admin/home/index.gohtml:44
2023-10-12 14:33:45 +00:00
msgctxt "action"
msgid "Delete"
msgstr "Borrar"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/carousel/index.gohtml:54
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:53
#: web/templates/admin/home/index.gohtml:53
2023-10-12 14:33:45 +00:00
msgid "No slides added yet."
msgstr "No se ha añadido ninguna diapositiva todavía."
2023-08-14 18:18:26 +00:00
#: web/templates/admin/campsite/form.gohtml:8
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:25
2023-08-08 00:29:14 +00:00
msgctxt "title"
2023-08-14 18:18:26 +00:00
msgid "Edit Campsite"
msgstr "Edición del alojamientos"
2023-08-08 00:29:14 +00:00
2023-08-14 18:18:26 +00:00
#: web/templates/admin/campsite/form.gohtml:10
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:27
2023-08-04 17:59:58 +00:00
msgctxt "title"
2023-08-14 18:18:26 +00:00
msgid "New Campsite"
msgstr "Nuevo alojamiento"
2023-08-04 17:59:58 +00:00
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:37
#: web/templates/admin/campsite/index.gohtml:20
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "campsite"
2023-08-14 09:43:58 +00:00
msgid "Active"
msgstr "Activo"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:46
2023-08-04 17:59:58 +00:00
msgctxt "input"
2023-08-14 18:18:26 +00:00
msgid "Campsite Type"
msgstr "Tipo de alojamiento"
2023-08-04 17:59:58 +00:00
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:51
2023-08-14 18:18:26 +00:00
msgid "Select campsite type"
msgstr "Escoged un tipo de alojamiento"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/form.gohtml:60
2023-08-04 17:59:58 +00:00
msgctxt "input"
2023-08-14 18:18:26 +00:00
msgid "Label"
msgstr "Etiqueta"
2023-08-04 17:59:58 +00:00
2023-10-06 11:26:01 +00:00
#: web/templates/admin/campsite/option/form.gohtml:8
#: web/templates/admin/campsite/option/form.gohtml:25
msgctxt "title"
msgid "Edit Campsite Type Option"
msgstr "Edición de la opción del tipo de alojamiento"
#: web/templates/admin/campsite/option/form.gohtml:10
#: web/templates/admin/campsite/option/form.gohtml:27
msgctxt "title"
msgid "New Campsite Type Option"
msgstr "Nueva opción del tipo de alojamiento"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:47
2023-10-06 11:26:01 +00:00
msgctxt "input"
msgid "Minimum"
msgstr "Mínimo"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:55
2023-10-06 11:26:01 +00:00
msgctxt "input"
msgid "Maximum"
msgstr "Màximo"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/form.gohtml:69
#: web/templates/admin/campsite/type/form.gohtml:84
2023-10-06 11:26:01 +00:00
msgctxt "input"
msgid "Price per night"
msgstr "Precio por noche"
#: web/templates/admin/campsite/option/index.gohtml:6
#: web/templates/admin/campsite/option/index.gohtml:12
msgctxt "title"
msgid "Campsite Type Options"
msgstr "Opciones del tipo de alojamiento"
#: web/templates/admin/campsite/option/index.gohtml:11
msgctxt "action"
msgid "Add Option"
msgstr "Añadir opción"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/option/index.gohtml:42
2023-10-06 11:26:01 +00:00
msgid "No campsite type options added yet."
msgstr "No se ha añadido ninguna opció al tipo de alojamiento todavía."
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:11
2023-08-14 18:18:26 +00:00
msgctxt "action"
msgid "Add Campsite"
msgstr "Añadir alojamiento"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:18
2023-08-14 18:18:26 +00:00
msgctxt "header"
msgid "Label"
msgstr "Etiqueta"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:19
2023-08-14 18:18:26 +00:00
msgctxt "header"
msgid "Type"
msgstr "Tipo"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:28
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:49
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/index.gohtml:41
2023-08-14 18:18:26 +00:00
msgid "Yes"
msgstr "Sí"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:28
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:49
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/index.gohtml:41
2023-08-14 18:18:26 +00:00
msgid "No"
msgstr "No"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/index.gohtml:34
2023-08-14 18:18:26 +00:00
msgid "No campsites added yet."
msgstr "No se ha añadido ningún alojamiento todavía."
#: web/templates/admin/campsite/type/form.gohtml:8
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/type/form.gohtml:25
2023-08-14 18:18:26 +00:00
msgctxt "title"
msgid "Edit Campsite Type"
2023-10-06 11:26:01 +00:00
msgstr "Edición del tipo de alojamiento"
2023-08-14 18:18:26 +00:00
#: web/templates/admin/campsite/type/form.gohtml:10
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/type/form.gohtml:27
2023-08-14 18:18:26 +00:00
msgctxt "title"
msgid "New Campsite Type"
msgstr "Nuevo tipo de alojamiento"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/type/form.gohtml:37
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:29
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "campsite type"
msgid "Active"
msgstr "Activo"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:62
2023-09-29 18:17:39 +00:00
msgctxt "input"
msgid "Maximum number of campers"
msgstr "Número máximo de personas"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:72
2023-09-29 18:17:39 +00:00
msgctxt "input"
msgid "Dogs allowed"
msgstr "Se permiten perros"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:92
2023-10-01 19:14:39 +00:00
msgctxt "input"
msgid "Minimum number of nights"
msgstr "Número mínimos de noches"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:104
2023-10-12 16:47:08 +00:00
msgctxt "input"
msgid "Spiel"
msgstr "Introducción"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:117
2023-10-13 11:40:48 +00:00
msgctxt "input"
msgid "Info"
msgstr "Información"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:130
2023-10-13 11:40:48 +00:00
msgctxt "input"
msgid "Facilities"
msgstr "Equipamento"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/form.gohtml:143
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/form.gohtml:65
2023-08-14 18:18:26 +00:00
msgctxt "input"
msgid "Description"
msgstr "Descripción"
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/campsite/type/index.gohtml:6
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/type/index.gohtml:12
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:42
2023-08-04 17:59:58 +00:00
msgctxt "title"
msgid "Campsite Types"
msgstr "Tipos de alojamientos"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/campsite/type/index.gohtml:11
2023-08-04 17:59:58 +00:00
msgctxt "action"
msgid "Add Type"
msgstr "Añadir tipo"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:26
2023-08-04 17:59:58 +00:00
msgctxt "header"
2023-10-13 18:30:31 +00:00
msgid "Features"
msgstr "Características"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:27
2023-10-13 18:30:31 +00:00
msgctxt "header"
2023-10-06 11:26:01 +00:00
msgid "Options"
msgstr "Opciones"
2023-08-04 17:59:58 +00:00
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:28
2023-10-12 14:33:45 +00:00
msgctxt "header"
msgid "Carousel"
msgstr "Carrusel"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:41
2023-10-13 18:30:31 +00:00
msgctxt "action"
msgid "Edit Features"
msgstr "Editar las características"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:44
2023-10-06 11:26:01 +00:00
msgctxt "action"
msgid "Edit Options"
msgstr "Editar opciones"
2023-09-12 18:20:23 +00:00
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:47
2023-10-12 14:33:45 +00:00
msgctxt "action"
msgid "Edit Carousel"
msgstr "Editar el carrusel"
2024-01-10 20:52:49 +00:00
#: web/templates/admin/campsite/type/index.gohtml:56
2023-08-04 17:59:58 +00:00
msgid "No campsite types added yet."
msgstr "No se ha añadido ningún tipo de alojamiento todavía."
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
#: web/templates/admin/season/form.gohtml:8
2023-09-25 18:10:33 +00:00
#: web/templates/admin/season/form.gohtml:25
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "title"
msgid "Edit Season"
msgstr "Edición de temporada"
#: web/templates/admin/season/form.gohtml:10
2023-09-25 18:10:33 +00:00
#: web/templates/admin/season/form.gohtml:27
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "title"
msgid "New Season"
msgstr "Nueva temporada"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/season/form.gohtml:37
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/index.gohtml:27
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "season"
msgid "Active"
msgstr "Activa"
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/form.gohtml:59
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "input"
msgid "Color"
msgstr "Color"
#: web/templates/admin/season/index.gohtml:6
2023-09-25 18:10:33 +00:00
#: web/templates/admin/season/index.gohtml:12
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:48
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "title"
msgid "Seasons"
msgstr "Temporadas"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/season/index.gohtml:11
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "action"
msgid "Add Season"
msgstr "Añadir temporada"
2023-12-20 18:52:14 +00:00
#: web/templates/admin/season/index.gohtml:25
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgctxt "header"
msgid "Color"
msgstr "Color"
2024-01-13 00:15:24 +00:00
#: web/templates/admin/season/index.gohtml:48
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgid "No seasons added yet."
msgstr "No se ha añadido ninguna temporada todavía."
2023-09-29 18:17:39 +00:00
#: web/templates/admin/season/calendar.gohtml:49
#: web/templates/admin/media/picker.gohtml:61
msgctxt "action"
msgid "Cancel"
msgstr "Cancelar"
2023-10-27 14:04:43 +00:00
#: web/templates/admin/payment.gohtml:6 web/templates/admin/payment.gohtml:12
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:39
2023-10-27 14:04:43 +00:00
msgctxt "title"
msgid "Payment Settings"
msgstr "Parámetros de pago"
#: web/templates/admin/payment.gohtml:17
msgctxt "input"
msgid "Merchant Code"
msgstr "Código del comercio"
#: web/templates/admin/payment.gohtml:26
msgctxt "input"
msgid "Terminal Number"
msgstr "Número de terminal"
#: web/templates/admin/payment.gohtml:36
msgctxt "input"
msgid "Merchant Key (only if must change it)"
msgstr "Clave del comercio (sólo si se debe cambiar)"
#: web/templates/admin/payment.gohtml:38
msgctxt "input"
msgid "Merchant Key"
msgstr "Clave del comercio"
#: web/templates/admin/payment.gohtml:48
msgctxt "title"
msgid "Environment"
msgstr "Entorno"
#: web/templates/admin/payment.gohtml:55
msgctxt "title"
msgid "Integration"
msgstr "Integración"
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
2023-12-22 01:23:18 +00:00
#: web/templates/admin/dashboard.gohtml:10 web/templates/admin/layout.gohtml:79
Get user from database based on cookie and serve login if not logged in
To get the user from the database i have to set the cookie first, that
was already done in database.MustAcquire, but i thought they were too
far apart, even thought they are so related. So, the cookie, and thus
the role, is set when getting the user, that is actually the first thing
to do once the connection is acquired. However, that way the database
package has no knowledge of cookies, and the code that sets the cookie
and retrieves the user are next to each other.
I applied the same logic to the changes of locale.Match: it has not
business knowing that the accept language string comes from a request;
it only needs the actual string. Also, the TODO comment about getting
the user’s locale made no sense, now, because app already knows that
locale, so there is no need to pass the user to the locale package.
Getting the locale is done after retrieving the user from the database,
for the same reason the connection is Acquired as far up as possible:
almost every request will need this value, together with the user and
the database connection.
I am a bit affraid that i will end up with functions that always expect
these three values. Maybe i can put the locale inside user, as it is
the user’s locale, after all, no matter if it came from the database or
the user agent, but connection and user must be separate, i think.
We’ll see.
2023-07-25 23:50:39 +00:00
msgctxt "title"
msgid "Dashboard"
msgstr "Panel"
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/login.gohtml:6 web/templates/admin/login.gohtml:13
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"
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/login.gohtml:31 web/templates/admin/profile.gohtml:46
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 "Contraseña"
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/login.gohtml:40
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 "Entrar"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/services/form.gohtml:8
#: web/templates/admin/services/form.gohtml:25
msgctxt "title"
msgid "Edit Service"
msgstr "Edición de servicio"
#: web/templates/admin/services/form.gohtml:10
#: web/templates/admin/services/form.gohtml:27
msgctxt "title"
msgid "New Service"
msgstr "Nuevo servicio"
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
#: web/templates/admin/services/index.gohtml:6
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:57
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
msgctxt "title"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgid "Services Page"
msgstr "Página de servicios"
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
2023-09-25 18:10:33 +00:00
#: web/templates/admin/services/index.gohtml:11
#: web/templates/admin/home/index.gohtml:11
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
msgctxt "title"
msgid "Carousel"
msgstr "Carrusel"
2024-01-12 18:33:44 +00:00
#: web/templates/admin/services/index.gohtml:57
2023-09-26 14:51:35 +00:00
msgctxt "action"
msgid "Add service"
msgstr "Añadir servicio"
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/index.gohtml:70
msgctxt "header"
msgid "Order"
msgstr "Orden"
#: web/templates/admin/services/index.gohtml:71
2023-09-25 18:10:33 +00:00
msgctxt "header"
msgid "Service"
msgstr "Servicio"
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/index.gohtml:76
2023-09-26 15:00:22 +00:00
msgid "Are you sure you wish to delete this service?"
msgstr "¿Estáis seguro de querer borrar este servicio?"
2024-01-13 00:15:24 +00:00
#: web/templates/admin/services/index.gohtml:97
2023-09-25 18:10:33 +00:00
msgid "No services added yet."
msgstr "No se ha añadido ningún servicio todavía."
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/profile.gohtml:6 web/templates/admin/profile.gohtml:12
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:32
2023-07-26 18:46:09 +00:00
msgctxt "title"
msgid "Profile"
msgstr "Perfil"
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/profile.gohtml:17
Allow users to update their profile images
I do not see the profile image as an “integral part” of the user (i.e.,
no need for constraints), hence i do not want to store it in the
database, as would do for the identification image during check-in.
By default, i store the avatars in /var/lib/camper/avatars, but it is a
variable to allow packagers change this value using the linker.
This is also served as a test bed for uploading files to the server,
that now has a better interface and uses less resources that what i did
to Numerus.
Now the profile handler needs to keep a variable to know the path to the
avatars’ directory, thus i had to change it to a struct nested in app,
much like the fileHandler does. It still has to return the HandlerFunc,
however, as this function needs to close over the user and connection
variables.
Part of #7.
2023-07-28 18:15:09 +00:00
msgctxt "inut"
msgid "Profile Image"
msgstr "Imagen del perfil"
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/profile.gohtml:43
Allow users to update their profile images
I do not see the profile image as an “integral part” of the user (i.e.,
no need for constraints), hence i do not want to store it in the
database, as would do for the identification image during check-in.
By default, i store the avatars in /var/lib/camper/avatars, but it is a
variable to allow packagers change this value using the linker.
This is also served as a test bed for uploading files to the server,
that now has a better interface and uses less resources that what i did
to Numerus.
Now the profile handler needs to keep a variable to know the path to the
avatars’ directory, thus i had to change it to a struct nested in app,
much like the fileHandler does. It still has to return the HandlerFunc,
however, as this function needs to close over the user and connection
variables.
Part of #7.
2023-07-28 18:15:09 +00:00
msgctxt "legend"
msgid "Change password"
msgstr "Cambio de contraseña"
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/profile.gohtml:55
2023-07-26 18:46:09 +00:00
msgctxt "input"
msgid "Password Confirmation"
msgstr "Confirmación de la contraseña"
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/profile.gohtml:65
2023-07-26 18:46:09 +00:00
msgctxt "input"
msgid "Language"
msgstr "Idioma"
2023-08-15 20:35:21 +00:00
#: web/templates/admin/taxDetails.gohtml:6
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:12
2023-08-15 20:35:21 +00:00
msgctxt "title"
msgid "Tax Details"
msgstr "Configuración fiscal"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:17
#: web/templates/admin/taxDetails.gohtml:58
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Business Name"
msgstr "Nombre de empresa"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:26
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "VAT Number"
msgstr "NIF"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:34
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Trade Name"
msgstr "Nombre comercial"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:66
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Address"
msgstr "Dirección"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:74
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "City"
msgstr "Población"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:82
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Province"
msgstr "Provincia"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:90
2023-08-15 20:35:21 +00:00
msgctxt "input"
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Postcode"
2023-08-15 20:35:21 +00:00
msgstr "Código postal"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/taxDetails.gohtml:108
2023-08-15 20:35:21 +00:00
msgctxt "input"
2023-10-14 19:59:36 +00:00
msgid "RTC number"
msgstr "Número RTC"
#: web/templates/admin/taxDetails.gohtml:116
msgctxt "input"
2023-08-15 20:35:21 +00:00
msgid "Currency"
msgstr "Moneda"
2023-10-14 19:59:36 +00:00
#: web/templates/admin/taxDetails.gohtml:126
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Default Language"
msgstr "Idioma por defecto"
2023-10-14 19:59:36 +00:00
#: web/templates/admin/taxDetails.gohtml:136
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Invoice Number Format"
msgstr "Formato de número de factura"
2023-10-14 19:59:36 +00:00
#: web/templates/admin/taxDetails.gohtml:144
2023-08-15 20:35:21 +00:00
msgctxt "input"
msgid "Legal Disclaimer"
msgstr "Nota legal"
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:28
2023-07-26 18:46:09 +00:00
msgctxt "title"
msgid "User Menu"
msgstr "Menú de usuario"
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:36
2023-08-15 20:35:21 +00:00
msgctxt "title"
msgid "Company Settings"
msgstr "Parámetros de la empresa"
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:51
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/index.gohtml:6
#: web/templates/admin/media/index.gohtml:11
msgctxt "title"
msgid "Media"
msgstr "Medios"
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
2023-12-21 20:17:04 +00:00
#: web/templates/admin/layout.gohtml:54 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"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgid "Home Page"
msgstr "Página de inicio"
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
2023-12-22 01:23:18 +00:00
#: web/templates/admin/layout.gohtml:68
2023-09-25 18:10:33 +00:00
msgctxt "action"
msgid "Logout"
msgstr "Salir"
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
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
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "title"
msgid "Media Picker"
msgstr "Selector de medio"
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
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 "Subida de un nuevo medio"
#: web/templates/admin/media/picker.gohtml:22
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/upload.gohtml:17
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 "Archivo"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
#: web/templates/admin/media/picker.gohtml:26
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/form.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
msgid "Maximum upload file size: %s"
msgstr "Tamaño máximo del archivos a subir: %s"
#: web/templates/admin/media/picker.gohtml:31
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/upload.gohtml:26
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 "Subir"
Add campsite map in SVG
I intend to use the same SVG file for customers and employees, so i had
to change Oriol’s design to add a class to layers that are supposed to
be only for customers, like trees. These are hidden in the admin area.
I understood that customers and employees have to click on a campsite to
select it, and then they can book or whatever they need to do to them.
Since customers and employees most certainly will need to have different
listeners on campsites, i decided to add the link with JavaScript. To
do so, i need a custom XML attribute with the campsite’s identifier.
Since i have seen that all campsites have a label, i changed the
“identifier” to the unique combination (company_id, label). The
company_id is there because different companies could have the same
label; i left the campsite_id primary key for foreign constraints.
In this case, as a test, i add an <a> element to the campsite with a
link to edit it; we’ll discuss with Oriol what exactly it needs to do.
However, the original design had the labels in a different layer, that
interfered with the link, as the numbers must be above the path and
the link must wrap the path in order to “inherit” its shape. I had no
other recourse than to move the labels in the same layer as the paths’.
2023-09-24 01:17:13 +00:00
#: 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ón de un medio existente"
Add campsite map in SVG
I intend to use the same SVG file for customers and employees, so i had
to change Oriol’s design to add a class to layers that are supposed to
be only for customers, like trees. These are hidden in the admin area.
I understood that customers and employees have to click on a campsite to
select it, and then they can book or whatever they need to do to them.
Since customers and employees most certainly will need to have different
listeners on campsites, i decided to add the link with JavaScript. To
do so, i need a custom XML attribute with the campsite’s identifier.
Since i have seen that all campsites have a label, i changed the
“identifier” to the unique combination (company_id, label). The
company_id is there because different companies could have the same
label; i left the campsite_id primary key for foreign constraints.
In this case, as a test, i add an <a> element to the campsite with a
link to edit it; we’ll discuss with Oriol what exactly it needs to do.
However, the original design had the labels in a different layer, that
interfered with the link, as the numbers must be above the path and
the link must wrap the path in order to “inherit” its shape. I had no
other recourse than to move the labels in the same layer as the paths’.
2023-09-24 01:17:13 +00:00
#: web/templates/admin/media/picker.gohtml:58
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/index.gohtml:20
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "No media uploaded yet."
msgstr "No se ha subido ningún medio todavía."
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
#: web/templates/admin/media/form.gohtml:6
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/form.gohtml:12
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "title"
msgid "Edit Media"
msgstr "Edición de medio"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/form.gohtml:18
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "input"
msgid "Updated file"
msgstr "Archivo actualizado"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/form.gohtml:27
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "input"
msgid "Filename"
msgstr "Nombre de archivo"
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/index.gohtml:12
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "action"
msgid "Upload media"
msgstr "Subir medio"
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
#: web/templates/admin/media/upload.gohtml:6
2023-09-25 18:10:33 +00:00
#: web/templates/admin/media/upload.gohtml:12
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgctxt "title"
msgid "Upload Media"
msgstr "Subida de medio"
2024-01-13 00:15:24 +00:00
#: pkg/legal/admin.go:258 pkg/app/user.go:249 pkg/campsite/types/option.go:344
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/feature.go:259 pkg/campsite/types/admin.go:453
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:415 pkg/services/admin.go:319
2023-12-22 01:23:18 +00:00
msgid "Name can not be empty."
msgstr "No podéis dejar el nombre en blanco."
2024-01-13 00:15:24 +00:00
#: pkg/legal/admin.go:259 pkg/campsite/types/option.go:345
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/feature.go:260 pkg/campsite/types/admin.go:454
2023-12-22 01:23:18 +00:00
msgid "Name must have at least one letter."
msgstr "El nombre tiene que tener como mínimo una letra."
2024-01-12 18:33:44 +00:00
#: pkg/carousel/admin.go:269 pkg/campsite/types/carousel.go:223
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "input"
2023-09-22 00:17:56 +00:00
msgid "Slide image"
msgstr "Imagen de la diapositiva"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2024-01-12 18:33:44 +00:00
#: pkg/carousel/admin.go:270 pkg/campsite/types/carousel.go:224
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "action"
2023-09-22 00:17:56 +00:00
msgid "Set slide image"
msgstr "Establecer la imagen de la diapositiva"
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2024-01-12 18:33:44 +00:00
#: pkg/carousel/admin.go:339 pkg/campsite/types/carousel.go:297
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgid "Slide image can not be empty."
msgstr "No podéis dejar la imagen de la diapositiva en blanco."
2024-01-12 18:33:44 +00:00
#: pkg/carousel/admin.go:340 pkg/campsite/types/carousel.go:298
2023-09-22 00:17:56 +00:00
msgid "Slide image must be an image media type."
msgstr "La imagen de la diapositiva tiene que ser un medio de tipo imagen."
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
2023-10-14 19:59:36 +00:00
#: pkg/app/login.go:56 pkg/app/user.go:246 pkg/company/admin.go:210
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:269
2023-07-24 15:17:15 +00:00
msgid "Email can not be empty."
msgstr "No podéis dejar el correo-e en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/app/login.go:57 pkg/app/user.go:247 pkg/company/admin.go:211
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:270
2023-07-24 15:17:15 +00:00
msgid "This email is not valid. It should be like name@domain.com."
msgstr "Este correo-e no es válido. Tiene que ser parecido a nombre@dominio.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
2023-07-24 15:17:15 +00:00
msgid "Password can not be empty."
msgstr "No podéis dejar la contraseña en blanco."
2023-07-26 18:46:09 +00:00
#: pkg/app/login.go:86
2023-07-24 15:17:15 +00:00
msgid "Invalid user or password."
msgstr "Usuario o contraseña incorrectos."
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
2023-08-08 00:29:14 +00:00
#: pkg/app/user.go:197
2023-07-26 18:46:09 +00:00
msgctxt "language option"
msgid "Automatic"
msgstr "Automático"
2023-08-08 00:29:14 +00:00
#: pkg/app/user.go:250
2023-07-26 18:46:09 +00:00
msgid "Confirmation does not match password."
msgstr "La confirmación no se corresponde con la contraseña."
2023-10-14 19:59:36 +00:00
#: pkg/app/user.go:251 pkg/company/admin.go:226
2023-07-26 18:46:09 +00:00
msgid "Selected language is not valid."
msgstr "El idioma escogido no es válido."
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
#: pkg/app/user.go:253
Allow users to update their profile images
I do not see the profile image as an “integral part” of the user (i.e.,
no need for constraints), hence i do not want to store it in the
database, as would do for the identification image during check-in.
By default, i store the avatars in /var/lib/camper/avatars, but it is a
variable to allow packagers change this value using the linker.
This is also served as a test bed for uploading files to the server,
that now has a better interface and uses less resources that what i did
to Numerus.
Now the profile handler needs to keep a variable to know the path to the
avatars’ directory, thus i had to change it to a struct nested in app,
much like the fileHandler does. It still has to return the HandlerFunc,
however, as this function needs to close over the user and connection
variables.
Part of #7.
2023-07-28 18:15:09 +00:00
msgid "File must be a valid PNG or JPEG image."
msgstr "El archivo tiene que ser una imagen PNG o JPEG válida."
2023-12-22 01:23:18 +00:00
#: pkg/app/admin.go:62
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 "Acceso prohibido"
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:348
2023-10-06 11:26:01 +00:00
msgid "Minimum can not be empty."
msgstr "No podéis dejar el mínimo en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:349
2023-10-06 11:26:01 +00:00
msgid "Minimum must be an integer number."
msgstr "El valor de mínimo tiene que ser un número entero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:351
2023-10-06 11:26:01 +00:00
msgid "Minimum must be zero or greater."
msgstr "El valor de mínimo tiene que ser como mínimo cero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:354
2023-10-06 11:26:01 +00:00
msgid "Maximum can not be empty."
msgstr "No podéis dejar el máxmimo en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:355
2023-10-06 11:26:01 +00:00
msgid "Maximum must be an integer number."
msgstr "El valor del máximo tiene que ser un número entero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:357
2023-10-06 11:26:01 +00:00
msgid "Maximum must be equal or greater than minimum."
msgstr "El valor del máximo tiene que ser igual o mayor al del mínimo."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:361 pkg/campsite/types/admin.go:467
2023-10-06 11:26:01 +00:00
msgid "Price per night can not be empty."
msgstr "No podéis dejar el precio por noche en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:362 pkg/campsite/types/admin.go:468
2023-10-06 11:26:01 +00:00
msgid "Price per night must be a decimal number."
msgstr "El precio por noche tien que ser un número decimal."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/option.go:363 pkg/campsite/types/admin.go:469
2023-10-06 11:26:01 +00:00
msgid "Price per night must be zero or greater."
msgstr "El precio por noche tiene que ser como mínimo cero."
2024-01-13 00:15:24 +00:00
#: pkg/campsite/types/feature.go:258 pkg/services/admin.go:318
2023-10-13 18:30:31 +00:00
msgid "Selected icon is not valid."
msgstr "El icono escogido no es válido."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:304
2023-09-22 00:17:56 +00:00
msgctxt "input"
msgid "Cover image"
msgstr "Imagen de portada"
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:305
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgctxt "action"
msgid "Set campsite type cover"
msgstr "Establecer la portada del tipo de alojamiento"
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:456
Add the sample campsite types to the demo file
Since campsite types need a media, i have to insert also images to the
media relation. The best would be to use PostgreSQL’s
pg_read_binary_file to read the media content from actual files when
inserting the new rows, but the files need to be within the database
cluster directory, or have to use an absolute path when running as a
superuser to read from files outside the cluster directory, which means
that it would depend on the path where i leave the files, that is
different in development that in staging.
To avoid that problem i can simply insert the rows using their base64
strings, with PostgreSQL’s decode. The images are kind of small, but
i was worried that each change in demo.sql would duplicate that data in
git, even if the change is not related to the images, because git stores
the whole file; even if small, soon everything adds up.
I do not care if the _final_ demo.sql is big, as this file is packaged
in a different deb and is only installed in staging, so i’ve chosen to
use m4 to build a single “amalgamated” SQL file from the base .sql
file and the individual image files converted to base64 strings. That
way, each image is individually managed by git and the base .sql file
does not balloon up for each little change.
Changed m4’s quotes to [[ ]] because the default ` ' was interfering
with Intellij’s syntax highlighting.
2023-09-10 01:57:46 +00:00
msgid "Cover image can not be empty."
msgstr "No podéis dejar la imagen de portada en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:457
2023-09-22 00:17:56 +00:00
msgid "Cover image must be an image media type."
msgstr "La imagen de portada tiene que ser un medio de tipo imagen."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:461
2023-09-29 18:17:39 +00:00
msgid "Maximum number of campers can not be empty."
msgstr "No podéis dejar el número máximo de personas en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:462
2023-09-29 18:17:39 +00:00
msgid "Maximum number of campers must be an integer number."
msgstr "El número máximo de personas tiene que ser entero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:463
2023-09-29 18:17:39 +00:00
msgid "Maximum number of campers must be one or greater."
msgstr "El número máximo de personas no puede ser cero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:472
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights can not be empty."
msgstr "No podéis dejar el número mínimo de noches en blanco."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:473
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights must be an integer."
msgstr "El número mínimo de noches tiene que ser entero."
2024-01-10 20:52:49 +00:00
#: pkg/campsite/types/admin.go:474
2023-10-01 19:14:39 +00:00
msgid "Minimum number of nights must be one or greater."
msgstr "El número mínimo de noches no puede ser cero."
2023-12-20 18:52:14 +00:00
#: pkg/campsite/admin.go:226 pkg/booking/public.go:278
2023-08-14 18:18:26 +00:00
msgid "Selected campsite type is not valid."
msgstr "El tipo de alojamiento escogido no es válido."
Add campsite map in SVG
I intend to use the same SVG file for customers and employees, so i had
to change Oriol’s design to add a class to layers that are supposed to
be only for customers, like trees. These are hidden in the admin area.
I understood that customers and employees have to click on a campsite to
select it, and then they can book or whatever they need to do to them.
Since customers and employees most certainly will need to have different
listeners on campsites, i decided to add the link with JavaScript. To
do so, i need a custom XML attribute with the campsite’s identifier.
Since i have seen that all campsites have a label, i changed the
“identifier” to the unique combination (company_id, label). The
company_id is there because different companies could have the same
label; i left the campsite_id primary key for foreign constraints.
In this case, as a test, i add an <a> element to the campsite with a
link to edit it; we’ll discuss with Oriol what exactly it needs to do.
However, the original design had the labels in a different layer, that
interfered with the link, as the numbers must be above the path and
the link must wrap the path in order to “inherit” its shape. I had no
other recourse than to move the labels in the same layer as the paths’.
2023-09-24 01:17:13 +00:00
#: pkg/campsite/admin.go:227
2023-08-14 18:18:26 +00:00
msgid "Label can not be empty."
msgstr "No podéis dejar la etiqueta en blanco."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:186
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "January"
msgstr "enero"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:187
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "February"
msgstr "febrero"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:188
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "March"
msgstr "marzo"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:189
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "April"
msgstr "abril"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:190
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "May"
msgstr "mayo"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:191
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "June"
msgstr "junio"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:192
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "July"
msgstr "julio"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:193
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "August"
msgstr "agosto"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:194
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "September"
msgstr "septiembre"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:195
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "October"
msgstr "octubre"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:196
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "November"
msgstr "noviembre"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:197
2023-09-27 00:23:09 +00:00
msgctxt "month"
msgid "December"
msgstr "diciembre"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:416
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgid "Color can not be empty."
msgstr "No podéis dejar el color en blanco."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:417
Add seasons’ relation, functions, and admin section
Seasons have a color to show on the calendar. I need them in HTML format
(e.g., #123abc) in order to set as value to `<input type="color">`, but
i did not want to save them as text in the database, as integers are
better representations of colors—in fact, that’s what the HTML syntax
also is: an integer.
I think the best would be to create an extension that adds an HTML color
type, with functions to convert from many representations (e.g., CSS’
rgb or even color names) to integer and back. However, that’s a lot of
work and i can satisfy Camper’s needs with just a couple of functions
and a domain.
To show the color on the index, at first tried to use a read-only
`<input type="color">`, but seems that this type of input can not be
read-only and must be disabled instead. However, i do not know whether
it makes sense to have a disabled input outside a form “just” to show
a color; i suspect it does not. Thus, at the end i use SVG with a
single circle, which is better that a 50%-rounded div with a background
color, even if the result is the same—SVG **is** intended for showing
pictures, which is this case.
2023-08-16 18:15:57 +00:00
msgid "This color is not valid. It must be like #123abc."
msgstr "Este color no es válido. Tiene que ser parecido a #123abc."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:517
2023-09-29 18:17:39 +00:00
msgctxt "action"
msgid "Unset"
msgstr "Desasignar"
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:548
2023-09-29 18:17:39 +00:00
msgid "Start date can not be empty."
msgstr "No podéis dejar la fecha de inicio en blanco."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:549
2023-09-29 18:17:39 +00:00
msgid "Start date must be a valid date."
msgstr "La fecha de inicio tiene que ser una fecha válida."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:551
2023-09-29 18:17:39 +00:00
msgid "End date can not be empty."
msgstr "No podéis dejar la fecha final en blanco."
2024-01-13 00:15:24 +00:00
#: pkg/season/admin.go:552
2023-09-29 18:17:39 +00:00
msgid "End date must be a valid date."
msgstr "La fecha final tiene que ser una fecha válida."
2023-12-20 18:52:14 +00:00
#: pkg/company/admin.go:193 pkg/booking/public.go:256
2023-08-15 20:35:21 +00:00
msgid "Selected country is not valid."
msgstr "El país escogido no es válido."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:197
2023-08-15 20:35:21 +00:00
msgid "Business name can not be empty."
msgstr "No podéis dejar el nombre de empresa en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:198
2023-08-15 20:35:21 +00:00
msgid "Business name must have at least two letters."
msgstr "El nombre de la empresa tiene que tener como mínimo dos letras."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:200
2023-08-15 20:35:21 +00:00
msgid "VAT number can not be empty."
msgstr "No podéis dejar el NIF en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:201
2023-08-15 20:35:21 +00:00
msgid "This VAT number is not valid."
msgstr "Este NIF no es válido."
2023-12-20 18:52:14 +00:00
#: pkg/company/admin.go:205 pkg/booking/public.go:272
2023-08-15 20:35:21 +00:00
msgid "Phone can not be empty."
msgstr "No podéis dejar el teléfono en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/company/admin.go:206 pkg/booking/public.go:273
2023-08-15 20:35:21 +00:00
msgid "This phone number is not valid."
msgstr "Este teléfono no es válido."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:214
2023-08-15 20:35:21 +00:00
msgid "This web address is not valid. It should be like https://domain.com/."
msgstr "Esta dirección web no es válida. Tiene que ser parecido a https://dominio.com/."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:216
2023-08-15 20:35:21 +00:00
msgid "Address can not be empty."
msgstr "No podéis dejar la dirección en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:217
2023-08-15 20:35:21 +00:00
msgid "City can not be empty."
msgstr "No podéis dejar la población en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:218
2023-08-15 20:35:21 +00:00
msgid "Province can not be empty."
msgstr "No podéis dejar la provincia en blanco."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:219
2023-08-15 20:35:21 +00:00
msgid "Postal code can not be empty."
msgstr "No podéis dejar el código postal en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/company/admin.go:220 pkg/booking/public.go:265
2023-08-15 20:35:21 +00:00
msgid "This postal code is not valid."
msgstr "Este código postal no es válido."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:224
msgid "RTC number can not be empty."
msgstr "No podéis dejar el número RTC en blanco."
#: pkg/company/admin.go:225
2023-08-15 20:35:21 +00:00
msgid "Selected currency is not valid."
msgstr "La moneda escogida no es válida."
2023-10-14 19:59:36 +00:00
#: pkg/company/admin.go:227
2023-08-15 20:35:21 +00:00
msgid "Invoice number format can not be empty."
msgstr "No podéis dejar el formato de número de factura en blanco."
Allow users to update their profile images
I do not see the profile image as an “integral part” of the user (i.e.,
no need for constraints), hence i do not want to store it in the
database, as would do for the identification image during check-in.
By default, i store the avatars in /var/lib/camper/avatars, but it is a
variable to allow packagers change this value using the linker.
This is also served as a test bed for uploading files to the server,
that now has a better interface and uses less resources that what i did
to Numerus.
Now the profile handler needs to keep a variable to know the path to the
avatars’ directory, thus i had to change it to a struct nested in app,
much like the fileHandler does. It still has to return the HandlerFunc,
however, as this function needs to close over the user and connection
variables.
Part of #7.
2023-07-28 18:15:09 +00:00
#: 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 "Se ha detectado un intento de falsificación de petición en sitios cruzados."
2023-08-14 09:43:58 +00:00
Change media picker from <div> to <dialog> and make it modal
Have to call Dialog.showModal when HTMx loaded the dialog in the DOM,
so had to add a onLoad event listened that checks whether the loaded
element is actually a DIALOG.
Had to restrict the margin: 0 for all elements (*) to exclude dialog,
because the browser sets it to auto, and i did not want to set it again
just because i was too overzealous with my “reset”.
The rest of the CSS is just to have a sticky header and footer, and see
the cancel button, that works as a “close”, all the time.
Finally, i realized that if i add the dialog at the end of the fieldset
and let HTMx inherit its hx-target and hx-swap, i no longer need to set
them in the dialog, as HTMx will always replace the fieldset, and i can
have the dialog side by side the current content of the fieldset, that
it was very confusing seeing it disappear when trying to select a new
media.
The cancel button could now just remove the dialog instead of making the
POST, but in local it makes no difference; we’lls see what happens on
production.
2023-09-22 00:11:03 +00:00
#: pkg/media/admin.go:265
Add the surroundings static page
This page is “highly stylized”, with a masonry-like grid, that i did not
know how to generate automatically from data defined in PostgreSQL,
therefore with Oriol we agreed to have this one as a static page and
we will see what we can do if the customer asks to be able to change
it.
I was a bit undecided on whether the icons in the bottom part of the
page should be defined in the CSS or with style="" and CSS variables,
like i do for the campsite type in the home page.
At first i thought that it should use CSS variables, mostly for
coherence: if another section of the web does it for its background
image, why no this one. The difference is that the home page is
dynamically created from the database, while this page is static and we
know what icons we need, thus it makes more sense to move it to the
stylesheet file, because then it will be downloaded by user agents that
actually want to use it (e.g., browsers, but not Braille terminals).
2023-09-16 22:11:39 +00:00
msgid "Uploaded file can not be empty."
msgstr "No podéis dejar el archivo del medio en blanco."
Change media picker from <div> to <dialog> and make it modal
Have to call Dialog.showModal when HTMx loaded the dialog in the DOM,
so had to add a onLoad event listened that checks whether the loaded
element is actually a DIALOG.
Had to restrict the margin: 0 for all elements (*) to exclude dialog,
because the browser sets it to auto, and i did not want to set it again
just because i was too overzealous with my “reset”.
The rest of the CSS is just to have a sticky header and footer, and see
the cancel button, that works as a “close”, all the time.
Finally, i realized that if i add the dialog at the end of the fieldset
and let HTMx inherit its hx-target and hx-swap, i no longer need to set
them in the dialog, as HTMx will always replace the fieldset, and i can
have the dialog side by side the current content of the fieldset, that
it was very confusing seeing it disappear when trying to select a new
media.
The cancel button could now just remove the dialog instead of making the
POST, but in local it makes no difference; we’lls see what happens on
production.
2023-09-22 00:11:03 +00:00
#: pkg/media/admin.go:324
Manage all media uploads in a single place
It made no sense to have a file upload in each form that needs a media,
because to reuse an existing media users would need to upload the exact
same file again; this is very unusual and unfriendly.
A better option is to have a “centralized” media section, where people
can upload files there, and then have a picker to select from there.
Ideally, there would be an upload option in the picker, but i did not
add it yet.
I’ve split the content from the media because i want users to have the
option to update a media, for instance when they need to upload a
reduced or cropped version of the same photo, without an edit they would
need to upload the file as a new media and then update all places where
the old version was used. And i did not want to trouble people that
uploads the same photo twice: without the separate relation, doing so
would throw a constraint error.
I do not believe there is any security problem to have all companies
link their media to the same file, as they were already readable by
everyone and could upload the data from a different company to their
own; in other words, it is not worse than it was now.
2023-09-20 23:56:44 +00:00
msgid "Filename can not be empty."
msgstr "No podéis dejar el nombre del archivo en blanco."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:76
2023-10-27 14:04:43 +00:00
msgctxt "redsys environment"
msgid "Test"
msgstr "Pruebas"
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:80
2023-10-27 14:04:43 +00:00
msgctxt "redsys environment"
msgid "Live"
msgstr "Real"
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:89
2023-10-27 14:04:43 +00:00
msgctxt "redsys integration"
msgid "InSite"
msgstr "InSite"
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:93
2023-10-27 14:04:43 +00:00
msgctxt "redsys integration"
msgid "Redirect"
msgstr "Redirección"
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:137
2023-10-27 14:04:43 +00:00
msgid "Merchant code can not be empty."
msgstr "No podéis dejar el código del comercio en blanco."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:138
2023-10-27 14:04:43 +00:00
msgid "Merchant code must be exactly nine digits long."
msgstr "El código del comercio tiene que ser de nueve dígitos."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:139
2023-10-27 14:04:43 +00:00
msgid "Merchant code must be a number."
msgstr "El código del comercio tiene que ser un número."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:143
2023-10-27 14:04:43 +00:00
msgid "Terminal number can not be empty."
msgstr "No podéis dejar el número de terminal en blanco."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:144
2023-10-27 14:04:43 +00:00
msgid "Terminal number must be a number between 1 and 999."
msgstr "El número de terminal tiene que ser entre 1 y 999."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:152
2023-10-27 14:04:43 +00:00
msgid "Selected environment is not valid."
msgstr "El entorno escogido no es válido."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:153
2023-10-27 14:04:43 +00:00
msgid "Selected integration is not valid."
msgstr "La integración escogida no es válida."
2023-12-21 20:17:04 +00:00
#: pkg/booking/admin.go:156
2023-10-27 14:04:43 +00:00
msgid "The merchant key is not valid."
msgstr "Esta clave del comercio no es válida."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:260
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Full name can not be empty."
msgstr "No podéis dejar el nombre y los apellidos en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:261
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Full name must have at least one letter."
msgstr "El nombre y los apellidos tienen que tener como mínimo una letra."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:279
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Arrival date can not be empty"
msgstr "No podéis dejar la fecha de llegada en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:280
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Arrival date must be a valid date."
msgstr "La fecha de llegada tiene que ser una fecha válida."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:284
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Departure date can not be empty"
msgstr "No podéis dejar la fecha de partida en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:285
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "Departure date must be a valid date."
msgstr "La fecha de partida tiene que ser una fecha válida."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:286
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "The departure date must be after the arrival date."
msgstr "La fecha de partida tiene que ser posterior a la de llegada."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:289
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "It is mandatory to agree to the reservation conditions."
msgstr "Es obligatorio aceptar las condiciones de reserva."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:292
Implement Redsys request signature in PostgreSQL
Every company need to have its own merchant code and encryption key,
thus it is not possible to use environment variables to keep that data,
and i have to store it in the database.
I do not want to give SELECT permission on the encryption key to guest,
because i am going to fuck it up sooner or later, and everyone would be
able to read that secret; i know it would. Therefore, i need a security
definer function that takes the data to encrypt, use the key to encrypt
it, and returns the result; nobody else should have access to that key,
not even admins!
By the way, i found out that every merchant receives the same key, thus
it is not a problem to keep it in the repository.
Since i need that SQL function to encrypt the data, i thought that i may
go the whole nine yards and sign the request in PostgreSQL too, after
all the data to sign comes from there, and it has JSON functions to
create and base64-code an object.
Fortunately, pg_crypto has all the functions that i need, but i can no
longer keep that extension inside the auth schema, because it is used
from others, and the public schema, like every other extensions, seems
more appropriate.
Instead of having the list of currency and language codes that Redsys
uses as constants in the code, i moved that as field to the currency
and language relations, so i can simply pass the lang_tag to the
function and it can transform that tag to the correct code; the currency
is from the company’s relation, since it is the only currency used in
the whole application (for now).
As a consequence, i had to grant execute to currency and the parse_price
functions to guest, too.
To generate the test data used in the unit tests, i used a third-party
PHP implementation[0], but i only got from that the resulting base64-coded
JSON object and signature, using the same that as in the unit test, and
did not use any code from there.
PostgreSQL formats the JSON as text differently than most
implementations i have seen: it adds spaces between the key name and
the colons, and space between the value and the separating comma. The
first implementation used replace() to format the JSON as exactly as
the PHP implementation, so that the result matches, and then tried to do
generate the form by hand using the output from PostgreSQL without the
replace(), to verify that Redsys would still accept my input. Finally,
i adjusted the unit test to whatever pg_prove said it was getting from
the function.
I still have the form’s action hard-codded to the test environment, but
the idea is that administrators should be able to switch from test to
live themselves. That means that i need that info in the redsys
relation as well. I think this is one of the few use cases for SQL’s
types, because it is unlikely to change anytime soon, and i do not need
the actual labels.
Unfortunately, i could not use enumerations for the request’s
transaction type because i can not attach an arbitrary number to the
enum’s values. Having a relation is overkill, because i would need
a constant in Go to refer to its primary key anyway, thus i kept the
same constant i had before for that. Language and currency constant
went out, as this is in the corresponding relations.
In setup_redsys i must have a separate update if the encrypt_key is null
because PostgreSQL checks constraints before key conflict, and i do
not want to give a default value to the key if the row is not there yet.
The problem is that i want to use null to mean “keep the same password”,
because it is what i intend to do with the user-facing form: leave the
input empty to keep the same password.
As now Go needs to pass composite types back and forth with PostgreSQL,
i need to register these types, and i have to do it every time because
the only moment i have access to the non-pooled connection is in the
AfterConnect function, but at that point i have no idea whether the
user is going to request a payment. I do not know how much the
performance degrades because of this.
[0]: https://github.com/ssheduardo/sermepa/blob/master/src/Sermepa/Tpv/Tpv.php
2023-10-26 23:52:04 +00:00
#, c-format
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
msgid "%s can not be empty"
msgstr "No podéis dejar %s en blanco."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:293
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#, c-format
msgid "%s must be an integer."
msgstr "%s tiene que ser un número entero."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:294
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#, c-format
msgid "%s must be %d or greater."
msgstr "%s tiene que ser como mínimo %d."
2023-12-20 18:52:14 +00:00
#: pkg/booking/public.go:295
Add the first draft of the booking and payment forms
The form is based on the one in the current website, but in a single
page instead of split into many pages; possibly each <fieldset> should
be in a separate page/view. The idea is for Oriol to check the design
and decide how it would be presented to the user, so i needed something
to show him first.
I hardcoded the **test** data for the customer’s Redsys account. Is
this bad? I hope not, but i am not really, really sure.
The data sent to Redsys is just a placeholder because there are booking
details that i do not know, like what i have to do with the “teenagers”
field or the area preferences, thus i can not yet have a booking
relation. Nevertheless, had to generate a random order number up to
12-chars in length or Redsys would refuse the payment, claiming that
the order is duplicated.
The Redsys package is based on the PHP code provided by Redsys
themselves, plus some hints at the implementations from various Go
packages that did not know why they were so complicated.
Had to grant select on table country to guest in order to show the
select with the country options.
I have changed the “Postal code” input in taxDetails for “Postcode”
because this is the spell that it is used in the current web, i did not
see a reason to change it—it is an accepted form—, and i did not want to
have inconsistencies between forms.
2023-10-19 19:37:34 +00:00
#, c-format
msgid "%s must be at most %d."
msgstr "%s tiene que ser como máximo %d"
2024-01-13 00:15:24 +00:00
#~ msgctxt "header"
#~ msgid "Translations"
#~ msgstr "Traducciones"
#~ msgctxt "title"
#~ msgid "Translate Season to %s"
#~ msgstr "Traducción de la temporada a %s"
#~ msgid "Source:"
#~ msgstr "Origen:"
#~ msgctxt "input"
#~ msgid "Translation:"
#~ msgstr "Traducción"
#~ msgctxt "action"
#~ msgid "Translate"
#~ msgstr "Traducir"
#~ msgctxt "title"
#~ msgid "Translate Service to %s"
#~ msgstr "Traducción del servicio a %s"
2024-01-10 20:52:49 +00:00
#~ msgctxt "title"
2024-01-12 18:33:44 +00:00
#~ msgid "Translate Carousel Slide to %s"
#~ msgstr "Traducción de la diapositiva de carrusel a %s"
#~ msgctxt "title"
2024-01-10 20:52:49 +00:00
#~ msgid "Translate Campsite Type Feature to %s"
#~ msgstr "Traducción de la característica del tipo de alojamiento a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Carousel Slide to %s"
#~ msgstr "Traducción de la diapositiva de carrusel del tipo de alojamiento a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type Option to %s"
#~ msgstr "Traducción de la opción del tipo de alojamiento a %s"
#~ msgctxt "title"
#~ msgid "Translate Campsite Type to %s"
#~ msgstr "Traducción de tipo de alojamiento a %s"
2023-12-22 02:32:40 +00:00
#~ msgid "Starting from %s €/night"
#~ msgstr "A partir de %s €/noche"
#~ msgctxt "season"
#~ msgid "Closed"
#~ msgstr "Cerrado"
2023-12-12 22:16:04 +00:00
#~ msgctxt "title"
#~ msgid "Party Details"
#~ msgstr "Datos de los visitantes"
#~ msgctxt "input"
#~ msgid "Adults"
#~ msgstr "Adultos"
#~ msgctxt "input"
#~ msgid "Teenagers (from 11 to 16 years old)"
#~ msgstr "Adolescentes (de 11 a 16 años)"
#~ msgctxt "input"
#~ msgid "Children (up to 10 years old)"
#~ msgstr "Niños (hasta 10 años)"
#~ msgctxt "input"
#~ msgid "Dogs"
#~ msgstr "Perros"
#~ msgid "Number of adults can not be empty"
#~ msgstr "No podéis dejar el número de adultos blanco."
#~ msgid "Number of adults must be an integer."
#~ msgstr "El número de adultos tiene que ser entero."
#~ msgid "Number of adults must be one or greater."
#~ msgstr "El número de adultos no puede ser cero."
#~ msgid "Number of teenagers can not be empty"
#~ msgstr "No podéis dejar el número de adolescentes en blanco."
#~ msgid "Number of teenagers must be an integer."
#~ msgstr "El número de adolescentes tiene que ser entero."
#~ msgid "Number of teenagers must be zero or greater."
#~ msgstr "El número de adolescentes tiene que ser como mínimo cero."
#~ msgid "Number of children can not be empty"
#~ msgstr "No podéis dejar el número de niños en blanco."
#~ msgid "Number of children must be an integer."
#~ msgstr "El número de niños tiene que ser entero."
#~ msgid "Number of children must be zero or greater."
#~ msgstr "El número de niños tiene que ser como mínimo cero."
#~ msgid "Number of dogs can not be empty"
#~ msgstr "No podéis dejar el número de perros en blanco."
#~ msgid "Number of dogs must be an integer."
#~ msgstr "El número de perros tiene que ser entero."
#~ msgid "Number of dogs must be zero or greater."
#~ msgstr "El número de perros tiene que ser como mínimo cero."
2023-10-13 11:40:48 +00:00
#~ msgctxt "title"
#~ msgid "Pricing"
#~ msgstr "Precios"
#~ msgctxt "input"
#~ msgid "Pricing"
#~ msgstr "Precios"
#~ msgctxt "input"
#~ msgid "Features"
#~ msgstr "Características"
2023-10-06 16:58:24 +00:00
#~ msgid "Singular Lodges"
#~ msgstr "Alojamientos singulares"
2023-10-06 11:26:01 +00:00
#~ msgctxt "campsite type"
#~ msgid "Translations"
#~ msgstr "Traducciones"
Add the services page
This page is more or less similar to home, in terms of database: it
has a carousel and a list of items; in this case, the definition of
campsite services.
As i said early, when adding the home carousel, this carousel has its
own relation and set of functions to manage slides. They are also
duplicated in Go code, but i think i will need to refactor it later to
a carousel package or something like that, because both relations have
the exact same fields and types, so it makes no sense to have twice the
same code.
I already did it with the CSS and JavaScript code, mostly because it was
easier to replace the `.surroundings div` selector with `.carousel`, and
because that way i can have a single template that loads and initializes
Slick.
There is no UI to create or edit service definitions, although there are
the SQL functions, because i have no more time now, and Oriol needs to
check that the style is correct for that page.
2023-09-17 01:42:16 +00:00
#~ msgid "Surroundings"
#~ msgstr "Entorno"
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 "Leyenda"
2023-08-14 09:43:58 +00:00
#~ msgctxt "input"
#~ msgid "Title"
#~ msgstr "Título"
#~ msgctxt "title"
#~ msgid "Pages"
#~ msgstr "Páginas"
#~ msgctxt "action"
#~ msgid "Add Page"
#~ msgstr "Añadir página"
#~ msgctxt "header"
#~ msgid "Title"
#~ msgstr "Título"