anomaly/default_page_handler-extension
An extension for the Anomaly CMS (PyroCMS) that supplies a default page handler, providing fallback routing and content rendering when no specific page handler matches a request. Helps keep URLs resolving predictably within Anomaly's pages module.
This extension is not something you reach for to solve a problem — it is the piece of plumbing that makes the Pages module's "Default" page type work at all. In a normal PyroCMS 3 install it arrives as a dependency of anomaly/pages-module, so the first thing to do is check whether it is already there before adding anything.
composer show anomaly/default_page_handler-extension
If it is missing (e.g. you assembled a module set by hand), install and register it through the addon lifecycle rather than just composer:
composer require anomaly/default_page_handler-extension
php artisan addon:install anomaly.default_page_handler-extension
php artisan view:clear
php artisan cache:clear
Where to look first, in this order:
src/DefaultPageHandlerExtension.php — the extension definition. Note the $provides slug (typically anomaly.module.pages::handler.default); this is the key the Pages module resolves handlers against.src/Handler/DefaultPageHandler.php — the class that actually implements the handler contract: which fields it exposes on the page form and what it returns when the page is rendered.resources/views/ — the template it renders. This is the file you will touch 90% of the time.resources/lang/ — the label/description strings shown in the admin page-type dropdown.The first real use case: in the control panel, go to Pages → Create, pick the Default page type, fill in the body content, assign it a path/route under a parent (or at root), save, publish, and visit the URI. If that renders your theme layout with the body content in the expected region, the extension is healthy and you can start shaping the template.
Treat it as the baseline, not a workspace. The intended workflow is: the Default handler renders a generic "title + body" page; when a page needs structure (a landing page with hero/sections, a team page with repeatable members), you create your own extension that mirrors this one rather than editing vendor files. Copy the Extension + Handler pair into addons/default/<vendor>/<your-handler>-extension/, bump the handler slug, and register it.
Custom handler skeleton, based on this package's shape:
class HeroPageHandler extends PageHandler
{
public function handle(PageInterface $page)
{
return view('anomaly.extension.hero_page_handler::page', [
'page' => $page,
'entry' => $page->getEntry(),
'content' => $page->getEntry()->getAttribute('body'),
]);
}
}
Declare custom fields for the page type either through the handler's field definitions or, more idiomatically, through a Streams assignment on the Pages module's pages stream — the Default handler does the latter, which is why its form is just the standard page fields.
Theming via view override. Publish the addon's views, then edit the published copy so upgrades do not clobber you:
php artisan addon:publish anomaly.default_page_handler-extension
After publishing, the template lives under your project's resources/views/ addon namespace. Keep the original structure (index/page/wrapper) so the Pages module's layout resolution keeps working.
Delegating layout to the theme. The Default handler should not hardcode <html>. It typically renders the page body and lets the theme's layout wrap it, driven by the page's layout/theme_layout field. If you find yourself writing a full document in the handler view, you have duplicated the theme.
Route and path resolution. Pages are resolved by path, not by handler — the handler only decides how the resolved page is rendered. That means one handler can serve many pages, and you should never key logic off the URI inside the handler. Use page fields or the entry's stream data instead.
Composing with the Pages module API. Inside the handler you have PageInterface: getPath(), getTitle(), getEntry(), isHome(), getResponse()/setResponse(). Prefer these over reading request data. If you need to short-circuit (redirect, 404), returning a Response from handle() is the clean escape hatch.
Testing integration. Point a feature test at a known page path and assert on rendered content rather than on the handler class directly — the handler is an implementation detail of the route.
vendor/. This is a zero-star, low-activity package. It will not be patched for you, and any local edit is silently lost on the next composer update. Fork it into addons/ with a distinct namespace if you must change behavior.anomaly/pages-module leaves you with an unregistered provider and a missing page type. Run addon:install for pages first.handler.default, whichever registers last wins and you get confusing "why is my page using the wrong template" behavior. Keep slugs namespaced to your vendor.php artisan view:clear && php artisan cache:clear. In PyroCMS, addon manifests are cached too — php artisan addon:reinstall anomaly.default_page_handler-extension is the blunt but reliable reset when the page type vanishes from the admin dropdown.enabled/published, the path is unique and correctly nested, the locale matches the request, and the theme actually provides the layout the page references.theme_layout the active theme does not ship renders an empty response rather than throwing. Grep the theme's layouts/ directory before debugging the handler.body comes back null, the problem is usually that the pages stream assignment was not migrated (fresh installs after a manual addon install) — reinstall the Pages module rather than patching the handler.PageHandler::getFields()/form definition (to add fields to the page type), and the published view namespace. Anything beyond these three means you want your own handler, not a modification of this one.php artisan route:list confirms the page route exists before it renders; dd($page->getEntry()->getAttributes()) in handle() tells you exactly what fields the Default handler can see; the addons / addons_extensions DB tables show install state when the UI disagrees with you.composer.json and avoid floating dev-master in anything you intend to maintain.How can I help you explore Laravel packages today?