Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Layout Bundle Laravel Package

funwithsymfony/layout-bundle

A Symfony bundle from FunWithSymfony that provides layout helpers for organizing page templates and view structure. It helps integrate consistent, reusable layouts into Symfony applications, making front-end scaffolding simpler to build and maintain.

View on GitHub
Deep Wiki
Context7

Getting Started

funwithsymfony/layout-bundle is a Symfony 2–era bundle that adds a configurable layout layer on top of Twig: you declare layouts (base templates with named regions/blocks), then pick one at runtime from config, a route, or a controller so every page renders into a consistent shell. It's tiny (1 star, 0 dependents), unmaintained, and pinned to the Symfony 2 generation — so the day-to-day reality is that you treat it as vendored code you own, not a dependency you lean on.

Reality check before you type anything (Laravel developer): this is not a Laravel package. There is no service provider auto-discovery, no facade, no Blade integration, and no Composer bridge. It registers through AppKernel, wires services through Symfony's DI container, and renders through TwigBundle. If your app is Laravel, stop here and read Implementation Patterns → Blade-native equivalent below instead. The only reason to follow the install steps is that you've inherited a Symfony 2 codebase and are inventorying or temporarily stabilising what's already there.

1. Install with a pinned constraint. There is no meaningful release cadence, so never float on dev-master:

composer require "funwithsymfony/layout-bundle:dev-master#<commit-sha>"

Open the package composer.json first and read its symfony/symfony and twig/twig constraints. On anything past Symfony 2.x / Twig 1.x they will conflict and you should abort — the dependency tree will not resolve on a modern PHP 8.x runtime.

2. Register the bundle in app/AppKernel.php (Symfony 2 layout — app/, not bin/):

public function registerBundles()
{
    return array(
        // ...
        new FWS\LayoutBundle\FWSLayoutBundle(),
    );
}

Confirm the exact class name and namespace from the package's composer.json autoload block and the bundle root file — the marketing description doesn't state them.

3. Read these files first, in this order. They are effectively the whole package:

  • README.md — usually the only usage doc, and often stale relative to the code.
  • DependencyInjection/Configuration.php — the authoritative config tree. The root key is derived from the bundle name (likely fws_layout); confirm it here, don't guess from the README.
  • DependencyInjection/FWSLayoutExtension.php — shows which services and parameters the config actually drives.
  • Resources/config/services.xml (or .yml) — the real service IDs you'll inject or override.
  • Resources/views/ — the shipped base layout template you extend or override.

4. First use case — register a layout, extend it. The core loop is: declare a named layout in config, point it at a Twig base template, then extends that layout from your page templates.

# app/config/config.yml
fws_layout:
    layouts:
        default:  "FWSLayoutBundle:Layout:base.html.twig"
        checkout: "FWSLayoutBundle:Layout:checkout.html.twig"
{# AcmeDemoBundle:Page:index.html.twig #}
{% extends 'FWSLayoutBundle:Layout:base.html.twig' %}

{% block content %}
    <h1>Hello</h1>
{% endblock %}

That's the day-to-day value: one place to define shells, many templates inheriting them. If you only need that, Twig's native extends already does it — the bundle earns its keep only when which layout a page uses is a runtime/config decision.

Implementation Patterns

Config-driven layout selection. Declare every layout once under the bundle's config root, keyed by a stable name. Controllers and templates then reference the name, not a filesystem path — so a brand/tenant/theme change is a one-line config edit rather than a search-and-replace across {% extends %} lines.

Template inheritance as the composition layer. Let the bundle own the outer shell (header/nav/footer/flash region) and let your feature templates fill named blocks. Keep three tiers clean:

{# 1. bundle base: chrome + regions #}
{# 2. feature layout: extends base, adds feature-specific nav #}
{% extends 'FWSLayoutBundle:Layout:base.html.twig' %}
{% block sidebar %}{% include 'AcmeDemoBundle:Nav:checkout.html.twig' %}{% endblock %}

{# 3. page template: extends feature layout #}
{% extends 'AcmeDemoBundle:Layout:checkout.html.twig' %}
{% block content %}...{% endblock %}

Controller-side selection. When the layout is a per-request decision, resolve the layout name in the controller (or in a kernel request listener if it's cross-cutting) and pass it to the view. Keep resolution logic in one small service rather than scattering conditionals through actions — that service is the piece you'll carry forward when you migrate off the bundle.

Symfony template-override conventions are your extension point. Rather than editing the bundle, drop a same-named template into app/Resources/FWSLayoutBundle/views/... to shadow the shipped one. This is how you theme without forking, and it's the first thing to check when a change "doesn't appear."

Decorate, don't modify. If you need resolution logic the bundle doesn't give you (fallback chains, tenant defaults), decorate the bundle's resolver service in your own bundle's services.yml and leave the original untouched. That keeps your diff isolated and makes the eventual removal a matter of deleting your decorator.

Blade-native equivalent (Laravel). Extract the concept — a resolution chain that picks a layout from context — and rebuild it on supported APIs:

Bundle idea Laravel primitive
Layout registered in config config/layouts.php map of name → view
{% extends %} hierarchy Blade @extends / @section / @include
Runtime layout selection Middleware or view composer sharing $layout
Theme/bundle template override View::addNamespace() + view()->prependNamespace()
Fallback chain (requested → tenant → default) Config array + a resolver service class

Roughly a few hundred lines, entirely inside supported APIs, and readable by anyone on the team.

Staged retirement pattern. If the bundle is live, wrap each use behind a small resolver interface so call sites depend on your abstraction, not the bundle's. Swap the implementation to Blade later without touching templates or controllers. This is the single highest-leverage pattern for the migration.

Gotchas and Tips

It is not installable on Laravel — don't try. No service provider, no facade, no Blade. rcrowe/twigbridge gives you Twig-as-engine but not Symfony bundle lifecycle, container semantics, or the TwigExtension wiring the bundle assumes. The port cost exceeds reimplementing the resolution logic natively.

Composer will refuse to resolve. Legacy Symfony 2 components and Twig 1.x are EOL and pin PHP below what current Laravel requires. If you see resolution failures, that's the signal to stop, not to reach for --ignore-platform-reqs — the transitive dependencies carry known, unpatched vulnerabilities.

The config root key is derived, not documented. It comes from the bundle name (fws_layout is the likely guess, but verify in DependencyInjection/Configuration.php). A wrong root key fails silently — Symfony just ignores unknown config — and you'll spend an hour wondering why layouts aren't registering.

Silent fallback is the classic failure. A missing or mistyped layout name often falls back to a default rather than erroring. Log the resolved layout name at debug level in your resolver, and assert in a functional test that a page renders the layout you expect. Without this, "wrong skin in production" is invisible until a customer reports it.

Compiled-template cache staleness. After changing a layout config value or theme files, clear Twig's compiled cache (app/cache/{env} removal, or cache:clear). Symptom: your edit appears to be ignored. This is the most common false "bug report" against the bundle.

Template override precedence confuses everyone. app/Resources/<Bundle>/views/ beats the bundle's own Resources/views/. If two layers define the same block, the most derived template wins — but a missing {{ parent() }} in an overridden block quietly drops the base content instead of erroring.

No upstream support means you own it. No issue triage, no security response, no upgrade path, bus factor of one. Plan to fork and vendor internally (or extract the resolution semantics into your own code and delete the dependency), and pin to a commit SHA so nothing changes under you.

Debugging toolkit. Enable twig.debug and use the profiler's template panel to see which template actually rendered; dump the container (debug:container FWSLayout) to find the real service IDs; dump the resolved layout name in your resolver before it reaches the view. With no upstream docs, tracing the container is faster than reading the README.

Where to extend. Decorate the resolver service, add a Twig global/function via your own extension for layout-name lookup, and use template overrides for presentation. Don't subclass bundle internals — you'll be re-merging them by hand at every fork.

When to walk away. If you're on Symfony 3.4+ or Laravel, this is a migration line item, not a component. Write the resolution requirements down as a spec, prototype the native implementation behind a feature flag, validate against real templates in staging, then remove the bundle.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings