Skip to content

Commit

Permalink
documentation for calendars; fixes #69
Browse files Browse the repository at this point in the history
  • Loading branch information
reinhrst committed May 22, 2023
1 parent 5d35a51 commit 04ca09b
Show file tree
Hide file tree
Showing 3 changed files with 178 additions and 2 deletions.
3 changes: 1 addition & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,4 @@ In order to run the website locally:
- `hugo serve`
- Go to http:/localhost:1313/

Also read the [I18n notes](i18n.md).
Also (todo) read the calendar notes.
Also read the [I18n notes](i18n.md) and the [calendar/event notes](calendar.md).
114 changes: 114 additions & 0 deletions calendar.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
This document is meant to document how the calendar-functionality works in the events-section of this website.

## Event pages
An event-page can have an `eventInfo` key, which describes the dates that the event happens (note: if there are multiple translations of the same page, only one of them can have this `eventInfo` key, and those events are used for all translations).
This key has (for now) three (optional) subkeys: `organizer`, `timezone` and `dates`. In time it could make sense to add additional keys here, like `location`, or `type={inperson/remote/both}`, `rsvp_requested`, etc.

`eventInfo.organizer` has two optional subkeys, `name` and `email`. Right now these are only used in building the `ics` file, but it could certainly make sense to show them on the webpage as well.

`timezone` should contain an IANA timezone (e.g. `Europe/Warsaw`) if the events in this page are not in the default timezone of the site.

`dates` has 4 optional subkeys. `periodics` allows one to make a recurring rule, `extra` allows one to make one-off events, `cancelled` allows cancelling a recurring event, and `changes` allows changes to an event (either date, or time, or add a message).

`periodics` has an array of dicts with keys: `start` (date), `end` (date) `rule` (see below), `starttime` (time) `endtime` (time) and `comment` (optional, string).

All recurring rules need to have a start and end date; without one, Hugo would need to generate an infinite amount of events. I would advice to keep the `end`s about 2 years in the future, in cases no `end` date is known.

The `rule` can be one of two types:

- `first Tuesday of the month` (`Tuesday` can be any weekday name, `first` can be any of {`first`, `second`, `third`, `fourth`, `fifth`, `last`, `penultimate`} -- if there is ever a need, adding a `pen-penultimate` is easy (but not supported atm). There is an idea to in the future allow `month` to also be `month / x` meaning every `x` months (counting from `start` date).
- `every X days`

Adding additional rules is possible, but not always super easy.

`cancelled` has a date as a key, and a message (reason why cancelled) as value. At the moment, only events generated by `periodics` can be cancelled (although it might make sense to allow one-off events to be cancelled as well). Cancelled events will still be shown in the interface, and in the `ics` files, but marked as cancelled (for now there is no way to completely delete recurring event).

`extra` takes as key date+starttime+endtime (e.g. `2023-05-04 12:00-14:00`), and as value a comment for that event (e.g. the reason why there is an extra event).

`changes` takes as key a change-rule (which is one of the following) and as value a comment (e.g. reason for the change):
- `2023-05-04`: no changes in date/time, just in properties of event (=comment)
- `2023-05-04->2023-05-05`: change date, same time, changed comment
- `2023-05-04->19:00-20:00`: change time, same date, changed comment
- `2023-05-04->2023-05-05 19:00-20:00`: change date and time, changed comment

It makes sense that in the future, we'll change the values of the items in `extra` and `changes` to be dicts themselves, with keys as `comment`, `location`, `organizer`, etc, to allow more flexibility in the events.

There is also [a proposal](https://github.com/hs3city/hs3.pl/issues/72) to allow bigger changes to individual events.

Example:

```yaml
eventInfo:
organizer:
name: Hackerspace Trójmiasto
dates:
periodics:
- start: 2022-10-01
end: 2024-01-02
rule: last Friday of the month
starttime: 18:00
endtime: 02:00
- start: 2022-12-01
end: 2023-02-10
rule: every 14 days
starttime: 12:00
endtime: 14:00
comment: Winter lunch meeting
cancelled:
2023-02-24: "Too cold"
2023-07-28: vacation
extra:
2022-12-07 18:00-19:00: extra meeting too
2023-08-27 18:00-19:00: extra meeting
2022-10-29 18:00-05:00: DLS change party!
changes:
2022-10-28->2022-10-27: "moved because of planning issues"
2022-12-30: bring 🍾
2023-04-28->19:00-01:00: "starting a bit later"
2023-10-27->2023-10-20 19:00-21:00: moved a week earlier
```
There are some limitations to how events work at the moment:
- Events cannot last longer than 24 hours. If the endtime < starttime, then an event lasts past midnight, but at the moment there is no way to have an event last 2 days.
- If the periodics work so that there are multiple events on the same day, the latter event will overwrite the former one (even if the times are different).
- You cannot make an extra event on the same day there is already an event (or move an event to the day with an event)
- During DST change, no way to specify if you mean time before or after change (basically what the `is_dst` in `pytz` is for) 🤓

The events are put on the page in [Microformat's event format](http://microformats.org/wiki/h-event).

If there are events, a section is shown at the top of the event page, with three tabs "Upcoming", "Past" and "Calendar" (showing upcoming and past events, and a calendar view). Hugo fills the Upcoming and Past sections with events, _but this is done t page-creation time_ (rather than page-view time). In order to make sure the events appear in the right spot, some JS is run to move them. This JS also creates a calendar-functionality view (JS uses the microformat to read the events).

## Event pages list

There are pages that show lists of events (e.g. `https://hs3.pl/wydarzenia/`, but also taxonomy pages like `https://hs3.pl/tags/druk-3d/`). On these pages we can also generate the Upcoming/Past/Calendar box.

At the moment, only the section head (`https://hs3.pl/wydarzenia/`, and `https://hs3.pl/en/events/`) has this functionality; it's planned to add this functionality later to the taxonomy pages as well.

On these pages, we show the events in long-form (including picture, and title).

## ICS files

Every page and section under `wydarzenia` section (basically every page that can have the Upcoming/Past/Calendar box) also generates an `.ics` icalendar-file. These files can either be downloaded and then imported into one's calendar-application, or the URL can be given in the `subscribe to calendar` box (at least in Apple Calendar and iPhone calendar, supposedly also in Google/Outlook). This latter method allows the calendar to auto-sync and stay up to date (sync frequency can be set by user).

## Timezones

Timezones are the programmer's biggest friend :(.

When events are declared, they are declared in:

- The timezone explicitly given in the `eventInfo.timezone` key; or if not present
- The timezone set in `config.toml`; or if not set
- The timezone of the server

Hugo only has functions to change timezone to Local (which is timezone of the server, not (as you may think) timezone set in `config.toml`, or to UTC. This means we _must_ make sure that the server that Hugo runs on, uses our default timezone (`Europe/Warsaw`). Luckily this can be set in `netlify.toml`; it _does_ mean however that if someone ever runs Hugo on their laptop, while not having their laptop at CET, they may see the wrong times.

The `.ics` files have their times in `UTC` (yeah!). It does mean that they show up in calendars using the local device time (i.e. if Picnics start at 18:00 local time, and you're in London, you'll see `17:00` in your calendar).

However for the calendar on the website, it's very confusing if the calendar follows the same rules; Hugo hard-prints on the website: `Picnic 18:00 - 23:00`, it would be very confusing, if then it would show as `17:00 - 22:00` in the calendar.

A lot of special hacky code is needed to convince javascript to do the right thing, but in the end, it works :).

## Blog post

I wrote [a blog post](https://blog.claude.nl/how-to/hugo-recurring-events-with-icalendar-support/) on the previous iteration of the event-code. Most things in this post are still accurate.
63 changes: 63 additions & 0 deletions how-to-change-meeting-info.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
This document describes for meeting-owners how they can change their meetings.
Let's look at this (fictional) calendar for the picnic:

Please read [the technical documentation](calendar.md) in order to find all details (including how to make a new recurring meeting), this document is just the quick and dirty reference.

Note that the event info can be _either_ on the Polish language page, _or_ on the English page, not both. This also means that at the moment, there is no i18n support for the comments.

## Add an extra meeting

Under `eventInfo.dates` in the frontmatter, add (if it doesn't exist) a key for `extra`. Under this key, create a new key `2022-12-07 08:00-19:00` (change to your dates and times), and value either an empty string, or some comment you want to add to this meeting. You can make a meeting last past midnight if endtime < starttime (e.g. `2022-12-07 18:00-06:00`).

E.g.

```yaml
eventInfo:
dates:
extra:
2022-12-07 18:00-19:00: This is an extra meeting
```
## Cancel a meeting
If the meeting you want to cancel is an extra (non-recurring) meeting, just remove the line for the meeting.
If it's a recurring meeting, under `eventInfo.dates` in the frontmatter, add (if it doesn't exist) a key for `cancelled`. Add underneath a key with the date (e.g. `2023-06-23`) and as value the reason for cancellation (or any other message, or an empty string).

E.g.

```yaml
eventInfo:
dates:
periodics:
[...]
cancelled:
2022-12-30: "No meeting day before silvester"
```

## Change a meeting

If the meeting you want to cancel is an extra (non-recurring) meeting, just change the line for the meeting.

If it's a recurring meeting, under `eventInfo.dates` in the frontmatter, add (if it doesn't exist) a key for `changes`. Add underneath a key in one of the following forms, and as value the reason for the change (or any other message, or an empty string):

- `2022-05-04`: date by itself allows adding a message to an existing event
- `2022-05-04->2022-05-05`: `date->date` changes the date (but not the time)
- `2022-05-04->18:00-19:00`: `date->start-end` changes the time (but not the date)
- `2022-05-04->2022-05-05 18:00-19:00`: `date->date start-end` changes both the date and the time.

E.g.

```yaml
eventInfo:
organizer:
name: Hackerspace Trójmiasto
dates:
periodics:
[...]
changes:
2022-10-28->2022-10-27: "moved because of planning issues"
2022-12-30: bring 🍾
2023-04-28->19:00-01:00: "starting a bit later"
2023-10-27->2023-10-20 19:00-21:00: moved a week earlier, but later start time
```

0 comments on commit 04ca09b

Please sign in to comment.