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

Tab Widget Laravel Package

friendsofvictoire/tab-widget

A Laravel package that provides a reusable tabbed widget for grouping content into switchable panels. Define tabs and their contents in PHP, then render a clean tabbed interface in dashboards or admin pages to keep dense information organized and easy to navigate.

View on GitHub
Deep Wiki
Context7

Getting Started

Framework reality check first: friendsofvictoire/tab-widget is a Symfony bundle (FriendsOfVictoire/WidgetTabBundle), not a Laravel package. It will not auto-discover, it has no service provider, and it is built for the Victoire CMS widget ecosystem (Doctrine entities, Symfony DI, Twig, and Victoire's WidgetsBundle / BusinessEntityBundle). If your target is Laravel, stop here and read the last section — you are porting a concept, not installing a dependency.

Minimal steps if you are on a (legacy) Symfony app already running Victoire:

  1. composer require friendsofvictoire/tab-widget — expect constraint fights; the last tagged release is 2016-08-22, so it pins Symfony 2.x/early 3.x era versions.
  2. Register the bundle in app/AppKernel.php:
    new FriendsOfVictoire\Bundle\WidgetTabBundle\WidgetTabBundle(),
    
    (check the actual class name in composer.json → autoload.psr-4 and the bundle root file; Victoire bundles are inconsistent about the FriendsOfVictoireWidgetTabBundle vs WidgetTabBundle suffix).
  3. Update the Doctrine schema (doctrine:schema:update --force or generate a migration) so the widget's entity tables exist.
  4. Clear cache and open the Victoire page builder; the widget should appear in the widget picker.

Where to look first (in this order):

  • Entity/ — the widget class and any child "tab"/"item" entity. This is the real API surface; everything else is plumbing.
  • Resources/views/ — the Twig templates that render the tab markup. This is where you will spend 90% of your time.
  • Resources/config/ — service definitions, and any widgets.yml/business_entity.yml style config that tells Victoire how the widget is registered.
  • DependencyInjection/ — usually thin, but reveals config keys.

First use case: drop a "Tab" widget into a Victoire page slot, define N tabs (label + content or a nested widget slot per pane), and render accessible tab markup on the front end. If your first attempt is "add the widget and see nothing," you have almost certainly hit a template override or a missing schema table, not a code bug.

Implementation Patterns

Widget-as-container. Victoire widgets are persisted Doctrine entities rendered through Twig, so the idiomatic pattern is composition: the tab widget owns a collection of tab items, and each item either holds rich text/HTML or reserves a slot for nested widgets. Treat the widget entity as your DTO and never put render logic in it beyond what the bundle already does — push markup into templates.

Template override is the primary extension point. Do not edit vendored files. Override in your app:

app/Resources/FriendsOfVictoireWidgetTabBundle/views/...

or, cleaner, register a Twig path that wins over the bundle's. Most real-world work on this package is "same data model, different HTML" — a Bootstrap nav-tabs variant, an accordion fallback for mobile, ARIA-correct role="tablist" markup.

Compose with the rest of Victoire. If each pane can host nested widgets, the tab widget becomes a layout primitive: use it to build settings pages, product spec sheets, FAQ blocks. Keep panes shallow (2–5 tabs) because the admin drag-and-drop gets unwieldy and the front-end markup rarely degrades gracefully past that.

Config-driven registration. Victoire widgets are discovered via bundle config (widget name, label, business entity mapping). If you are adding a variant — say "Tab (vertical)" — the pattern is a second widget class reusing the same entity/table with a mode discriminator, plus its own template and registration entry. Copy the existing config block rather than inventing a new convention.

For a Laravel developer translating the idea: the equivalent is a Blade component (<x-tabs :items="$items">) with slots per pane, or a Livewire component if tabs need server round-trips. The Symfony bundle's "entity + Twig template + registration config" triad maps to "model + Blade view + service provider registration." Do not attempt to run this bundle under Laravel; there is no bridge and no maintained port.

Gotchas and Tips

  • Abandonment is the headline risk. 2 stars, 0 dependents, last release 2016. There is effectively no documentation, no issue triage, and no compatibility work for PHP 7.2+ / Symfony 4+. Plan on forking and vendoring ("repositories": [{"type": "vcs", ...}]) rather than depending on Packagist.
  • Transitive dependency hell. Victoire bundles tend to require each other at dev-master or with loose ~2.0 constraints. Expect composer update to resolve to something you did not intend. Pin everything and commit composer.lock.
  • Missing tables = silent-ish failure. Widgets are Doctrine entities; forgetting the schema update produces errors deep in the render path, not at registration time. If the widget appears in the picker but the page 500s, check the schema first.
  • Translation keys for labels. The widget's display name in the admin usually comes from a translator key in Resources/translations/. If the picker shows a raw key, your locale file is missing or the bundle's translations were not loaded (cache clear required).
  • Cache is aggressive. Victoire caches widget maps and container config. After any template or config change: cache:clear and, in some setups, a manual wipe of the widget/HTML cache directory. "My template change did nothing" is nearly always cache.
  • Template resolution surprises. Symfony bundle inheritance means your override path must exactly mirror the bundle's internal path. A single wrong directory name silently falls back to the vendor template. Verify by temporarily breaking the vendor template — if the page still renders, your override is not being hit.
  • Debugging entry points: debug:container filtered on the widget service, debug:router for the admin routes, and Twig's dump() inside the widget template to see the actual entity shape — the entity's field names are undocumented, so inspect rather than guess.
  • Extension points, ranked: (1) template override, (2) Twig path registration, (3) subclass the widget entity and register it as a new widget, (4) decorate services. Anything beyond (2) is a fork.
  • Security: this predates most modern escaping guidance. Audit any |raw usage in the templates before letting non-admin users author tab content.
  • Migration advice: if you are evaluating this for new work, treat it as a reference implementation, not a dependency. The feature is "group content into tabs with persisted, editable labels and bodies" — a weekend of work in Blade + Alpine.js + a JSON column in Laravel, with zero legacy constraint risk and full control over accessibility and responsive behavior.
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.
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle
glavweb/extra-bundle
glavweb/api-bundle
glavweb/admin-bundle
adachsoft/api-version-bundle
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
cgv/localized-resource