Pelican Events: iCalendar Plugin for Pelican
============================================
[](https://github.com/ikluft/pelican-events/actions/workflows/main.yml)
[](https://pypi.org/project/pelican-events/)

Pelican plugin to embed event data in posts and generate iCalendar data
This project was created for the [Portland Linux Kernel Meetup (PDX-LKMU)](https://ikluft.github.io/pdx-lkmu/) site. This is a refresh of the 2015 events plugin and includes improvements from Makerspace Esslingen.
This plugin/module was made to generate iCalendar data for the Linux Kernel Meetup in Portland, Oregon and also to be general-use for other groups who find it helpful. The PDX-LKMU site uses the static site generator Pelican.
We intended to use the previously-existing "events" plugin to automatically generate iCalendar entries from events with calendar metadata. But the events plugin was unmaintained. It also didn't generate enough iCalendar properties for our needs, where we need the Portland-area Calagator system to process our iCalendar output. Also, the original events plugin was so old it didn't implement the current "namespace plugin" standard for Pelican plugins, namely being a standalone Python module. That's what this project was intended to solve - rewrite it as a Python module and bring it up to current plugin standards.
Let's give credit to the volunteers who created the foundation this is built upon. This plugin pulls together code from the legacy [events plugin by Federico Ceratto](https://github.com/getpelican/pelican-plugins/tree/master/events) and the forked [pelican-events-plugin by Makerspace Esslingen](https://github.com/Makerspace-Esslingen/pelican-events-plugin) into a plugin compliant with the current [namespace plugin structure](https://docs.getpelican.com/en/latest/plugins.html#namespace-plugin-structure). We also added support for more iCalendar properties, as many as make sense in a public setting. A security review excluded some properties which are intended for private email use, and could cause misconfiguration or be used for mischief. Those details are documented below.
Installation
------------
This plugin is available as ['pelican-events' on PyPI](https://pypi.org/project/pelican-events/) and can be installed via:
python -m pip install pelican-events
### Dependencies
Whether installing from PyPI with pip, or building from source, you may install dependencies from OS packages if you prefer. But you will have to do that first.
The pelican-events plugin depends on the following Python packages:
* pelican
* icalendar
* recurrent
* html2text
* and others
Some dependencies are available for installation via OS-native packages.
* on RPM-based systems (Fedora, RHEL, Rocky, Alma, etc):
dnf install python3-pelican python3-icalendar python3-html2text
* on DEB-based systems (Debian, Ubuntu, etc):
apt install pelican python3-icalendar python3-html2text
### Building from source
Pelican uses PDM (Python Dependency Manager) for builds and Ruff as its linter. So the Pelican-Events plugin does too. PDM determines the project's dependencies with the command
pdm lock
Dependencies which aren't available as OS-native packages may be installed via PDM:
pdm install
### Settings
As long as you have not explicitly added a `PLUGINS` setting to your Pelican settings file, then the newly-installed plugin should be detected as a Python module with a "pelican.plugins" prefix, and then automatically enabled. Otherwise, you must add `pelican-events` to your existing `PLUGINS` list. For more information, please see the [How to Use Plugins](https://docs.getpelican.com/en/latest/plugins.html#how-to-use-plugins) documentation.
Define settings in pelicanconf.py with the PLUGIN_EVENTS variable:
PLUGIN_EVENTS = {
'ics_fname': 'calendar.ics',
'metadata_field_for_summary': 'title',
},
'TIMEZONE': 'US/Pacific', # use your local time zone
Settings available in the PLUGIN_EVENTS dictionary variable:
* ics_fname: where the iCal file is written - disables plugin if not set
* metadata_field_for_summary: which field to use for the event summary, default: summary
* recurring_events: recurring event rules in [recurrent module](https://github.com/kvh/recurrent) format. If not set, then recurring events will not be generated. This feature was added by Makerspace Esslingen. *(This feature is now minimally tested with some unit tests. But we don't use it on the PDX-LKMU site.)*
Settings used from Pelican's top-level configuration:
* TIMEZONE: time zone to use for events in icalendar output, default: UTC. If set, this must be an official time zone name from the [IANA Time Zone Database](https://www.iana.org/time-zones).
Usage
-----
You can use the following metadata in your Pelican content, which are from the original 2015 events plugin:
* event-start: When the event will start in "YYYY-MM-DD hh:mm"
* event-end: When the event will stop in "YYYY-MM-DD hh:mm"
* event-duration: The duration of the event [note 1]
* event-location: Where the event takes place [[RFC5545, Section 3.8.1.7](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.7)]
Note 1: To specify the event duration, use a number followed by a time unit, for example "2h 30m"
* w: weeks
* d: days
* h: hours
* m: minutes
* s: seconds
Support for more iCalendar properties, prefixed with "event-" in the post metadata, were added in the update for the Portland Linux Kernel Meetup.
* event-categories: comma-separated list of arbitrary categories [[RFC5545, Section 3.8.1.2](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.2), [RFC7986, Section 5.6](https://www.rfc-editor.org/rfc/rfc7986#section-5.6)]
* event-comment: comment to the calendar user [[RFC5545, Section 3.8.1.4](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.4)]
* event-description: textual description of the activity [[RFC5545, Section 3.8.1.5](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.5), [RFC7986, Section 5.2](https://www.rfc-editor.org/rfc/rfc7986#section-5.2)]
* event-geo: latitude and longitude as floating point numbers separated by semicolon [[RFC5545, Section 3.8.1.6](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.6)]
* event-status: status of the event as "tentative", "confirmed", or "cancelled" [[RFC5545, Section 3.8.1.11](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.11)]
* event-summary: short one-line summary about the activity [[RFC5545, Section 3.8.1.12](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.12)]
* event-url: URL online location of a more dynamic rendition of the calendar information [[RFC5545, Section 3.8.4.6](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.6), [RFC7986, Section 5.5](https://www.rfc-editor.org/rfc/rfc7986#section-5.5)]
* event-uid: globally unique identifier [[RFC5545, Section 3.8.4.7](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.7), [RFC7986, Section 5.5](https://www.rfc-editor.org/rfc/rfc7986#section-5.3)]
* event-created: date and time that the calendar information was created [[RFC5545, Section 3.8.7.1](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.1)]
* event-name: name for presenting the calendar data to a user [[RFC7986, Section 5.1](https://www.rfc-editor.org/rfc/rfc7986#section-5.1)]
* event-image: image for the event via a URI or inline data [[RFC7986, Section 5.10](https://www.rfc-editor.org/rfc/rfc7986#section-5.10)]
* event-conference: information for accessing a conferencing system for attendees [[RFC7986, Section 5.11](https://www.rfc-editor.org/rfc/rfc7986#section-5.11)]
* event-styled-description: rich-text description of the activity [[RFC9073, Section 6.5](https://www.rfc-editor.org/rfc/rfc9073#name-styled-description)]
* event-concept: formal categories or classifications of the event [[RFC9253, Section 8.1](https://www.rfc-editor.org/rfc/rfc9253#section-8.1)]
* event-link: additional information related to the component [[RFC9253, Section 8.2](https://www.rfc-editor.org/rfc/rfc9253#section-8.2)]
* event-refid: free-form text that creates an identifier for associated components [[RFC9253, Section 8.3](https://www.rfc-editor.org/rfc/rfc9253#section-8.3)]
* event-x-\*: non-standard experimental properties [[RFC5545, Section 3.8.8.2](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.8.2)]
However, not all iCalendar properties make sense in the context of a public post. Those intended for private emails were excluded in a security review to prevent misconfiguration and mischief. A few were disallowed because they are redundant with metadata settings that generate those properties in the original events plugin. If you think you need a property which was excluded, [submit an issue to the project](https://github.com/ikluft/pelican-events/issues) stating which property is requested and explaining why it should be allowed in a public setting.
The disallowed iCalendar properties are: *acknowledged action attach attendee busytype calendar-address calscale class color completed contact dtend dtstamp dtstart due duration exdate exrule freebusy last-modified location-type method organizer participant-type percent-complete priority prodid proximity rdate recurrence-id refresh-interval related-to repeat request-status resources resource-type rrule sequence source structured-data transp trigger tzid tzid-alias-of tzname tzoffsetfrom tzoffsetto tzuntil tzurl version xml*
Contributing
------------
Contributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][].
To start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section.
[existing issues]: https://github.com/ikluft/pelican-events/issues
[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html
### Development Environment
Upon commit to the repository, the Github workflow will perform unit tests on current versions of Python.
So prior to checking in code, at least run the tests on your local environment to make sure you won't break the build.
pdm run invoke tests
It will also do a lint check which shows diffs that the linter wants for proper formatting.
This is also marked as a build failure if it doesn't work.
pdm run invoke lint --diff
If it says there are changes to make, you can run this in your workspace to apply those changes.
pdm run invoke lint --fix
To make a local git hook to perform these checks before each commit, make a symbolic link as follows:
ln -s "../../docs/pre-commit-git-hook.sh" .git/hooks/pre-commit
Example usage
-------------
The pelican-events plugin was made for and is used by the [Portland Linux Kernel Meetup](https://ikluft.github.io/pdx-lkmu/) in Portland, Oregon, USA.
License
-------
This project is licensed under the AGPL-3.0 license in order to be compatible with Pelican.
Raw data
{
"_id": null,
"home_page": null,
"name": "pelican-events",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.11",
"maintainer_email": null,
"keywords": "pelican, plugin, icalendar, events",
"author": null,
"author_email": "Ian Kluft <ko6yq.dev+python@gmail.com>",
"download_url": "https://files.pythonhosted.org/packages/2b/70/f1efef3a3924c7f68ffe1bb65efbdf43e335b072d5df0054d9e2671cda5d/pelican_events-0.1.2.tar.gz",
"platform": null,
"description": "Pelican Events: iCalendar Plugin for Pelican\n============================================\n\n[](https://github.com/ikluft/pelican-events/actions/workflows/main.yml)\n[](https://pypi.org/project/pelican-events/)\n\n\nPelican plugin to embed event data in posts and generate iCalendar data\n\nThis project was created for the [Portland Linux Kernel Meetup (PDX-LKMU)](https://ikluft.github.io/pdx-lkmu/) site. This is a refresh of the 2015 events plugin and includes improvements from Makerspace Esslingen.\n\nThis plugin/module was made to generate iCalendar data for the Linux Kernel Meetup in Portland, Oregon and also to be general-use for other groups who find it helpful. The PDX-LKMU site uses the static site generator Pelican.\n\nWe intended to use the previously-existing \"events\" plugin to automatically generate iCalendar entries from events with calendar metadata. But the events plugin was unmaintained. It also didn't generate enough iCalendar properties for our needs, where we need the Portland-area Calagator system to process our iCalendar output. Also, the original events plugin was so old it didn't implement the current \"namespace plugin\" standard for Pelican plugins, namely being a standalone Python module. That's what this project was intended to solve - rewrite it as a Python module and bring it up to current plugin standards.\n\nLet's give credit to the volunteers who created the foundation this is built upon. This plugin pulls together code from the legacy [events plugin by Federico Ceratto](https://github.com/getpelican/pelican-plugins/tree/master/events) and the forked [pelican-events-plugin by Makerspace Esslingen](https://github.com/Makerspace-Esslingen/pelican-events-plugin) into a plugin compliant with the current [namespace plugin structure](https://docs.getpelican.com/en/latest/plugins.html#namespace-plugin-structure). We also added support for more iCalendar properties, as many as make sense in a public setting. A security review excluded some properties which are intended for private email use, and could cause misconfiguration or be used for mischief. Those details are documented below.\n\nInstallation\n------------\n\nThis plugin is available as ['pelican-events' on PyPI](https://pypi.org/project/pelican-events/) and can be installed via:\n\n python -m pip install pelican-events\n\n### Dependencies\n\nWhether installing from PyPI with pip, or building from source, you may install dependencies from OS packages if you prefer. But you will have to do that first.\n\nThe pelican-events plugin depends on the following Python packages:\n\n * pelican\n * icalendar\n * recurrent\n * html2text\n * and others\n\nSome dependencies are available for installation via OS-native packages.\n\n * on RPM-based systems (Fedora, RHEL, Rocky, Alma, etc):\n\n dnf install python3-pelican python3-icalendar python3-html2text\n\n * on DEB-based systems (Debian, Ubuntu, etc):\n\n apt install pelican python3-icalendar python3-html2text\n\n### Building from source\n\nPelican uses PDM (Python Dependency Manager) for builds and Ruff as its linter. So the Pelican-Events plugin does too. PDM determines the project's dependencies with the command\n\n pdm lock\n\nDependencies which aren't available as OS-native packages may be installed via PDM:\n\n pdm install\n\n### Settings\n\nAs long as you have not explicitly added a `PLUGINS` setting to your Pelican settings file, then the newly-installed plugin should be detected as a Python module with a \"pelican.plugins\" prefix, and then automatically enabled. Otherwise, you must add `pelican-events` to your existing `PLUGINS` list. For more information, please see the [How to Use Plugins](https://docs.getpelican.com/en/latest/plugins.html#how-to-use-plugins) documentation.\n\nDefine settings in pelicanconf.py with the PLUGIN_EVENTS variable:\n\n PLUGIN_EVENTS = {\n 'ics_fname': 'calendar.ics',\n 'metadata_field_for_summary': 'title',\n },\n 'TIMEZONE': 'US/Pacific', # use your local time zone\n\nSettings available in the PLUGIN_EVENTS dictionary variable:\n\n * ics_fname: where the iCal file is written - disables plugin if not set\n * metadata_field_for_summary: which field to use for the event summary, default: summary\n * recurring_events: recurring event rules in [recurrent module](https://github.com/kvh/recurrent) format. If not set, then recurring events will not be generated. This feature was added by Makerspace Esslingen. *(This feature is now minimally tested with some unit tests. But we don't use it on the PDX-LKMU site.)*\n\nSettings used from Pelican's top-level configuration:\n * TIMEZONE: time zone to use for events in icalendar output, default: UTC. If set, this must be an official time zone name from the [IANA Time Zone Database](https://www.iana.org/time-zones).\n\nUsage\n-----\n\nYou can use the following metadata in your Pelican content, which are from the original 2015 events plugin:\n\n * event-start: When the event will start in \"YYYY-MM-DD hh:mm\"\n * event-end: When the event will stop in \"YYYY-MM-DD hh:mm\"\n * event-duration: The duration of the event [note 1]\n * event-location: Where the event takes place [[RFC5545, Section 3.8.1.7](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.7)]\n\nNote 1: To specify the event duration, use a number followed by a time unit, for example \"2h 30m\"\n\n * w: weeks\n * d: days\n * h: hours\n * m: minutes\n * s: seconds\n\nSupport for more iCalendar properties, prefixed with \"event-\" in the post metadata, were added in the update for the Portland Linux Kernel Meetup.\n\n * event-categories: comma-separated list of arbitrary categories [[RFC5545, Section 3.8.1.2](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.2), [RFC7986, Section 5.6](https://www.rfc-editor.org/rfc/rfc7986#section-5.6)]\n * event-comment: comment to the calendar user [[RFC5545, Section 3.8.1.4](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.4)]\n * event-description: textual description of the activity [[RFC5545, Section 3.8.1.5](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.5), [RFC7986, Section 5.2](https://www.rfc-editor.org/rfc/rfc7986#section-5.2)]\n * event-geo: latitude and longitude as floating point numbers separated by semicolon [[RFC5545, Section 3.8.1.6](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.6)]\n * event-status: status of the event as \"tentative\", \"confirmed\", or \"cancelled\" [[RFC5545, Section 3.8.1.11](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.11)]\n * event-summary: short one-line summary about the activity [[RFC5545, Section 3.8.1.12](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.1.12)]\n * event-url: URL online location of a more dynamic rendition of the calendar information [[RFC5545, Section 3.8.4.6](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.6), [RFC7986, Section 5.5](https://www.rfc-editor.org/rfc/rfc7986#section-5.5)]\n * event-uid: globally unique identifier [[RFC5545, Section 3.8.4.7](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.4.7), [RFC7986, Section 5.5](https://www.rfc-editor.org/rfc/rfc7986#section-5.3)]\n * event-created: date and time that the calendar information was created [[RFC5545, Section 3.8.7.1](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.7.1)]\n * event-name: name for presenting the calendar data to a user [[RFC7986, Section 5.1](https://www.rfc-editor.org/rfc/rfc7986#section-5.1)]\n * event-image: image for the event via a URI or inline data [[RFC7986, Section 5.10](https://www.rfc-editor.org/rfc/rfc7986#section-5.10)]\n * event-conference: information for accessing a conferencing system for attendees [[RFC7986, Section 5.11](https://www.rfc-editor.org/rfc/rfc7986#section-5.11)]\n * event-styled-description: rich-text description of the activity [[RFC9073, Section 6.5](https://www.rfc-editor.org/rfc/rfc9073#name-styled-description)]\n * event-concept: formal categories or classifications of the event [[RFC9253, Section 8.1](https://www.rfc-editor.org/rfc/rfc9253#section-8.1)]\n * event-link: additional information related to the component [[RFC9253, Section 8.2](https://www.rfc-editor.org/rfc/rfc9253#section-8.2)]\n * event-refid: free-form text that creates an identifier for associated components [[RFC9253, Section 8.3](https://www.rfc-editor.org/rfc/rfc9253#section-8.3)]\n * event-x-\\*: non-standard experimental properties [[RFC5545, Section 3.8.8.2](https://www.rfc-editor.org/rfc/rfc5545#section-3.8.8.2)]\n\nHowever, not all iCalendar properties make sense in the context of a public post. Those intended for private emails were excluded in a security review to prevent misconfiguration and mischief. A few were disallowed because they are redundant with metadata settings that generate those properties in the original events plugin. If you think you need a property which was excluded, [submit an issue to the project](https://github.com/ikluft/pelican-events/issues) stating which property is requested and explaining why it should be allowed in a public setting.\n\nThe disallowed iCalendar properties are: *acknowledged action attach attendee busytype calendar-address calscale class color completed contact dtend dtstamp dtstart due duration exdate exrule freebusy last-modified location-type method organizer participant-type percent-complete priority prodid proximity rdate recurrence-id refresh-interval related-to repeat request-status resources resource-type rrule sequence source structured-data transp trigger tzid tzid-alias-of tzname tzoffsetfrom tzoffsetto tzuntil tzurl version xml*\n\nContributing\n------------\n\nContributions are welcome and much appreciated. Every little bit helps. You can contribute by improving the documentation, adding missing features, and fixing bugs. You can also help out by reviewing and commenting on [existing issues][].\n\nTo start contributing to this plugin, review the [Contributing to Pelican][] documentation, beginning with the **Contributing Code** section.\n\n[existing issues]: https://github.com/ikluft/pelican-events/issues\n[Contributing to Pelican]: https://docs.getpelican.com/en/latest/contribute.html\n\n### Development Environment\n\nUpon commit to the repository, the Github workflow will perform unit tests on current versions of Python.\nSo prior to checking in code, at least run the tests on your local environment to make sure you won't break the build.\n\n pdm run invoke tests\n\nIt will also do a lint check which shows diffs that the linter wants for proper formatting.\nThis is also marked as a build failure if it doesn't work.\n\n pdm run invoke lint --diff\n\nIf it says there are changes to make, you can run this in your workspace to apply those changes.\n\n pdm run invoke lint --fix\n\nTo make a local git hook to perform these checks before each commit, make a symbolic link as follows:\n\n ln -s \"../../docs/pre-commit-git-hook.sh\" .git/hooks/pre-commit\n\nExample usage\n-------------\n\nThe pelican-events plugin was made for and is used by the [Portland Linux Kernel Meetup](https://ikluft.github.io/pdx-lkmu/) in Portland, Oregon, USA.\n\nLicense\n-------\n\nThis project is licensed under the AGPL-3.0 license in order to be compatible with Pelican.\n",
"bugtrack_url": null,
"license": "AGPL-3.0",
"summary": "iCalendar events plugin for Pelican",
"version": "0.1.2",
"project_urls": {
"Changelog": "https://github.com/ikluft/pelican-events/blob/main/CHANGELOG.md",
"Homepage": "https://github.com/ikluft/pelican-events",
"Issue Tracker": "https://github.com/ikluft/pelican-events/issues"
},
"split_keywords": [
"pelican",
" plugin",
" icalendar",
" events"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "6334b3ed21f051f716a71e45c3e56406f0a8d883d6fd3597175d79e2b1b33f9d",
"md5": "bc8c61c0cda817b1aa2cf2b656e10c23",
"sha256": "8039c105e75685a45c9ac5ff0d6fc5a068da8efac308b9a2b737ff82091ca1ab"
},
"downloads": -1,
"filename": "pelican_events-0.1.2-py3-none-any.whl",
"has_sig": false,
"md5_digest": "bc8c61c0cda817b1aa2cf2b656e10c23",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.11",
"size": 41734,
"upload_time": "2025-10-15T08:36:55",
"upload_time_iso_8601": "2025-10-15T08:36:55.425970Z",
"url": "https://files.pythonhosted.org/packages/63/34/b3ed21f051f716a71e45c3e56406f0a8d883d6fd3597175d79e2b1b33f9d/pelican_events-0.1.2-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "2b70f1efef3a3924c7f68ffe1bb65efbdf43e335b072d5df0054d9e2671cda5d",
"md5": "7ef824c0295b54db1be8a8e074251109",
"sha256": "29fce1dde6b02b7712beb3135ade6ea88f162c2d2a49f188c474eae8910b0891"
},
"downloads": -1,
"filename": "pelican_events-0.1.2.tar.gz",
"has_sig": false,
"md5_digest": "7ef824c0295b54db1be8a8e074251109",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.11",
"size": 38388,
"upload_time": "2025-10-15T08:36:56",
"upload_time_iso_8601": "2025-10-15T08:36:56.780432Z",
"url": "https://files.pythonhosted.org/packages/2b/70/f1efef3a3924c7f68ffe1bb65efbdf43e335b072d5df0054d9e2671cda5d/pelican_events-0.1.2.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2025-10-15 08:36:56",
"github": true,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"github_user": "ikluft",
"github_project": "pelican-events",
"travis_ci": false,
"coveralls": false,
"github_actions": true,
"lcname": "pelican-events"
}