diff --git a/content/resources/roadmap.md b/content/resources/roadmap.md
index 7f6f081e0..d18697d4e 100644
--- a/content/resources/roadmap.md
+++ b/content/resources/roadmap.md
@@ -10,6 +10,9 @@ sidebar: true
# Road Map
{{< roadmap >}}
+{{< button class="is-primary1 is-rounded" link="https://qgis.org/schedule.ics" text="Subscribe to the roadmap iCalendar" >}}
+
+
Releases and development of QGIS follow a timebased schedule (roadmap).
- Even version numbers (2.18, 3.2 etc) are release versions.
diff --git a/themes/hugo-bulma-blocks-theme/assets/sass/bulma/components/level.sass b/themes/hugo-bulma-blocks-theme/assets/sass/bulma/components/level.sass
index 6793ae060..d8b3073b7 100644
--- a/themes/hugo-bulma-blocks-theme/assets/sass/bulma/components/level.sass
+++ b/themes/hugo-bulma-blocks-theme/assets/sass/bulma/components/level.sass
@@ -4,7 +4,7 @@ $level-item-spacing: ($block-spacing * 0.5) !default
.level
@extend %block
- align-items: center
+ // align-items: center
justify-content: space-between
code
border-radius: $radius
diff --git a/themes/hugo-bulma-blocks-theme/layouts/shortcodes/roadmap.html b/themes/hugo-bulma-blocks-theme/layouts/shortcodes/roadmap.html
index 86e18a9e1..8e406fe72 100644
--- a/themes/hugo-bulma-blocks-theme/layouts/shortcodes/roadmap.html
+++ b/themes/hugo-bulma-blocks-theme/layouts/shortcodes/roadmap.html
@@ -58,6 +58,12 @@
Long Term Release (LTR)
Sec.
+
+
@@ -146,6 +152,11 @@
Latest Release
Sec.
+
@@ -233,6 +244,11 @@
Development Version
Sec.
+
@@ -277,6 +293,11 @@
Development Version
Sec.
+
@@ -354,6 +375,11 @@
Development Version
let nextFreezeDateStr = {{ .nextfreezedate }};
let nextReleaseDateStr = {{ .nextreleasedate }};
let nextPointReleaseDateStr = {{ .nextpointreleasedate }};
+ let nextLtrVersion = {{ .next_ltr_version }};
+ let nextLrVersion = {{ .next_lr_version }};
+ let devVersion = {{ .devversion }};
+ let nextVersion = {{ .nextversion }};
+
{{ end }}
// We need to correct the date string format for Safari otherwise it will return NaN
const nextFreezeDate = new Date(nextFreezeDateStr.replace(" ", "T").replace(" UTC", "Z"))
@@ -364,4 +390,45 @@
Development Version
initializeClock('latest-point-release', nextPointReleaseDate);
initializeClock('freeze', nextFreezeDate);
initializeClock('package', nextReleaseDate);
+
+ function createiCalendar(event) {
+ // Format the date/time in the iCalendar format (UTC)
+ const formatDate = (date) =>
+ date.toISOString().replace(/-|:|\.\d+/g, "");
+ // Create the iCalendar file content
+ const icsContent = `
+BEGIN:VCALENDAR
+VERSION:2.0
+BEGIN:VEVENT
+SUMMARY:${event.title}
+DTSTART:${formatDate(event.start)}
+DTEND:${formatDate(event.end)}
+END:VEVENT
+END:VCALENDAR
+ `.trim();
+
+ // Create a blob and a download link
+ const blob = new Blob([icsContent], { type: "text/calendar" });
+ const link = document.createElement("a");
+ link.href = URL.createObjectURL(blob);
+ link.download = "event.ics";
+ document.body.appendChild(link);
+ link.click();
+ document.body.removeChild(link);
+ }
+ function addEventToCalendar(buttonId, eventTitle, eventDate) {
+ document.getElementById(buttonId).addEventListener("click", () => {
+ const event = {
+ title: eventTitle,
+ start: eventDate,
+ end: eventDate,
+ };
+ createiCalendar(event);
+ });
+ }
+
+ addEventToCalendar("addPrToCalendar", `QGIS Point Release ${nextLtrVersion}`, nextPointReleaseDate);
+ addEventToCalendar("addLatestPrToCalendar", `QGIS Point Release ${nextLrVersion}`, nextPointReleaseDate);
+ addEventToCalendar("addFreezeToCalendar", `QGIS Feature Freeze ${devVersion}`, nextFreezeDate);
+ addEventToCalendar("addPackageToCalendar", `QGIS Long-term Release ${nextVersion}`, nextReleaseDate);