1
0
Fork 0
mirror of https://github.com/netz39/www.netz39.de.git synced 2025-05-05 21:11:57 +02:00

Merge pull request from netz39/155-add-rrule-to-ical_event

feat(events): add recurring events
This commit is contained in:
0Ry5 2025-04-26 16:18:21 +02:00 committed by GitHub
commit 93a6f2a440
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 141 additions and 6 deletions

View file

@ -50,6 +50,7 @@ Unsere Webseite setzt aus folgenden Gründen auf Jekyll, einen statischen Websit
end: 2023-10-20 21:00:00 # optional, Zeitpunkt, an dem das Event endet
organizer: "Netz39 Team <kontakt@netz39.de>" # optional, Kontaktdaten im ical Event
location: "Netz39 e.V." # optional, Ort des Events
rrule: "FREQ=MONTHLY;INTERVAL=1;BYDAY=1FR,1TH" # follows https://icalendar.org/iCalendar-RFC-5545/3-3-10-recurrence-rule.html
---
```
- Unterhalb des Front Matters die Beschreibung des Events in Markdown aufschreiben

View file

@ -1,5 +1,6 @@
{% assign author = site.data.authors[include.author] %}
{% assign date = include.date | default: "today" | date: "%-d. %B %Y" %}
{% assign rrule = include.rrule %}
<div class="post-info">
{%- if author.url -%}<a href="{{ author.url | relative_url }}" target="_blank" rel="noopener">{%- endif -%}
@ -9,7 +10,83 @@
<p class="meta">
{% if author.name %}{{ author.name }} - {% endif %}
{% assign x = date | date: "%m" | minus: 1 %}
{% if rrule %}
{% assign freq = rrule | split: ";" %}
{% assign frequency = freq[0] | split: "=" | last %}
{% assign interval = freq[1] | split: "=" | last %}
{% assign byday = freq[2] | split: "=" | last %}
{% capture transformed_text %}
{% if frequency == "MONTHLY" %}
{% assign days = byday | split: "," %}
{% capture days_text %}
{% for day in days %}
{% assign day_of_week = day | slice: 1, 2 %}
{% assign week = day | slice: 0, 1 %}
{% case day_of_week %}
{% when "MO" %}
{% assign day_name = "Monday" %}
{% when "TU" %}
{% assign day_name = "Tuesday" %}
{% when "WE" %}
{% assign day_name = "Wednesday" %}
{% when "TH" %}
{% assign day_name = "Thursday" %}
{% when "FR" %}
{% assign day_name = "Friday" %}
{% when "SA" %}
{% assign day_name = "Saturday" %}
{% when "SU" %}
{% assign day_name = "Sunday" %}
{% endcase %}
{% assign week_suffix = week | append: "th" %}
{% if week == "1" %}
{% assign week_suffix = week | append: "st" %}
{% elsif week == "2" %}
{% assign week_suffix = week | append: "nd" %}
{% elsif week == "3" %}
{% assign week_suffix = week | append: "rd" %}
{% endif %}
{% if forloop.first %}
{{ week_suffix }} {{ day_name }}
{% else %}
and {{ week_suffix }} {{ day_name }}
{% endif %}
{% endfor %}
{% endcapture %}
{% capture month_text %}
{% if interval == "1" %}
Every month
{% elsif interval == "2" %}
Every other month
{% else %}
Every {{interval}} months
{% endif %}
{% endcapture %}
{{ month_text }} on the {{days_text}}
{% elsif frequency == "WEEKLY" %}
{% capture week_text %}
{% if interval == "1" %}
Every week
{% elsif interval == "2" %}
Every other week
{% else %}
Every {{interval}} weeks
{% endif %}
{% endcapture %}
{% capture day %}
{{ date | date: "%A" }}
{% endcapture %}
{{ week_text }} on {{ day }}
{% endif %}
{% endcapture %}
{{transformed_text}}
{% else %}
{{ date | date: "%-d. " }}{{ site.data.language.str_months[x]}} {{ date | date: "%Y" }}
{% endif %}
</p>
{%- if author.url -%}</a>{%- endif -%}
</div>

View file

@ -9,7 +9,7 @@ layout: default
{% else %}
<h1 id="{{ page.title | cgi_escape }}" class="title">{{ page.title }}</h1>
{% assign start_date = page.event.start | default: page.event_date %}
{% include blog/post_info.liquid author=page.author date=start_date %}
{% include blog/post_info.liquid author=page.author date=start_date rrule=page.event.rrule %}
{% endif %}
</div>
</header>

View file

@ -39,6 +39,7 @@ module Jekyll
end_date = event.data.dig('event', 'end') || event.data['event_date'] || start_date + default_duration
organizer = event.data.dig('event', 'organizer') || default_organizer
location = event.data.dig('event', 'location') || default_location
rrule = event.data.dig('event', 'rrule')
# Skip events older than 365 days
next if start_date.to_date < (Date.today - 365)
@ -63,6 +64,9 @@ module Jekyll
ical_event.dtstart = Icalendar::Values::Date.new(start_date)
ical_event.dtend = Icalendar::Values::Date.new(end_date)
end
if rrule
ical_event.rrule = rrule
end
ical_event.summary = title
ical_event.description = description
ical_event.organizer = organizer

View file

@ -0,0 +1,6 @@
/*!
FullCalendar RRule Plugin v6.1.17
Docs & License: https://fullcalendar.io/docs/rrule-plugin
(c) 2024 Adam Shaw
*/
FullCalendar.RRule=function(e,r,t,i){"use strict";function n(e){if(e&&e.__esModule)return e;var r=Object.create(null);return e&&Object.keys(e).forEach((function(t){if("default"!==t){var i=Object.getOwnPropertyDescriptor(e,t);Object.defineProperty(r,t,i.get?i:{enumerable:!0,get:function(){return e[t]}})}})),r.default=e,r}var l=n(t);const u={parse(e,r){if(null!=e.rrule){let t=function(e,r){let t,n=!1,u=!1;if("string"==typeof e.rrule){let r=function(e){let r=l.rrulestr(e,{forceset:!0}),t=function(e){let r=!1,t=!1;function n(e,n,l){let u=i.parseMarker(l);r=r||!u.isTimeUnspecified,t=t||null!==u.timeZoneOffset}return e.replace(/\b(DTSTART:)([^\n]*)/,n),e.replace(/\b(EXDATE:)([^\n]*)/,n),e.replace(/\b(UNTIL=)([^;\n]*)/,n),{isTimeSpecified:r,isTimeZoneSpecified:t}}(e);return Object.assign({rruleSet:r},t)}(e.rrule);t=r.rruleSet,n=r.isTimeSpecified,u=r.isTimeZoneSpecified}if("object"==typeof e.rrule&&e.rrule){let i=a(e.rrule,r);t=new l.RRuleSet,t.rrule(i.rrule),n=i.isTimeSpecified,u=i.isTimeZoneSpecified}let f=[].concat(e.exdate||[]),s=[].concat(e.exrule||[]);for(let e of f){let r=i.parseMarker(e);n=n||!r.isTimeUnspecified,u=u||null!==r.timeZoneOffset,t.exdate(new Date(r.marker.valueOf()-60*(r.timeZoneOffset||0)*1e3))}for(let e of s){let i=a(e,r);n=n||i.isTimeSpecified,u=u||i.isTimeZoneSpecified,t.exrule(i.rrule)}return{rruleSet:t,isTimeSpecified:n,isTimeZoneSpecified:u}}(e,r);if(t)return{typeData:{rruleSet:t.rruleSet,dateEnv:t.isTimeZoneSpecified?void 0:r},allDayGuess:!t.isTimeSpecified,duration:e.duration}}return null},expand:(e,r,t)=>e.rruleSet.between(i.addDays(r.start,-1),i.addDays(r.end,1)).map(r=>t.createMarker(e.dateEnv?e.dateEnv.toDate(r):r))};function a(e,r){let t=!1,n=!1;function u(e){if("string"==typeof e){let r=i.parseMarker(e);return r?(t=t||!r.isTimeUnspecified,n=n||null!==r.timeZoneOffset,new Date(r.marker.valueOf()-60*(r.timeZoneOffset||0)*1e3)):null}return e}let a=Object.assign(Object.assign({},e),{dtstart:u(e.dtstart),until:u(e.until),freq:s(e.freq),wkst:null==e.wkst?(r.weekDow-1+7)%7:s(e.wkst),byweekday:f(e.byweekday)});return{rrule:new l.RRule(a),isTimeSpecified:t,isTimeZoneSpecified:n}}function f(e){return Array.isArray(e)?e.map(s):s(e)}function s(e){return"string"==typeof e?l.RRule[e.toUpperCase()]:e}const c={rrule:i.identity,exrule:i.identity,exdate:i.identity,duration:i.createDuration};var o=r.createPlugin({name:"@fullcalendar/rrule",recurringTypes:[u],eventRefiners:c});return r.globalPlugins.push(o),e.default=o,Object.defineProperty(e,"__esModule",{value:!0}),e}({},FullCalendar,rrule,FullCalendar.Internal);

File diff suppressed because one or more lines are too long

40
assets/js/vendor/rrule.min.js vendored Normal file

File diff suppressed because one or more lines are too long

View file

@ -9,11 +9,14 @@ permalink: /calendar-data/
{% assign start = event.event.start | default: event.event_date %}
{% assign end = event.event.end | default: start %}
{
"title":"{{event.title}}",
"title": "{{event.title}}",
"start": "{{start | date: "%Y-%m-%dT%H:%M:%S"}}",
"end": "{{end | date: "%Y-%m-%dT%H:%M:%S"}}",
"allDay": {% if start == end %}true{% else %}false{% endif %},
"url":"{{event.url}}"
"url": "{{event.url}}",
{% if event.event.rrule %}
"rrule": "{{event.event.rrule}}"
{% endif %}
}
{%unless forloop.last %},{%endunless%}
{% endfor %}

View file

@ -13,8 +13,10 @@ position: 1
<html lang='de'>
<head>
<meta charset='utf-8' />
<script src='/assets/js/vendor/rrule.min.js'></script>
<script src='/assets/js/vendor/fullcalendar/index.global.min.js'></script>
<script src='/assets/js/vendor/fullcalendar/de.global.min.js'></script>
<script src='/assets/js/vendor/fullcalendar/fullcalendar-rrule.global.min.js'></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
@ -36,6 +38,7 @@ position: 1
});
</script>
</head>
<body>
<div id='calendar' style="width:95%; margin: auto;"></div>
@ -69,5 +72,6 @@ position: 1
alert('URL wurde in die Zwischenablage kopiert!');
});
</script>
</body>
</html>