Skip to main content

mbarde.signups

Plone-Addon to provide dynamic sign-up forms for events with single or multiple dates / timeslots available.

Originally inspired by https://github.com/collective/uwosh.timeslot (content-type prefixes still come from there):

uwosh.timeslot offers a simple way to allow users of a Plone site to register for events (for example: training sessions or office hours).

Features

  • Define date based timeslots users can sign up to
  • Logged in users can watch and manage their signups
  • Timeslots can have capacities (waiting list and automatically moving up included)
  • Timeslots can have effective and expires date (for example to realize registration periods)
  • Customizable notification emails
  • Dynamically extend signup form with EasyForm (https://github.com/collective/collective.easyform)
  • External mail validation via OTP

User states:

  1. unconfirmed: Manager hast to confirm signup
  2. signedup: User is signed up
  3. signedoff: User is not signed up
  4. waiting: User is on waiting list (moves up when another signup is cancelled)

Dependecies

Installation

uv pip install mbarde.signups

Setup

Datasets of signups are identified by the email address of the registrant. So in order to do a proper matching you need to either

  • Set Use email address as login name to True in Plone security controlpanel

or

  • Create a member property called email

If you want pre-filling of personal data you have to specify corresponding member properties in @@mbarde-signups-controlpanel.

Usage

  1. Create UTSignupSheet
  2. Add UTDay
  3. Add UTTimeslot

Optional: Create EasyForm and set as additional form in UTSignupSheet settings

Important: Ensure MailHost is configured properly (https://docs.plone.org/adapt-and-extend/config/mail.html).

Automatic deletion of personal data

Managers can set "Automatically delete personal data after (days)" for each signup sheet. To have any effect a cronjob needs to be deployed to run purge_expired_persons.py regulary.

For example like this:

0 3 * * * cd /path/to/instance && venv/bin/zconsole run etc/zope.conf venv/bin/mbarde_signups_purge_expired_persons --no-dryrun --site-id Plone

(see [project.scripts] in pyproject.toml)

Contribute

Development

Setup

uv venv venv
source venv/bin/activate
uv pip install -e .
uv pip install -r requirements-dev.txt

Test, lint & format

venv/bin/pytest
venv/bin/pytest -k name_of_a_test
venv/bin/black src/
venv/bin/flake8 src/
venv/bin/isort src/

Run a local Plone instance

Create a Zope/Plone instance once (creates instance/, gitignored, with an admin user):

venv/bin/mkwsgiinstance -d instance -u admin:admin

Start it:

venv/bin/runwsgi instance/etc/zope.ini

Then open http://localhost:8080 and use "Create a new Plone site" (log in as admin), adding mbarde.signups (and collective.easyform) as add-ons during site creation, or afterwards via Site Setup > Add-ons.

Set debug-mode on in instance/etc/zope.conf for template auto-reload during development (Python changes still need a restart).

Signups and cancellations send notification emails, which fail locally without a configured SMTP server (ConnectionRefusedError). With debug-mode on and Products.PrintingMailHost installed (part of requirements-dev.txt), outgoing mail is printed to the instance log (instance/var/log/event.log) instead of actually being sent - no local mail server needed.

Update translations

source venv/bin/activate
uv pip install i18ndude
cd src/mbarde/signups/locales
./update.sh

Zope only ever loads compiled .mo catalogs at startup, never the .po source files directly (and .mo files are gitignored, since they're a build artifact). Add this to the <environment> section of instance/etc/zope.conf so a fresh .po is automatically compiled to .mo on every restart - otherwise translations silently keep showing the English text no matter which language is negotiated:

<environment>
  zope_i18n_compile_mo_files true
</environment>

Publish to PyPI

  1. Bump version in pyproject.toml (a version can never be uploaded twice), commit and push.
  2. Run tests: venv/bin/pytest
  3. Build fresh (clear dist/ first, it may contain older versions):
rm -rf dist build src/*.egg-info
uv build
uvx twine check dist/*
  1. Upload with an API token from pypi.org (Account settings > API tokens):
uv publish --token pypi-...
  1. Tag the release: git tag vX.Y.Z && git push --tags
  2. Verify in a clean environment: uv pip install --pre mbarde.signups (--pre is only needed for pre-releases like 1.0.0rc2).

Optional dry run against TestPyPI (separate account and token): uv publish --publish-url https://test.pypi.org/legacy/ --token pypi-...

VS Code setup

Plugins:

  • ms-python.black-formatter: Python formatting
  • ms-python.flake8: Python linting
  • ms-python.vscode-pylance: Python language support
  • ms-python.isort: Python imports sorting
  • esbenp.prettier-vscode: .html/.pt/.md formatting
  • redhat.vscode-xml: .xml formatting

Settings:

{
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[python]": {
    "editor.defaultFormatter": "ms-python.black-formatter"
  },
  "editor.formatOnSave": true,
  "files.associations": {
    "*.pt": "html",
    "*.zcml": "xml"
  },
  "editor.codeActionsOnSave": {
    "source.organizeImports": "always"
  }
}

License

The project is licensed under the GPLv2, see LICENSE.GPL.

AI Usage

Parts of this addon were developed with assistance from Claude Code, Anthropic's agentic coding CLI, using the Claude Sonnet 5 model. The tool was used interactively under human direction and review.

Metadata

Release files for mbarde.signups 1.0.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mbarde.signups 1.0.0
File Size Uploaded
mbarde_signups-1.0.0.tar.gz 87.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mbarde.signups 1.0.0
File Interpreter ABI Platform
mbarde_signups-1.0.0-py3-none-any.whl Python 3 none any Details

Total release size: 210.1 kB

Release files / mbarde_signups-1.0.0.tar.gz

Download URL mbarde_signups-1.0.0.tar.gz
Size 87.0 kB
Tags Source
SHA-256 checksum
How to use checksums
6439f3d93e16fd405059b2033103606294072dfe8bb35952ee5a9bcdb816c3bb
BLAKE2b-256 checksum
How to use checksums
995de8bdb8b57864a6be9de57dc478c0dbb2ad538dd56220320ce15850c2e935
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / mbarde_signups-1.0.0-py3-none-any.whl

Download URL mbarde_signups-1.0.0-py3-none-any.whl
Size 123.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
fc121685a037b6a369f4142f6789ac1fdd9a9bf62c1dbc63a0dc0ee917ca36cc
BLAKE2b-256 checksum
How to use checksums
7a042e7acc274ef03c1b692df0dde62d49a6a3e4858ba7071bcac51a57c4b0bf
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via uv/0.12.12 {"installer":{"name":"uv","version":"0.12.12","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"26.04","id":"resolute","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release history Release notifications | RSS feed

This release

1.0.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page