Until now i always had the translations be empty strings if some columns
did not have the full translation, but this is going too far on the
non-NULL policy: surely they have a translations, but we do not know it
yet; this is the exact type of situations NULL values are for.
Besides the philosophical distinction, having empty strings instead of
NULLs is less practical, because i no longer can user coalesce() to
retrieve the default language text in case the translation for that
particular field is not available, even if the row for a locale exists.
In time i will change all _i18n relations, but for now only these from
campsite follow the “new policy”.
A small page with a brief description, carousel, and feature list of
each individual accommodation.
Most of the relations and functions for carousel and features are like
the ones for campsite types, but i had to use the accommodation’s label
to find them, because they do not have slugs; i did not even though
these would be public, and they already have a label, although not
unique for all companies, like UUID slugs are.
I can not use <a> in that map because Leaflet handles the mouse over
before the anchors sees it, thus it is impossible to click on them; i
have to use a Leaflet layer.
Fortunately, i can just use the <path>’s coordinates as
the polygon points, because with CRS.Simple the coordinates map to
pixel, except for the reversed Y/latitude coordinate. Unfortunately,
<path> coordinates are not straightforward to get: I have to follow the
drawing coordinates, taking into account the current transformation
(CTM), and keeping the last point around for relative coordinates.
Bézier curves are simplified to a straight line from start to end.
There is one single accommodation that started with a relative move
command (m), which apparently have to be treated as an absolute
move (M), but subsequent pairs are treated as relative coordinates[0].
It was easier for me to convert that relative move to absolute and add
a relative lineto command (l) to the next pair.
For now, all i do is highlight the accommodation and zoom it on click,
because i do not know how i should the accommodation’s information.
[0]: https://www.w3.org/TR/SVG11/paths.html#PathDataMovetoCommands
In the map i added in e3503187d, paths around each accommodation
inherited the fill and stroke from the group, thus i could just override
that fill at the anchor level, but the current map sets the fill to each
accommodation’s path, party because the text is not a path too, partly
because Affinity is a visual tool only and does not give a shit about
mark up.
If we keep the text in a group, however, we can set the fill of the area
using CSS too, although it is not nice due to `!important`, but still.
There was a plot, however, #93, that had the area in a group too, and
i had to remove that group manually.
It seems that the prefix got removed in one of the edits.
Also, Affinity does not give a fuck to what classes we give to the
elements, and just removes them, thus .guest-only no longer matches, and
had to hide the layers by id. Hope they hold this time.
There is no kayaking, canoe, or raft icon in Font Awesome[0], so i redid
the kayak icon in more or less the same style, but shittier, of course.
Oriol also asked me to add the sailboat, that may replace the use of
kayak.
[0]: https://github.com/FortAwesome/Font-Awesome/issues/10772
We were using what was very clearly a campfire as the icon for the
barbecue service, when we first replaced it with a Font Awesome icon
we chose an icon that was neither campfire nor barbecue (flame-curved),
but now Oriol wanted one that left no doubt it was a barbecue.
Instead of replacing the campfire SVG with that of the barbecue, i have
chosen a campfire image from Font Awesome for our icon, and added a
separate icon for that service.
It is virtually impossible to see when such a field fails prior to
submit the form, unless you happen to have the correct language selected
at the time.
Leave it to the backend’s validation for now.
Otherwise, the browser assumes they are two different resources, because
i am telling it so with the two URI, and loads the same file twice,
triggering the execution of startup functions, such as the ones that
convert textareas to CKEditor divs, twice.
Apparently, each campsite type could have different check-in and
check-out times, thus i need them in the database.
I thought about using an integer or a datetime field, but customer seems
to want a text field to maybe add “before” and “after” there as well.
Translatable text it is.
Otherwise, we can not show the error message to the user, although it
assumes only the default language has error message, which is the case
for now, but….
Previously, the only type with options was plots, that was always the
third fieldset, which was the wrong thing to hardcode, but it was done
in a hurry. Now there are more types with options, so we have to do it
properly.
I also changed the translatable link to not include any HTML, because it
meant that i had to retranslate them just to add a new attribute, that
does not make much sense—the attribute is not even translatable, thus
all translations must include it verbatim.
I tried to use ../, and ../../ to make the routes relatives, but it
would not work well because the same page would have two URLs, one
ending with slash and another without, and the relative links would be
different on each case.
I need to have a single top-level element in order to serialize to XML
when returning the editor’s content back to the text area, because,
unlike PostgreSQL, XMLSerializer only works with XML documents.
I added a <div> because this is the least “semantic” block element there
is, but Oriol seems to have trouble in services when trying to align
services using a grid due to this extra div.
Now i still use the div to serialize to XML, but then remove that
top-level element from the output string by stripping out its label. I
can not be sure that all browsers would serialize the <div> in the
same way, thus i can not use fixed indices in call to substring.
This is mostly because it is required for the “Digital Kit”, but it also
works in our favor because now i can version the URL to the static
resources.
Go 1.18 adds the info from git if the package is build from a git
repository, but this is not the case in OBS, so i instead relay on a
constant for the version number. This constant is “updated” by Debian’s
rules, mostly due to the discussion in [0].
[0]: https://github.com/golang/go/issues/22706
It is for people aged 17 or olded, not 16. I was confused by the
expression “over 16”, that **seems** to mean 17 or older, but actually
includes people aged 16, too.