- Two new stub rows now bookend each section's rail. The top cap is a 4px-high TR whose rail TD carries border-top-left/ -right-radius so the rail's top end visually rounds off. The bottom cap is an 18px-high TR with border-bottom-left/ -right-radius so the rail's tail tapers into a rounded stop beneath the last card. - The chevron arrowhead now lives in its own TR with no rail border, sitting 14px below the rounded rail-end and another ~18px of cell height below that — visibly separated from the rail rather than sitting flush against its tip. - Chevron's horizontal offset shifted from -38 to -37 (one px right) and SVG width bumped to 26 to give the arrow a little more visual weight at its new lower position.
webtrees Email Newsletter
A webtrees 2.2+ custom module that sends recurring email newsletters with:
- Upcoming birthdays of still-living individuals.
- Upcoming marriage anniversaries of intact couples (optional — admin toggle, per tree). Marriages with a divorce or annulment fact are excluded automatically.
- Once-per-month historical section: births and deaths of deceased individuals whose anniversary falls in the upcoming window.
The decision to actually send is made by comparing a stored "last sent" timestamp to the configured frequency, so the dispatch run is idempotent — calling the trigger more often than the frequency simply does nothing extra.
Requirements
- webtrees ≥ 2.2.0
- PHP ≥ 8.2
- A working SMTP / sendmail configuration in webtrees → Control panel → Sending email (this module reuses webtrees' standard mailer).
- An external scheduler on the host: system
cron, asystemdtimer, a KubernetesCronJob, or anything else that can fire an HTTP request at a fixed interval. Newsletter dispatch never runs on visitor page loads — it only runs when the scheduler triggers it.
Installation
-
Copy this directory into the webtrees
modules_v4/folder, renaming it toemail_newsletter(the folder name determines the internal module identifier — the registered name will be_email_newsletter_).cp -r webtrees_email_newsletter /var/www/webtrees/modules_v4/email_newsletter -
In the webtrees control panel, go to Modules → All modules and enable Email Newsletter.
-
Open Control panel → Modules → Email Newsletter → Preferences and:
- Enable newsletter dispatch per tree.
- Pick a frequency (default: 14 days).
- Optionally toggle marriage anniversaries and add any extra external email addresses.
- Copy the Cron URL at the bottom — this is the secret-token URL your scheduler must hit.
Setting up the scheduler
Why no built-in scheduler? PHP has no daemon, and frameworks like Laravel rely on a once-per-minute system cron to fire their internal scheduler. This module follows the same convention: the host OS owns the timer, the module owns the "is it actually due?" decision.
System cron
# Run every 15 minutes. The module itself decides whether sending is due.
*/15 * * * * curl -fsS --max-time 60 'https://example.com/module/_email_newsletter_/Cron?token=YOUR_TOKEN' > /dev/null
systemd timer
/etc/systemd/system/webtrees-newsletter.service:
[Unit]
Description=webtrees newsletter trigger
[Service]
Type=oneshot
ExecStart=/usr/bin/curl -fsS --max-time 60 "https://example.com/module/_email_newsletter_/Cron?token=YOUR_TOKEN"
/etc/systemd/system/webtrees-newsletter.timer:
[Unit]
Description=Trigger webtrees newsletter dispatch
[Timer]
OnCalendar=*-*-* *:00/15
Persistent=true
[Install]
WantedBy=timers.target
Then systemctl enable --now webtrees-newsletter.timer.
Forcing a one-off send
The admin Preferences page has a Send now button for testing.
For an unattended one-off send, append &force=1 to the cron URL —
that bypasses the "is it due?" check.
Subscribers
Two sources, combined:
- Logged-in webtrees users who opt in via the per-tree Newsletter subscription menu entry (visible only to logged-in users on trees where the module is enabled). Only approved and email-verified accounts will receive the newsletter.
- External addresses the tree administrator lists in the Extra recipient email addresses textarea (one per line).
Privacy
The dispatch service does not impersonate a webtrees user, so it sees the tree from the visitor access level. Records and facts that your tree settings hide from visitors will be omitted from the newsletter even if a recipient has higher in-app access. This is the safest default for an outbound email — if you need to expose more information, relax the tree's visitor-access settings or hand-curate the Extra recipient list.
License
AGPL-3.0-or-later. See LICENSE for the full text.