From 443ae1e05dc8f6de4e357097718c306bcbeed155 Mon Sep 17 00:00:00 2001 From: Stefan Bethke Date: Sat, 17 Oct 2026 02:13:21 +0200 Subject: [PATCH] Use a pill with explicit links for iCal and Google Calendar. --- README.md | 4 ++-- assets/css/_custom.css | 27 +++++++++++++++++++------- assets/js/calendar.js | 15 -------------- i18n/de.yaml | 4 ++-- i18n/en.yaml | 4 ++-- layouts/_partials/calendar-script.html | 4 ---- layouts/_shortcodes/calendar.html | 14 +++++++------ layouts/baseof.html | 1 - layouts/home-baseof.html | 1 - 9 files changed, 34 insertions(+), 40 deletions(-) delete mode 100644 assets/js/calendar.js delete mode 100644 layouts/_partials/calendar-script.html diff --git a/README.md b/README.md index 90819d0..ddae0b7 100644 --- a/README.md +++ b/README.md @@ -49,7 +49,7 @@ Without a data file, or without any tours in it, the shortcode renders nothing a ## Shortcode: Calendar entry -`{{< calendar >}}` adds a calendar icon after a tour date that downloads a calendar file (`.ics`) for that date. Hackertours-Admin puts it into the list of dates on each tour page: +`{{< calendar >}}` adds a small pill after a tour date with a calendar icon and two links: "iCal download", a calendar file (`.ics`) for that date, and "Google calendar", which adds the date in Google Calendar. Hackertours-Admin puts it into the list of dates on each tour page: ```markdown * Tag 1 (27.12.) **17:30 Uhr** {{< calendar date="2026-12-27" time="17:30" duration="210" >}} @@ -62,7 +62,7 @@ Without a data file, or without any tours in it, the shortcode renders nothing a | `duration` | no | Length in minutes. Without it, `duration` of the tour in `tours` in the schedule file is used (see "Map data in the schedule file"); without either, the calendar entry has no end time and the build logs a warning with the ID `warning-calendar-duration`. | | `title` | no | Title of the calendar entry. Without it, the `title` of this date in the schedule file is used, then the page title. | -The `.ics` file is in the iCalendar format (RFC 5545), which Apple Calendar, Outlook, Thunderbird and most other calendar apps open directly. The Google Calendar app on Android can't open downloaded `.ics` files, so on Android the link adds the date in Google Calendar instead ([assets/js/calendar.js](assets/js/calendar.js) switches it when the browser reports Android). That also applies to Android users with another calendar app, such as Samsung Calendar, which could have opened the file; without JavaScript, everyone gets the `.ics` file. +The `.ics` file is in the iCalendar format (RFC 5545), which Apple Calendar, Outlook, Thunderbird and most other calendar apps open directly. The Google calendar link is there because the Google Calendar app on Android can't open downloaded `.ics` files. The icon is `regular/calendar-plus` from [Font Awesome Free](https://fontawesome.com/search?ic=free), kept in [assets/vendor/fontawesome/](assets/vendor/fontawesome/). Other templates can use any of its icons with `{{ partial "fa-icon.html" "solid/ship" }}`: it inlines the SVG, decorative and in the text colour. The icons are CC BY 4.0; the attribution is the comment inside each SVG, which the partial keeps. diff --git a/assets/css/_custom.css b/assets/css/_custom.css index c830f9d..6b9a32d 100644 --- a/assets/css/_custom.css +++ b/assets/css/_custom.css @@ -107,17 +107,30 @@ span.content-image { color: var(--color-text-meta); } -/* Calendar link after a tour date, see layouts/_shortcodes/calendar.html. - At least 24 by 24 pixels, so it is easy to hit (WCAG 2.5.8). */ +/* Calendar links after a tour date, see layouts/_shortcodes/calendar.html. + The links are at least 24 pixels high, so they are easy to hit (WCAG 2.5.8). */ .tour-calendar { display: inline-flex; align-items: center; - justify-content: center; - min-width: 24px; - min-height: 24px; - margin-inline-start: 0.25em; + gap: 0.4em; + margin-inline-start: 0.4em; + padding: 0 0.6em; + border: 1px solid color-mix(in oklch, var(--color-text) 25%, transparent); + border-radius: 999px; + font-family: var(--ff-alt); + font-size: var(--fs-xs); vertical-align: middle; - text-decoration: none; + white-space: nowrap; + + a { + display: inline-flex; + align-items: center; + min-height: 24px; + } +} + +.tour-calendar__separator { + color: var(--color-text-meta); } .fa-icon { diff --git a/assets/js/calendar.js b/assets/js/calendar.js deleted file mode 100644 index ad27ecc..0000000 --- a/assets/js/calendar.js +++ /dev/null @@ -1,15 +0,0 @@ -// Calendar shortcode: on Android, the calendar links add the date in Google Calendar instead of -// downloading the .ics file, because the Google Calendar app there can't open .ics files. -{ - const isAndroid = - navigator.userAgentData?.platform === 'Android' || /\bAndroid\b/i.test(navigator.userAgent); - - if (isAndroid) { - for (const link of document.querySelectorAll('a.tour-calendar[data-google-href]')) { - link.href = link.dataset.googleHref; - link.removeAttribute('download'); - link.title = link.dataset.googleTitle; - link.querySelector('.visually-hidden').textContent = link.dataset.googleLabel; - } - } -} diff --git a/i18n/de.yaml b/i18n/de.yaml index 25f2eee..123d4d7 100644 --- a/i18n/de.yaml +++ b/i18n/de.yaml @@ -6,5 +6,5 @@ skip_to_content: "Zum Inhalt springen" logo_alt: "Hamburg Hackertours – Startseite" map_39c3_title: "Karte der 39C3-Touren mit Wegen vom CCH (uMap)" calendar_meeting_point: "Hackertours-Desk" -calendar_ics: "iCal-Kalenderdatei" -calendar_google: "In Google Kalender eintragen" +calendar_ics: "iCal Download" +calendar_google: "Google Calendar" diff --git a/i18n/en.yaml b/i18n/en.yaml index f658519..d001184 100644 --- a/i18n/en.yaml +++ b/i18n/en.yaml @@ -6,5 +6,5 @@ skip_to_content: "Skip to content" logo_alt: "Hamburg Hackertours – home page" map_39c3_title: "Map of the 39C3 tours with routes from the CCH (uMap)" calendar_meeting_point: "Hackertours Desk" -calendar_ics: "iCal calendar file" -calendar_google: "Add to Google Calendar" +calendar_ics: "iCal download" +calendar_google: "Google calendar" diff --git a/layouts/_partials/calendar-script.html b/layouts/_partials/calendar-script.html deleted file mode 100644 index c185deb..0000000 --- a/layouts/_partials/calendar-script.html +++ /dev/null @@ -1,4 +0,0 @@ -{{- /* Script for the calendar shortcode, included by the base templates on pages that use it. */ -}} -{{- with resources.Get "js/calendar.js" | minify | fingerprint -}} - -{{- end -}} diff --git a/layouts/_shortcodes/calendar.html b/layouts/_shortcodes/calendar.html index e0afab4..45ab606 100644 --- a/layouts/_shortcodes/calendar.html +++ b/layouts/_shortcodes/calendar.html @@ -1,7 +1,7 @@ {{- /* -Calendar link for one date of a tour, shown as a calendar icon: an .ics file (iCalendar), which -Apple Calendar, Outlook, Thunderbird and most other calendar apps can open. On Android, -assets/js/calendar.js turns it into a link that adds the date in Google Calendar. +Calendar links for one date of a tour, in a small pill with a calendar icon: an .ics file +(iCalendar), which Apple Calendar, Outlook, Thunderbird and most other calendar apps can open, +and a link that adds the date in Google Calendar, whose Android app can't open .ics files. Meant for the list of dates on a tour page: * Tag 1 (27.12.) **17:30 Uhr** {{< calendar date="2026-12-27" time="17:30" duration="210" >}} @@ -71,9 +71,8 @@ title of this date in the schedule data, else the page title). {{- $file := printf "%s-%s-%s.ics" $slug $date (replace $time ":" "") -}} {{- $icsFile := resources.FromString (path.Join (strings.TrimPrefix "/" $page.RelPermalink) $file) $ics -}} -{{- /* The icon is the same for every date, so the link name for screen readers includes the date. */ -}} +{{- /* The link texts are the same for every date, so their names for screen readers include the date. */ -}} {{- $when := printf "%s %s" ($start | time.Format "Mon 2.1.") $time -}} -{{- /* Android's Google Calendar app can't open .ics files; there, calendar.js uses this link instead. */ -}} {{- $google := printf "https://calendar.google.com/calendar/render?%s" (querify "action" "TEMPLATE" "text" $title @@ -82,5 +81,8 @@ title of this date in the schedule data, else the page title). "location" $location "ctz" "Europe/Berlin" ) -}} -{{ partial "fa-icon.html" "regular/calendar-plus" }}{{ i18n "calendar_ics" }} {{ $when }} +{{ partial "fa-icon.html" "regular/calendar-plus" -}} +{{ i18n "calendar_ics" }} {{ $when }} +{{- /* */ -}} +{{- /* */ -}}{{ i18n "calendar_google" }} {{ $when }} {{- /* chomp */ -}} diff --git a/layouts/baseof.html b/layouts/baseof.html index ce09816..6e6bf60 100644 --- a/layouts/baseof.html +++ b/layouts/baseof.html @@ -15,7 +15,6 @@ {{ block "head" . }}{{ end }} {{ if .HasShortcode "schedule" }}{{ partial "schedule-script.html" . }}{{ end }} {{ if .HasShortcode "tour-map" }}{{ partial "tour-map-script.html" . }}{{ end }} -{{ if .HasShortcode "calendar" }}{{ partial "calendar-script.html" . }}{{ end }} diff --git a/layouts/home-baseof.html b/layouts/home-baseof.html index a760955..156a130 100644 --- a/layouts/home-baseof.html +++ b/layouts/home-baseof.html @@ -15,7 +15,6 @@ {{ block "head" . }}{{ end }} {{ if .HasShortcode "schedule" }}{{ partial "schedule-script.html" . }}{{ end }} {{ if .HasShortcode "tour-map" }}{{ partial "tour-map-script.html" . }}{{ end }} -{{ if .HasShortcode "calendar" }}{{ partial "calendar-script.html" . }}{{ end }}