goldnead/statamic-email-templates
Statamic addon for managing email templates in the control panel. Create, edit, and organize reusable email layouts with variables, previews, and multilingual support, so transactional emails stay consistent without touching code.
Architecture fit. This package now spans two distinct concerns. The v2.9.0 change is a Statamic Control Panel addon concern: settingsNavParent() returns a [section, name] tuple that nests the addon's settings screen under its own CP nav entry. The v2.9.1 change is materially different — EmailTemplates::resolve() sits in the outbound email rendering path, and now accepts a branded => false key in a caller-supplied fallback array so an already-complete body (with its own header/footer) is returned verbatim rather than wrapped in the branded shell again. That is a public API contract on a runtime path that produces customer-facing output, not a presentational CP detail. It still fits the Laravel/Statamic composition cleanly and adds no new dependencies, but the package's blast radius is now wider than "admin sidebar layout."
Integration feasibility. High for both changes, and both are explicitly non-breaking. v2.9.0 is version-gated on statamic-brand-context (1.16+ nests; below 1.16 the method is ignored). v2.9.1 is opt-in per call site: absent the branded key, behavior is byte-identical to before. No migrations, no new config key required. The practical work is not adoption but deliberate opt-in — deciding which callers pass branded => false and validating the rendered output in real mail clients.
Technical risk. Low-to-moderate, revised upward from the prior assessment. The v2.9.0 caveats stand (soft capability dependency on a sibling addon; hardcoded German label "Einstellungen" if the codebase is otherwise localizable). v2.9.1 adds three new concerns. First, the fix encodes a layout responsibility split: the branded shell vs. the caller's own header/footer. Two systems can each believe they own the chrome, and the opt-out flag is the only thing preventing double-framing — so correctness now depends on callers knowing their fallback body is complete. Second, if the branded shell carries legally required elements (unsubscribe link, postal address, compliance footer), returning the body unwrapped may drop them; the release note describes marketing templates carrying "their own header and footer" but does not state parity of required elements. Third, branded is a silently-defaulting boolean — a typo or a caller that forgets the key fails open into the double-wrapped rendering, which is the exact bug being fixed. Email rendering is also hard to catch with unit tests: the defect surfaced as mobile overflow, a client-specific visual symptom.
Key questions.
statamic-brand-context a suggested/optional dependency in composer.json, and what constraint range is declared?settingsNavParent() degrade safely if the referenced nav entry is absent or renamed?branded validated strictly (bool, unknown keys rejected) or does a misspelled key silently fall back to wrapped?Stack fit. Standard Laravel + Statamic composition; no new PHP extensions, queue workers, storage drivers, or external services. The CP change remains orthogonal to public request handling. The email change does touch a runtime path, but it is a pure rendering branch inside an existing resolver — no new transport, no new queue, no change to how mail is dispatched.
Migration path. Still effectively a composer version bump — nothing to publish, migrate, or cache-clear beyond normal package discovery. Two independent opt-ins follow: (a) raising statamic-brand-context to 1.16+ to adopt the new CP nesting, and (b) adding branded => false to specific fallback-returning callers. Both are reversible (pin brand-context; remove the key).
Compatibility. Backward compatible by design in both dimensions. Forward-compatibility caveat for the CP change is unchanged: if the addon's own nav entry is later removed or renamed, settings relocate silently to the shared "Addon-Suite" page. For email, the risk is the inverse — the default path keeps working forever, so stale double-wrapped templates will never announce themselves; they must be found by audit, not by error.
Sequencing.
branded behavior).EmailTemplates::resolve() that return complete HTML with their own header/footer — start with marketing's template files, which are the reported trigger.branded => false to those callers only, in a staging branch, and render-test across real clients (Gmail web/iOS, Apple Mail, Outlook) at mobile width, plus dark mode and the plain-text alternative.statamic-brand-context to 1.16+; verify the settings screen appears as "Einstellungen" under the addon's own nav entry.Maintenance. Two support matrices now instead of one. The CP side is documentation/triage overhead across the brand-context version boundary, collapsible once 1.16+ is universal. The email side is a standing ownership ambiguity: every new complete-HTML template is a fresh decision about who supplies the chrome, and the flag lives in calling code, not in this package. Recommend recording the convention (e.g. "complete templates must set branded => false and include the compliance footer") alongside the template files themselves.
Support. Expect "I can't find the settings" tickets after any brand-context upgrade (position moved, content unchanged) and, separately, a lower-volume but higher-severity class of "the email looks broken" reports if a caller is missed or a new one forgets the key. Brief support on both: how to check the brand-context version, and how to identify whether an affected email came from a wrapped or verbatim path.
Scaling. No impact. CP navigation rendering affects only authenticated admin users. Email rendering is per-send, CPU-trivial, and the new branch is a shallow conditional that removes work rather than adding it. No bearing on request throughput, database load, or queue capacity.
Failure modes.
statamic-brand-context is uninstalled after being present, verify settings remain reachable rather than resolving at render time.branded => false renders double-framed — the original defect — and fails silently.branded misspelled or wrong type defaults to wrapped; fails open, not closed.Ramp-up. Under an hour for a developer familiar with Statamic addons to adopt both changes mechanically. The real effort is validation and convention-setting: auditing email call sites, rendering across real mail clients, confirming compliance content, updating admin-facing docs and screenshots, and briefing support on two UI layouts and two email layouts. Budget a half-day of QA across both brand-context versions before rollout, weighted toward the email path.
How can I help you explore Laravel packages today?