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

Widget Bundle Laravel Package

evgeniy-it/widget-bundle

Widget Bundle brings MODX-style shortcodes to your CMS, parsing nested [[widget? &option=value]] tags through a Twig filter. Includes simple template-based widgets, Doctrine repository widgets, array settings, and nesting.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit

The first and most material finding: evgeniy-it/widget-bundle is a Symfony bundle, not a Laravel package. It ships as an EvgeniyIt\WidgetBundle\WidgetBundle-style bundle intended for registration in AppKernel/bundles.php, and exposes functionality through Twig — the README's only public entry point is the |widget filter ({{ some_string_var|widget }}). There is no service provider, no facade, no config publish tag, and no Laravel-style auto-discovery. So the "Laravel/PHP package" framing only holds in the narrow sense that both frameworks use Twig-adjacent templating and Composer; the integration surface does not exist.

What is potentially reusable is the shortcode engine itself: the [[widget_name? &key=\value` &arr=`[1,2,3]`]]` grammar, the nested-render resolution, and the "render settings into a template" behavior. That logic is framework-agnostic in principle, but it is packaged as a bundle and coupled to Symfony's container for widget discovery/registration. Extracting it is a port, not a configuration change.

Integration feasibility

Low-to-moderate, and asymmetric:

  • Syntax/feature fit — high. A MODX-snippet-style shortcode system mapped to a Twig filter is a reasonable content-authoring model, and the nested example ([[widget_name2? &setting2=\[[widget3]]`]]) shows a real recursive resolver, not just string substitution. If the product need is "let CMS editors embed parameterized components in body copy," the conceptual model is sound and portable to a Laravel Blade directive/Illuminate\Support\Str`-based macro.
  • Packaging fit — effectively zero for Laravel. Installing it and expecting it to "be ready to work" (the README's claim) will not happen on a Laravel app without a bridge layer that instantiates the bundle's services manually.
  • Version fit — unknown and likely hostile. Last release 2017-01-18 predates PHP 7.2 by a wide margin in ecosystem terms, so the constraint block almost certainly excludes PHP 8.x and modern Symfony; Composer will likely refuse resolution outright.
  • Runtime fit — the engine resolves a string to a rendered template, which implies runtime template loading from a path or inline string (README: "whether as a link or as a string"). That is a template-injection surface if untrusted authors can supply the template reference.

Technical risk

  • Abandonment (high). Zero stars, zero dependents, last release 2017, single-author, MIT. There is no maintainer response path, no security advisory channel, and no upgrade history to learn from. Any CVE in its dependencies or in its own parser is permanently ours to fix.
  • Adoption signal (high). 0 dependents is not a soft metric here — it means zero field-tested edge cases. The nested-shortcode grammar is exactly the class of feature that breaks on adversarial input (unbalanced backticks, ]] inside a value, deep nesting).
  • Parsing safety (high). A bracket-and-backtick-delimited grammar with recursion invites ReDoS or unbounded recursion if the resolver is regex-driven and depth-unbounded. This requires source review, which we cannot shortcut.
  • Quality evidence (medium). Maturity is listed as "readme, releases" — no test suite, no CI, no docs beyond the README. There is nothing to validate behavior against.
  • Licensing (low). MIT is clean and permits forking/vendoring, which is the mitigating factor for everything above.

Key questions

  1. Is the actual requirement shortcode-in-content, or specifically this grammar? If the former, we should evaluate maintained Laravel options (a Blade directive, a spatie/laravel-shortcodes-class library) before touching a 2017 orphan.
  2. Does the package even install against our PHP/Laravel baseline? This is a 15-minute composer require spike and should gate everything else.
  3. Is the parser extractable in isolation, or is it welded to the Symfony container for widget registration? This determines "fork" vs. "reimplement" — and reimplement is likely cheaper.
  4. Do content authors need arbitrary template-path rendering, or only inline templates? The former is a security decision, not a feature.
  5. Who owns the fork if we adopt it? A package with no upstream maintenance transfers 100% of the maintenance cost to us on day one.

Integration Approach

Stack fit

Partial. Twig is the shared substrate — if the target application uses Twig (Laravel can, via twigbridge, and Symfony natively), the |widget filter contract could survive a port. If the target is Blade (the Laravel default), there is no direct fit; the equivalent is a Blade::directive('widget', ...) plus a shared rendering service, which means we are writing the integration layer regardless.

Recommendation: treat the package as a specification and reference implementation, not a dependency.

Migration path

  1. Prove the concept against the README grammar only. Build a small fixture set from the documented examples (simple widget with &content, custom template, array/assoc-array settings, and the two-level nested case). These become the acceptance tests for whatever we build.
  2. Spike the original in a throwaway container. Attempt composer require on a pinned legacy PHP image purely to observe behavior — specifically recursion depth handling and how it treats ]] and backticks inside values. Do not ship it.
  3. Reimplement the resolver in-application (likely 200–400 LOC): tokenize the shortcode, parse &key=\value`` pairs with type coercion for [...]/{...}, resolve nested content bottom-up, and dispatch widget names through an explicit registry — an explicit allowlist, not container auto-discovery.
  4. Expose it through the framework-native surface: a Blade::directive (or Twig filter if Twig is in play) that delegates to the resolver service. Keep parsing and rendering as separate services so the renderer can be swapped.
  5. Preserve syntax compatibility. Keeping the [[name? &k=\v`]]` grammar means existing authored content (and any docs written against this bundle) remain valid, which is the only thing the package genuinely gives us.

Compatibility

  • Assume no compatibility with current PHP/Laravel/Symfony; treat any success as a bonus, not a baseline.
  • Pin nothing to the package. The reimplementation has zero transitive risk.
  • If a fork is chosen over a reimplementation, the fork must be renamed and namespaced (ourorg/widget-bundle), vendored or in a private registry, and explicitly documented as a permanent internal fork — not a temporary override.

Sequencing

Dependency audit spike → grammar fixture suite → build-vs-fork decision (default: build) → resolver implementation → framework adapter → author-facing docs and escaping rules → deprecation plan for any existing content. The grammar fixtures must land before the implementation so the decision is evidence-based.

Operational Impact

Maintenance

This is the dominant cost. Adopting the package as-is means acquiring an unmaintained Symfony-era codebase: we own PHP-version bumps, security review, and any framework-API drift, with no upstream to merge from. Reimplementing shifts the cost to a one-time build plus a small, readable surface we control — which is materially cheaper over a 2–3 year horizon. Either way, the "0 stars, 0 dependents, last release 2017" profile means the maintenance line item is not small and must be budgeted explicitly.

Support

No maintainer, no issue triage, no release notes to correlate against incidents. Internal support means the adopting team is the sole escalation path, and that must be named in the runbook. The reimplementation approach at least keeps the knowledge in-house by construction.

Scaling

Parsing and rendering are CPU-light per request and unlikely to be a throughput bottleneck. Two real scaling concerns:

  • Repeated work. If the filter runs on every page render over long bodies, parsed output should be cached keyed on the source string hash. The original has no evident caching layer.
  • Recursion depth. Nested resolution must be bounded (hard cap, e.g. 10 levels) or a pathological document becomes a self-inflicted DoS. This is a design requirement of the reimplementation, not a nice-to-have.

Template resolution also scales badly if it hits the filesystem per widget — resolve once, memoize per request.

Failure modes

  • Deep/malformed nesting → stack exhaustion or regex backtracking; bounded recursion plus a linear tokenizer mitigates.
  • Unbalanced delimiters (stray [[, backtick inside a value) → silent partial render or literal leakage into published content. Needs an explicit "unparseable, render literal" policy so authors see their syntax rather than a broken page.
  • Unknown widget name → the original would likely fail or render empty; the reimplementation should log and render a visible placeholder in non-production, degrade silently in production.
  • Template injection → arbitrary template reference from author-supplied content. Restrict to a configured template root; never accept absolute paths from content.
  • Supply chain → an abandoned package is an unpatched dependency by definition; only relevant if not reimplemented.

Ramp-up

Low for syntax — the README is sufficient for an author to learn [[name? &k=\v`]]` in under an hour, and the grammar is familiar to anyone who has used MODX or shortcode-style CMSes. Higher for engineering: anyone touching the resolver needs to understand the tokenizer's edge-case handling and the deliberate deviations from the original. Budget a half-day of onboarding for the resolver plus the fixture suite as living documentation. If the original bundle is adopted rather than reimplemented, add a multi-day ramp for the Symfony bundle internals — reading someone else's 2017 container wiring to fix a parser bug is the worst of both worlds.

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.
payerurl/telegrambot-crypto-payment-instant-payout
dskripchenko/laravel-hybrid-search
riorizkyrainey/lara-ced
mehedimi/static-vel
zharp/zharp
nonsapiens/bigquery-model-sync
lgu-bayambang-ict-office/lgu-laravel-development-standards
andydefer/laravel-support
se7enxweb/flysystem
lampwick/laravel
jeslage/statamic-emojis
micahdshackelford/rmap-laravel
draftsmaninc/draftsman
square-bit/laravel-volition
himito/laravel-mailman
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk