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

Button Widget Laravel Package

friendsofvictoire/button-widget

Provides a configurable button widget for the Victoire CMS page builder. Editors insert call-to-action buttons and set labels, links, styles, and target options through a visual form, so no template edits or custom markup are required.

View on GitHub
Deep Wiki
Context7

Getting Started

This bundle is a single-purpose Victoire CMS widget: it adds a "Button" entry to Victoire's widget picker so editors can drop a styled CTA (label, link, target, maybe style variant) into any widget slot. It is not a standalone button library — it has no meaning outside a Symfony application already running Victoire. Confirm that first: if bin/console debug:router | grep victoire returns nothing, installing this bundle will get you nowhere.

Minimal sequence:

composer require friendsofvictoire/button-widget

Then register the bundle (FriendsOfVictoire\WidgetButtonBundle\FriendsOfVictoireWidgetButtonBundle) in app/AppKernel.php (Symfony 2/3, which is what Victoire's era implies) or config/bundles.php:

bin/console assets:install --symlink
bin/console cache:clear

Where to look first, in this order:

  1. vendor/friendsofvictoire/button-widget/Widget/ — the widget class. This file is the package: its @Widget annotation (name, icon, slot defaults) and its properties define everything an editor can configure.
  2. Resources/views/Widget/*.html.twig — the entire public rendering surface. Read this before you promise a designer anything.
  3. Resources/config/ — form type and service wiring, if the widget exposes one.

First use case: open a page in the Victoire editor, add a widget to a slot, pick "Button", fill in the label and pick a link through Victoire's link picker, save, view the page. That round-trip is the whole integration test — if it works, the bundle is wired correctly (assets, cache, annotation discovery, template).

Implementation Patterns

Editor-driven authoring. The normal workflow is 100% in the Victoire UI: editors create buttons per page slot, business entities (pages/templates) expose the widget's fields as part of their form. Treat the widget's properties as content schema — changing them later means migrating existing business entities.

Template override, not vendor edits. Copy the widget template into your app's override path and own it:

app/Resources/FriendsOfVictoireWidgetButtonBundle/views/Widget/button.html.twig
# Symfony 4/5: templates/bundles/FriendsOfVictoireWidgetButtonBundle/

This is where you attach your design system classes (btn btn--primary), add rel="noopener" logic, or wrap the anchor in a <span> for icon layout. Keep the block structure intact so Victoire's slot rendering and any inline-edit attributes survive.

Reuse via Victoire templates. Rather than re-configuring the same button on every page, place it once in a Victoire template business entity and inherit. This is the Victoire-native equivalent of a component and avoids duplicating link configuration across pages.

Link handling. The widget typically stores a Victoire Link entity rather than a raw URL string, so render defensively:

{% if widget.link is defined and widget.link %}
    <a href="{{ widget.link.url }}" target="{{ widget.link.target|default('_self') }}"
       {% if widget.link.target == '_blank' %}rel="noopener"{% endif %}>
        {{ widget.label }}
    </a>
{% endif %}

If you need the raw URL programmatically (sitemap, analytics, nav mirroring), read it from the business entity after render rather than re-parsing markup.

Styling as a field, not a fork. If the widget exposes a class/variant property, map it through a whitelist in the template ({% set variant = widget.style in ['primary','ghost'] ? widget.style : 'primary' %}) instead of letting free-text classes through — it keeps the CSS contract with your theme honest.

Extending fields. To add an icon picker or analytics ID, subclass the widget and override its form type + template in your own bundle, or copy the bundle in as src/Widget/Button and drop the composer dependency. Given the package size, forking is often the pragmatic answer; a subclass is cleaner only if you plan to keep the upstream package updated.

Gotchas and Tips

  • Unmaintained, near-zero adoption. Zero stars and zero dependents means no community safety net and probable Symfony 2.8/3.x assumptions (old annotation syntax, @Widget\Widget, no PHP 8 attribute support). Pin the version explicitly in composer.json, and expect fatal errors on modern PHP before anything else. Check the widget class for @ annotations before assuming the bundle will even load.
  • Missing widget in the picker is almost always cache or discovery, not code: clear the cache, verify the bundle is enabled, and confirm the annotation reader is scanning vendor/ (Victoire registers widget directories via a compiler pass — if you installed with --no-scripts or moved the bundle, discovery breaks silently).
  • Broken icon in the editor = assets not published. assets:install --symlink and check web/bundles/friendsofvictoirewidgetbutton/ exists.
  • Null link crashes. A freshly created widget, before the editor sets a link, may render an empty href or throw on widget.link.url. Guard it in the template as shown above; this is the most common runtime error with link-based widgets.
  • Never edit vendor/. Composer update silently reverts it, and the fix lands in a file nobody reviews. Override the template; fork only if you need entity changes.
  • Button labels are content, not translations. If the site is multilingual, Victoire's i18n applies at the business-entity level — a button configured on a template will share its label across locales unless you configure per-locale entities. Verify before handing to editors.
  • Debugging rendering: the Symfony profiler in the editor context plus {{ dump(widget) }} in the widget template is faster than reading Victoire's slot-resolution code. For discovery issues, inspect the container for the widget tag (bin/console debug:container --tag=<victoire widget tag>) — the tag name is visible in the bundle's compiler pass or Victoire core.
  • Extension points worth knowing: the widget template blocks (override), the widget form type (subclass/override), and Resources/public CSS/JS (published asset override in your own bundle). Those three cover virtually every customization this widget supports.
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.
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
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