Auth pages
Status: 80% — login / fpw / members-only solved, signup polish remaining.
What they are
The three core authentication pages — login.php, signup.php, fpw.php (forgot password) — mapped to the auth layout (formerly named splash) via theme.xml:
<layout name='auth' title='Splash (auth pages)'>
<custompages>login fpw signup</custompages>
</layout>The layout is the Tabler auth pattern: .page.page-center → .container-tight → centered brand → {---}. The card around the form itself comes from tablestyle(), not from the layout — that is what keeps the standard and members-only render paths visually identical.
The famous problem: members-only renders differently
This was a long-standing mystery. With Members only enabled, fpw and signup ignore the theme layout completely. Root cause (core):
fpw.php/signup.phpcalldefine('e_IFRAME', true)in their members-only branch and pass the templateheader/footerase_IFRAME_HEADER/e_IFRAME_FOOTER.In
header_default.php,e_IFRAMEmode discards the theme's$HEADER/$FOOTERand prints the iframe strings instead — layout, custompages mapping,theme.html, everything is bypassed.Bonus core quirk: with an HTML-layout theme the page then has no
<body>tag at all (the layout that carried it was discarded and thenoBodycode path prints none).
login.php is different again: it renders in e_IFRAME mode always (not only members-only), but offers an official opt-out.
The solutions
Login — official opt-out
In the theme override templates/login_template.php:
Login then renders through the full theme (auth layout).
fpw / signup — replicate the layout in the template
No opt-out exists, so the theme override templates/fpw_template.php defines header/footer that replicate the auth layout wrapper. Those two keys are used only in the members-only (e_IFRAME) path — the standard path uses only the form key — so nothing is duplicated at runtime. membersonly_template.php does the same for signup via its ['signup']['header'] / ['footer'] keys.
The simpleParse() trap. fpw.php pipes the template header/footer through simpleParse(), whose regex {[\w]+} deletes every plain {WORD} shortcode before the full parser ever runs — {SITENAME}, {THEME}, custom theme shortcodes, all gone. Only parameterized shortcodes survive (e.g. {SITELOGO: h=40} — the colon breaks the match). Rule: build paths and texts in these headers/footers from PHP constants (SITEURL, SITENAME, SITETAG, THEME_ABS) and read theme prefs via e107::getThemePref() in PHP. Documented as a code comment in the template.
A theme template override replaces the core file entirely — the fpw override must define the form key too, otherwise the standard page renders an empty form.
Security notes
Theme pref values used in HTML attributes (auth image path) are escaped with
e107::getParser()->toAttribute().The templates contain no custom
<form>actions and no auth logic — authentication stays entirely in core.During this work the fork's
fpw.phpwas found lagging behind upstream security fixes (reset-code replay,hash_equals()comparison, expired-code fallthrough) — synced before building templates on top of it.
Remaining work (the missing 20%)
Signup form field styling pass (Tabler
mb-3/form-labelmarkup).Auth splash image as a theme preference (
{THEME_AUTH_BGIMAGE}shortcode for layouts, PHP pref read for the fpw/membersonly templates).Report the missing-
<body>-tage_IFRAMEquirk upstream; consider anoiframePR forfpw.php/signup.phpmirroringlogin.php.
Last updated