toa/twitter-bootstrap-bundle
Symfony bundle that integrates Twitter Bootstrap into Symfony projects, providing Bootstrap-ready templates and form themes to help you build responsive, styled interfaces with less frontend boilerplate.
Reality check first: toa/twitter-bootstrap-bundle is a Symfony2 bundle, not a Laravel package. There is no service provider, no Facade, no auto-discovery (Symfony bundles predate Composer's extra.laravel conventions entirely). You cannot composer require it into a Laravel app and expect it to wire itself up. Practically, you have two paths: (a) you're maintaining a legacy Symfony 2.x application and this is already in composer.json, or (b) you're mining it for templates/markup to port into Laravel Blade + Vite.
If you're on the legacy Symfony side, the minimal path is:
composer require toa/twitter-bootstrap-bundle (expect a dependency-resolution failure against any modern symfony/* requirement — this targets Symfony ~2.0/2.1).app/AppKernel.php:
new Toa\TwitterBootstrapBundle\ToaTwitterBootstrapBundle(),
php app/console assets:install web --symlink and, if Assetic is in play, php app/console assetic:dump.php app/console cache:clear --env=dev.Where to look first: Resources/public/ (the vendored Bootstrap CSS/JS — read the header comment to confirm whether it's Bootstrap 2.x or 3.x, because that dictates every class name you'll write), Resources/views/ (layout/base template and the form theme under Resources/views/Form/), and DependencyInjection/Configuration.php (what few knobs exist).
First use case: have a controller render a form and apply the bundle's form theme so form_row emits Bootstrap-friendly markup (<div class="control-group">, class="help-inline", etc.) rather than Symfony's default table-based output. That's the entire value proposition — the asset shipping is a convenience you'd replace with Vite on day one anyway.
For the Laravel dev specifically: your first useful move is to copy Resources/views/Form/*.html.twig into your project as reference and rewrite the blocks as Blade components (<x-form.input>, <x-form.error>). There is no drop-in Laravel equivalent in this repo.
Global form theme application. The idiomatic Symfony2 pattern was to register the theme once in config.yml rather than per-template:
twig:
form:
resources:
- 'ToaTwitterBootstrapBundle:Form:bootstrap.html.twig'
Then every form_widget()/form_row() in the app picks it up. If you only need it in one view, use {% form_theme form '...' %} at the top of the template instead — this is the pattern to prefer when you're incrementally bootstrapping an existing app and don't want to break unrelated forms.
Base layout inheritance. Extend the bundle's base template and override blocks, rather than editing vendor templates:
{% extends 'ToaTwitterBootstrapBundle::base.html.twig' %}
{% block content %}{{ parent() }}...{% endblock %}
Porting pattern into Laravel (the realistic day-to-day use). Map the Twig form theme blocks to Blade components and swap the bundle's vendored CSS for a maintained Bootstrap via npm/Vite:
npm install bootstrap @popperjs/core
{{-- resources/views/components/form/input.blade.php --}}
@props(['name', 'label' => null, 'type' => 'text'])
<div class="mb-3">
@if ($label)<label for="{{ $name }}" class="form-label">{{ $label }}</label>@endif
<input type="{{ $type }}" name="{{ $name }}" id="{{ $name }}"
{{ $attributes->merge(['class' => 'form-control' . ($errors->has($name) ? ' is-invalid' : '')]) }}>
@error($name)<div class="invalid-feedback">{{ $message }}</div>@enderror
</div>
Note the class translation: Bootstrap 2 (control-group, help-inline, span6) → Bootstrap 3 (form-group, help-block, col-md-6) → Bootstrap 5 (mb-3, invalid-feedback, grid via col-md-6 on children). You will be doing this mapping by hand; nothing in the bundle automates it.
Icon/macro helpers. Bundles of this vintage typically expose Twig macros for icons and buttons. In Blade these become @include partials or components with named slots. Keep them dumb — the original macros were string-concatenation helpers and port cleanly.
Integration tip: don't run the legacy bundle and a Vite-built Bootstrap asset pipeline side by side. Pick one. Dual-loading Bootstrap 2 and 5 will produce subtly broken modals and tooltips that are miserable to debug.
symfony/http-kernel / twig/twig conflict. Don't --ignore-platform-reqs your way past it — you'll get a bundle installed that references removed Symfony APIs.assets:install), assetic:dump not run for the current env, or the web/ symlinks broken from a moved project directory. Clear app/cache/ before suspecting the bundle itself.form_row looks wrong, dump() the resolved theme list with {{ dump(form.vars) }} or check twig.form.resources from app/console container:debug — the theme that actually wins may not be the one you think you registered globally.app/Resources/ToaTwitterBootstrapBundle/views/... mirroring the bundle's relative path. This is the Symfony2 convention and survives composer update. Prefer it over editing vendor/, which is the most common way people lose their work on this class of package.app/console cache:clear → app/console assets:install --symlink → app/console assetic:dump → inspect the rendered HTML for the expected <link> tag → only then read the bundle's Twig. The bundle is rarely the failing component; the asset pipeline around it usually is.DependencyInjection/Configuration.php with few or no options. Real customization happens at the Twig theme level and via template overrides, not through configuration.How can I help you explore Laravel packages today?