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

victoire/button-widget

A lightweight Laravel/PHP package from victoire that provides a reusable button widget for defining and rendering consistent action buttons in Blade views and UI components. Helps standardize button markup and simplify adding customizable buttons across your application.

View on GitHub
Deep Wiki
Context7

Getting Started

victoire/button-widget (Victoire\Widget\ButtonBundle) is a single-widget bundle for the Victoire CMS: it gives editors a "Button" widget (label + link + link behaviour) that can be dropped into a page slot in the Victoire backend and rendered on the front end. It is a content-type plugin, not a standalone library — nothing works without Victoire Core and WidgetBundle installed.

Minimal steps

  1. Check constraints before you start. Open the package's composer.json first. It is a 2019-era bundle and will pin php and symfony/* to 2.8/3.x ranges. If your app is Symfony 4+, Composer will refuse to resolve — in that case skip composer require and copy the bundle into src/ as a local scaffold instead (see Gotchas).
  2. Install into a Victoire project:
    composer require victoire/button-widget
    
  3. Register the bundle (app/AppKernel.php on Symfony 2/3):
    new Victoire\Widget\ButtonBundle\VictoireWidgetButtonBundle(),
    
    Register it after Victoire\Bundle\WidgetBundle\VictoireWidgetBundle so the widget tags/services resolve.
  4. Persist its entity. The widget extends Victoire's BaseWidget and has its own table:
    bin/console doctrine:schema:update --force
    # or, preferred: doctrine:migrations:diff && doctrine:migrations:migrate
    
  5. Clear caches and install assets (Victoire caches widget metadata and form types aggressively):
    bin/console cache:clear
    bin/console assets:install --symlink
    

Where to look first — five files tell you everything:

File Why
Entity/WidgetButton.php The persisted fields (label, url, target, style…). Extend here.
Form/WidgetButtonType.php The backend edit form. Extend here.
Resources/views/Widget/button.html.twig Front-end markup. Override here.
Resources/config/config.yml (or the bundle's DI Extension) Widget registration name/key.
Resources/translations/*.yml Backend field labels.

First use case: log into /admin, open a page, add a "Button" widget to a slot, fill in the label and link, save and publish. Confirm it renders. Then confirm the same button renders outside the CMS by rendering the widget from a Twig template, so you know both the slot path and the programmatic path work before you start customising.

Implementation Patterns

1. Extending the widget with your own fields. The bundle is best treated as a template for your own button. Add the property + ORM column on WidgetButton, add the field to WidgetButtonType, then render it in the template:

// Entity/WidgetButton.php
/** @ORM\Column(name="icon", type="string", length=63, nullable=true) */
protected $icon;
// Form/WidgetButtonType.php
$builder->add('icon', TextType::class, ['required' => false, 'label' => 'button.form.icon.label']);

Generate the migration with doctrine:migrations:diff — do not hand-edit the schema, because the base widget table is managed by Victoire Core and easy to corrupt.

2. Overriding the front-end template (preferred over editing vendor code). Symfony's bundle override still works here:

app/Resources/VictoireWidgetButtonBundle/views/Widget/button.html.twig

Copy the vendor template verbatim first, verify it renders identically, then customise. This keeps you upgradeable and makes the diff obvious when you later vendor the bundle.

3. Rendering a widget from your own templates. Always go through Victoire's renderer instead of doing {{ widget.label }} manually — the renderer applies the CMS wrapper (needed for inline editing in the backend) and the widget cache. Use the same helper Victoire's slot templates use (inspect VictoireWidgetBundle's Resources/views/ for the exact function name in your Victoire version, e.g. victoire_widget_render/render_widget). Rendering the entity by hand silently breaks edit-mode on that page.

4. Link handling. If your Victoire build exposes a page/link picker, use it so internal links survive page-slug changes; otherwise store an absolute/relative URL string and normalise it in the entity getter:

public function getUrl(): ?string
{
    $url = $this->url;
    if ($url && 0 !== strpos($url, '/') && !preg_match('~^[a-z][a-z0-9+.-]*:~i', $url)) {
        $url = 'https://'.$url;   // bare "example.com" typed by an editor
    }
    return $url;
}

5. Presentation is a field, not a template fork. Rather than creating a new template per button colour/size, add style/size choice fields and map them to CSS classes in button.html.twig. One template, N variants — much easier to maintain than five overrides.

6. Composing with other widgets. A button is usually the CTA inside a "Text", "Jumbotron" or "Card" widget. Victoire widgets can be nested/positioned within slots; if you need the button inside a parent widget, prefer placing it in the parent's slot in the backend rather than embedding one widget's template in another — nested widgets keep their edit handles, hardcoded includes don't.

7. Cloning as a scaffold. Because it is tiny and complete (entity + form + template + registration + translations), this bundle is a good copy-paste starting point for WidgetCtaBundle, WidgetBadgeBundle, etc. Rename namespace, entity table, bundle class, translation keys and the widget registration key together — see the rename gotcha below.

Gotchas and Tips

  • It's effectively abandoned. Last release May 2019, 2 stars, 0 dependents. Expect no Symfony 4/5/6 compatibility, no PHP 8 fixes, no security patches. If you must use it, fork/vendor it into src/ and own it:
    "repositories": [{ "type": "path", "url": "packages/button-widget" }]
    
    Then bump constraints yourself: getBlockPrefix() instead of getName() on the form type, Symfony\Component\HttpKernel\Bundle\Bundle unchanged, @= service syntax removed, Assetic removed.
  • getName() vs getBlockPrefix(). Symfony 2 form types use getName(); Symfony 3+ use getBlockPrefix(). If the backend form renders the button fields in the wrong place or as a nested widget_button_type fieldset, this is why — rename the method, don't delete it.
  • The widget registration key is load-bearing. The key in Resources/config/config.yml is what page/widget records reference. Renaming it after editors have created buttons orphans existing content (renders nothing, no error). Decide the name once; if you must rename, write a data migration over the widget table.
  • Doctrine inheritance traps. WidgetButton extends Victoire's BaseWidget; if you copy the bundle, also copy/adapt the Doctrine mapping file (Resources/config/doctrine/*.orm.xml) and the bundle class name. Mismatch between entity class, table name and registration produces the classic "widget type not found" or a blank slot with no exception.
  • URLs are user input. Escape label and URL in Twig ({{ widget.label }} is auto-escaped; href="{{ widget.url }}" is not safe against javascript: — validate in the form with a Url/Regex constraint) and add rel="noopener noreferrer" whenever target is _blank.
  • Cache after every template tweak. Victoire caches rendered widgets and Twig compiles templates by bundle; if your change "doesn't appear", run bin/console cache:clear and disable the Twig cache in dev, then verify you edited the overridden template and not the vendor one.
  • Backend form styling. Field labels come from Resources/translations/messages.*.yml; missing keys show the raw key in the admin. Add translations alongside every new field or the CMS UI looks broken to editors.
  • Debugging toolkit: bin/console debug:container | grep -i victoire to confirm services registered, bin/console config:dump-reference victoire_core (adapt the root key to your Victoire version) to see how widgets are registered, doctrine:mapping:info to confirm WidgetButton is mapped, and {{ dump(widget) }} inside the template to inspect actual field values.
  • Empty render? In order: is the bundle in the kernel? is the schema migrated (check the table exists and has your new columns)? is the widget key registered? is the template path exactly Widget/button.html.twig? Almost every "button not showing" bug is one of those four.
  • Don't fight the CMS wrapper. Victoire injects data-widget-id/edit-mode markup around widgets; replacing the whole template with a bare <a> can break inline editing and page caching. Keep the outer wrapper the bundle provides unless you know the renderer chain.
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.
skyraptor/chatter
edlugz/sasapay
abbasudo/artisan-route
mirvan/ippanel
ignibyte/aic-framework
glavweb/data-schema-bundle
glavweb/datagrid-bundle
tacticmedia/scim-server
uni-method/frame
neika-ai/sdk
adachsoft/php-code-style
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
adachsoft/api-version-bundle
cgv/localized-resource