Skip to content

Forms learn to feed the newsletter - #41

Merged
AllTerrainDeveloper merged 2 commits into
mainfrom
feature/mailpoet-integration
Aug 22, 2026
Merged

AllTerrainDeveloper merged 2 commits into
mainfrom
feature/mailpoet-integration

Conversation

@AllTerrainDeveloper

Copy link
Copy Markdown
Owner

What

The MailPoet integration: a new MailPoet row in the dock submenu (below Themes) opens a dedicated window where any form can be connected to MailPoet lists.

The window

  • MailPoet-styled hero — their logo (served from their own install, only when present) on the one surface allowed their brand orange; everything else wears the shell's tokens like every other window.
  • Per-form connection cards: tick the lists, map the email / first / last name answers, and bind the subscription to an opt-in the visitor actually ticks. Consent is the default; "everyone who submits" is the deliberate choice. Lazy status ("Subscribing → Newsletter mailing list") per form.
  • Without MailPoet: the same window makes the case and points at the installer — the row is how anyone discovers the integration either way.

The plumbing

Deliberately unexciting: an ordinary mailpoet action in the form's schema — conditional through the same logic block every action carries, run by atf_run_actions(), failures recorded on the entry. The handler (includes/mailpoet.php) maps answers to MailPoet's documented API (addSubscriber → subscribeToLists fallback), treats "already subscribed" as an outcome rather than an error, and MailPoet's own double opt-in confirms every address. GET /atf/v1/mailpoet serves state + lists, capability-gated on editing forms.

Verified

  • End to end against real MailPoet 5.36 on the QA site: connected "Old site contact form" to the Newsletter list bound to its consent field, submitted the front end — the subscriber appeared in MailPoet as unconfirmed (double opt-in pending) on the chosen list.
  • PHPUnit: 725 pass (9 new — mapping, consent gate via the full atf_run_actions() pipeline, both already-subscribed fallbacks, clean refusals, REST payload) against a recording stub that answers to the same API, so CI needs no MailPoet.
  • vitest: 372 pass (3 new dock-row cases). tsc --noEmit clean, PHPCS clean.

readme.txt gains the feature section — the kind of integration that is a paid addon elsewhere, free here.

🤖 Generated with Claude Code

https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp

AllTerrainDeveloper and others added 2 commits August 22, 2026 21:10
A form is where a relationship with a visitor starts; the newsletter
is how it continues. With MailPoet installed, any form can now
subscribe the visitors who opt in — and the bridge is a window of its
own, one dock row below Themes.

The window wears MailPoet's face where it introduces them — their
logo, served from their own install, on the one hero surface allowed
their orange — and the shell's tokens everywhere it works. Pick a
form, tick the lists, map the email and name answers, and bind the
subscription to a box the visitor actually ticks: consent is the
default, "everyone who submits" is the deliberate choice, and
MailPoet's own double opt-in confirms every address on top. Without
MailPoet, the same window makes the case and points at the installer.

What it writes is deliberately unexciting: an ordinary `mailpoet`
action in the form's schema, conditional through the same logic block
every action carries, run by the same pipeline, its failures recorded
on the entry like any action's. The handler maps the answers, hands
them to MailPoet's documented API, and treats "already subscribed" as
the visitor asking for something that is already true — an outcome,
not an error to stamp on their entry.

Proven end to end against the real MailPoet: a front-end submission
with the consent box ticked lands as an unconfirmed subscriber on the
chosen list, with MailPoet's confirmation email on its way. The PHP
side is covered by a recording stub that answers to the same API, so
the suite proves the mapping, the consent gate and both
already-subscribed fallbacks without MailPoet installed.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
The api module gained the /mailpoet call, and every bundle that
imports it re-emits with the change — CI's bundles-match-source check
is precisely for the ones forgotten.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0119U4sRRWGcTQdwYreTwpAp
@AllTerrainDeveloper
AllTerrainDeveloper merged commit b54589d into main Aug 22, 2026
3 checks passed
@AllTerrainDeveloper
AllTerrainDeveloper deleted the feature/mailpoet-integration branch August 22, 2026 19:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant