anomaly/starter-theme
A starter theme package for Laravel that gives you a ready-made front-end scaffold to build on. Ships sensible defaults, reusable views, and a clean structure so you can style your app quickly without starting from scratch.
anomaly/starter-theme is a PyroCMS 3 / Streams Platform theme addon, not a general-purpose Laravel package. If you are not running a PyroCMS 3 application, nothing here applies — there is no service provider meant for a vanilla Laravel config/app.php provider list.
Minimal steps in a PyroCMS 3 project:
composer require anomaly/starter-theme
php artisan addon:install anomaly/starter-theme # registers the addon
php artisan addon:publish anomaly/starter-theme # publishes theme assets
Then activate it in the control panel under Appearance → Themes (the active theme is persisted in the settings module, not in config/). Confirm the theme is actually the active one before debugging anything else — a surprising amount of "my layout edits do nothing" is a theme that was never activated.
Where to look first, in this order:
vendor/anomaly/starter-theme/src/StarterThemeServiceProvider.php — the binding that registers the Theme class and, implicitly, the anomaly.theme.starter:: view namespace.vendor/anomaly/starter-theme/src/Theme/StarterTheme.php (or similarly named) — $slug, $name, $type, and any layout defaults live here.vendor/anomaly/starter-theme/resources/views/layouts/ — the actual Blade shell, and the file you will spend 90% of your time in.resources/views/partials/ — nav, header, footer, portfolio sections from the Freelancer template.First use case is almost never "use the theme." It is "use the theme as a starting point." The intended workflow is to copy it into your project's addons/ directory, rename the namespace, and own the code:
cp -r vendor/anomaly/starter-theme addons/anomaly/my-theme
# rename StarterThemeServiceProvider -> MyThemeServiceProvider, $slug = 'my_theme', etc.
composer dump-autoload
php artisan addon:install anomaly/my-theme
Treat the package as a scaffold you read once and then fork. That framing should drive every decision you make with it.
View namespace resolution. Addon views are addressed by the dotted addon slug, so a layout in resources/views/layouts/default.blade.php is anomaly.theme.starter::layouts.default. In your own theme, if you renamed the slug to my_theme under vendor anomaly, everything becomes anomaly.theme.my_theme::layouts.default. Hardcoding the old namespace in partial @extends/@include calls is the #1 rename mistake.
Pages module renders into your layout. A PyroCMS page selects a layout from your theme's layouts/ directory and injects its content. Your layout is responsible for the shell:
{{-- resources/views/layouts/default.blade.php --}}
<!DOCTYPE html>
<html>
<head>
<title>{{ page_title() }}</title>
@include('anomaly.theme.my_theme::partials.metadata')
</head>
<body>
@include('anomaly.theme.my_theme::partials.navigation')
<div class="container">@yield('content')</div>
@include('anomaly.theme.my_theme::partials.footer')
</body>
</html>
Keep @yield('content') where the Pages module expects it; moving or renaming that section silently blanks every page.
Multiple layouts for different sections. The Freelancer base gives you one layout. Real projects want a home (full-bleed hero), default (content with sidebar), and landing (no nav). Add files under layouts/ and they become selectable per page in the admin — no code changes needed. This is the cheapest way to make the starter theme feel like a real product.
Partial-driven page building. Because the Pages module supports embedded blocks/fields, the pattern that scales is: one partial per repeatable section (hero, portfolio grid, about strip, contact form), each reading from page fields rather than hardcoded markup. Convert the Freelancer HTML sections into partials you @include and feed variables, otherwise every new page means copy-pasting 200 lines of Bootstrap 3.
Assets. Theme CSS/JS live in the addon's resources/assets/ and are published on install. Reference them through the asset helper rather than relative paths so the URL survives being served from a subdirectory:
<link rel="stylesheet" href="{{ asset('addons/anomaly/starter-theme/resources/assets/css/starter.css') }}">
After changing assets in the addon, re-run php artisan addon:publish anomaly/starter-theme — edits to the source file do nothing until republished.
Navigation and links. Use the platform's link/navigation helpers rather than url('/about'). Pages get moved, slugs change, and multi-site installs mean the same template serves different domains.
Integration with other addons. Blocks, Pages, and Files modules all drop into your layout as partials. If you need a globally available variable in every view, register a view composer in your project's service provider — not in the vendor theme, where it will be lost on the next composer update.
vendor/. Every composer update wipes your changes with no warning. Fork to addons/ first, always..col-xs-*, panel, and img-responsive classes that no longer exist. Decide up front whether you are upgrading the CSS framework — mixing BS3 classes into a BS5 bundle produces silent layout breakage rather than errors.resources/views/partials/ or a LICENSE file; stripping it is both rude and a compliance risk.php artisan view:clear and often php artisan cache:clear. If your edit "didn't apply," clear before you debug.$slug property, and the anomaly.theme.<slug>:: namespace must all agree. A mismatch gives you View [layouts.default] not found with no hint about which of the four is wrong.composer dump-autoload is not optional after forking; the PSR-4 map still points at the old class name otherwise..env. If the theme is set in the settings repository (the control panel writes there), an ACTIVE_THEME style env var may be ignored. Change it where the admin UI writes it, or you will chase a phantom config precedence bug.php artisan view:clear && php artisan serve with APP_DEBUG=true gives you the Blade file and line — but only after the namespace resolves. If it hasn't, use php artisan tinker and check app('view')->getFinder()->getHints() for the registered namespace before assuming a typo in the template.Theme class exposes layout selection — override the layout per request there rather than with @if conditionals sprinkled through a single mega-layout.How can I help you explore Laravel packages today?