contenir / errors-laminas-mvc
Laminas MVC adapter for contenir/errors — swaps the default error rendering with admin-authored per-status pages.
Requires
- php: ^8.1 || ^8.2 || ^8.3
- contenir/errors: ^0.1.0
- laminas/laminas-eventmanager: ^3.0
- laminas/laminas-http: ^2.0
- laminas/laminas-mvc: ^3.4
- laminas/laminas-servicemanager: ^3.0
- laminas/laminas-view: ^2.0
- psr/log: ^1.0 || ^2.0 || ^3.0
Requires (Dev)
- phpunit/phpunit: ^11.0
- squizlabs/php_codesniffer: ^3.10
README
Laminas MVC adapter for contenir/errors.
Replaces the framework's default 4xx/5xx rendering with admin-authored per-status pages when configured. Non-invasive on first install — when the admin hasn't authored a page for a given status, the framework's default rendering proceeds unchanged.
Install
composer require contenir/errors-laminas-mvc
The Module is auto-registered by laminas/laminas-component-installer.
Configure
Point the package at a shared error-pages file (the same path the admin writes to) and optionally wire a PSR-3 logger:
// config/autoload/errors.global.php return [ 'errors' => [ 'file' => realpath(__DIR__ . '/../..') . '/configs/errors.local.php', 'view_template' => 'contenir/errors/fault', // override to use a Site-owned template 'logger' => 'log.psr3', // optional PSR-3 service ID ], ];
file is required. view_template defaults to the package's shipped
contenir/errors/fault.phtml (uses the .fault BEM block, no scripts,
<meta name="robots" content="noindex">, single "Return home" link).
logger may be null, a service ID resolvable from the container, or a
Psr\Log\LoggerInterface instance.
How it works
The ErrorListener attaches at MvcEvent::EVENT_RENDER and
EVENT_RENDER_ERROR at priority 100. By the time RENDER fires, the
response status is already settled (RouteNotFoundStrategy has set 404,
ExceptionStrategy has set 500, or a controller has called
setStatusCode(403)). The listener:
- Logs the 4xx/5xx via the optional PSR-3 logger (
info()for 4xx,error()for 5xx, with the exception in context if available). - If the repository has a non-empty page for the status, swaps the
result
ViewModeltemplate + variables (status,title,body) and marks it terminal so the layout is bypassed. - Otherwise leaves the existing render path untouched.
Override the view
To brand the page beyond what's possible in the body field, set
errors.view_template to your own template name:
'errors' => [ 'view_template' => 'site/error-page', ],
Your template receives:
| Variable | Type | Notes |
|---|---|---|
$status |
int |
HTTP status code (e.g. 404) |
$title |
string |
Plain text written by the admin |
$body |
string |
Sanitized HTML fragment (inline only) — render raw |
The body is trusted — sanitization is the writer's responsibility (see
the admin-side wiring in the consuming CMS). Render with <?= $body ?>.