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

Blaze Bundle Laravel Package

happyr/blaze-bundle

Symfony bundle for integrating the Blaze templating engine. It registers Blaze services, wires template configuration into Symfony, and lets you render lightweight templates from controllers and services with minimal setup.

View on GitHub
Deep Wiki
Context7

Getting Started

1. Confirm compatibility before installing. The package now has a 2.0.0 release whose only stated change is "Adding support for Symfony 5 & Twig 3". That tells you the ceiling and the floor:

composer show happyr/blaze-bundle --all
composer why-not happyr/blaze-bundle ^2.0

Interpret it literally:

  • Symfony 5 is supported — and Symfony 5 has been end-of-life since November 2023. This is compatibility with a maintenance-only branch, not a forward-looking upgrade.
  • Symfony 6/7 are still not covered by the release notes. Do not assume 2.0.0 crosses that gap; check the require block in composer.json and the CI matrix on the tag before you commit.
  • It is a major version bump. Something was dropped to get here — almost certainly Symfony 3/4 support and possibly older PHP. If you are still on Symfony 4, you stay on 1.x.

Pin an exact version ("happyr/blaze-bundle": "2.0.0") rather than floating ^2.0.

2. Install and register the bundle.

composer require happyr/blaze-bundle:^2.0

Symfony Flex probably has no recipe, so register it manually in config/bundles.php:

return [
    // ...
    Happyr\BlazeBundle\HappyrBlazeBundle::class => ['all' => true],
];

3. Look at these files first. The package is small and lightly documented, so read the source rather than assuming the API. The 2.0.0 notes hint at a Twig integration — confirm it:

  • README.md — install and annotation syntax
  • composer.json — the real Symfony/PHP/doctrine/annotations constraints for 2.0.0
  • src/Annotation/Blaze.php — supported annotation properties (route, parameters, possibly name)
  • src/Service/Blaze.php — the getUrl() / getPath() methods
  • src/Twig/ or src/Extension/ — the Twig extension that justifies "Twig 3 support"; note the function/filter name and whether it is auto-registered
  • src/Resources/config/services.* — the actual service id and whether it is public/autowirable
  • src/DependencyInjection/ — whether there is configuration for the annotation reader

Use bin/console debug:container | grep -i blaze and bin/console debug:twig | grep -i blaze to find the real service id and Twig callable.

4. First use case: turn an entity into a route URL. The core idea is that an entity owns its route mapping:

// src/Entity/Post.php
use Happyr\BlazeBundle\Annotation\Blaze;

/**
 * @Blaze(route="post_show", parameters={"id" = "getId"})
 */
class Post
{
    public function getId(): int
    {
        return $this->id;
    }
}

Then inject the service and generate:

use Happyr\BlazeBundle\Service\Blaze;

class PostController extends AbstractController
{
    public function __construct(private Blaze $blaze)
    {
    }

    public function index(Post $post): Response
    {
        $url  = $this->blaze->getUrl($post);  // absolute URL
        $path = $this->blaze->getPath($post); // relative path

        // ...
    }
}

If autowiring does not resolve the service, alias it explicitly in config/services.yaml:

services:
    Happyr\BlazeBundle\Service\Blaze:
        alias: happyr.blaze

Verify the exact service id and method names in the bundle source before wiring this into many call sites.

Implementation Patterns

Entity-owned route mapping. The intended pattern is one annotation per entity, mapping route placeholders to getter methods. This keeps route knowledge close to the model and avoids repeating $this->generateUrl('post_show', ['id' => $post->getId()]) in every controller and template.

Override parameters at call time. Use the second argument for context-dependent values such as locale, page number, or slugs that are not direct getters:

$url = $this->blaze->getUrl($post, [
    '_locale' => $request->getLocale(),
    'page'    => 2,
]);

Confirm whether overrides replace or merge with the annotation mapping; the small service class is the source of truth.

Lists and index pages. The service is most useful in loops, where the route mapping would otherwise be repeated:

$urls = array_map(fn (Post $post) => $this->blaze->getUrl($post), $posts);

The cost per item is annotation metadata lookup plus the router. Cache the metadata if the bundle does not already do so.

Twig usage — check the shipped extension before writing your own. The 2.0.0 "Twig 3 support" note implies the bundle already registers a Twig extension. Find it, confirm its callable name in debug:twig, and use it directly:

<a href="{{ post|blaze_path }}">{{ post.title }}</a>

Only fall back to a thin wrapper if the extension turns out to be missing or too limited:

// src/Twig/BlazeExtension.php
public function blazeUrl(object $entity): string
{
    return $this->blaze->getUrl($entity);
}

If you wrote such a wrapper against 1.x, re-check on upgrade — you may now have two registrations for the same idea, or the bundle's extension may shadow yours.

Custom or third-party entities. The annotation approach requires editing the entity. For entities you do not own, or for polymorphic objects, create your own small resolver around the bundle service:

final class EntityUrlResolver
{
    public function __construct(private Blaze $blaze) {}

    public function url(object $entity): string
    {
        return match (true) {
            $entity instanceof Post   => $this->blaze->getUrl($entity),
            $entity instanceof Author => $this->blaze->getUrl($entity),
            default => throw new \InvalidArgumentException('Unsupported entity'),
        };
    }
}

Use this as the application-facing abstraction so replacing the bundle later is a one-class change.

Absolute vs. relative URLs. Use getPath() for links in HTML and getUrl() for emails, feeds, canonical tags, and API payloads. Absolute URL generation depends on the router's request context.

Testing. Mock or use Symfony's real UrlGeneratorInterface in tests. Assert the generated URL, not the internal annotation parsing. If you use the service in domain code, wrap it behind an interface so unit tests do not need a booted kernel.

Gotchas and Tips

A 2.0.0 that only says "Symfony 5 & Twig 3" is a compatibility patch, not a revival. Read that as minimum-viable maintenance: the package is alive enough to receive a version bump, not alive enough to track Symfony's current release line. Keep it pinned, keep it behind your own wrapper, and keep the fork option open — MIT licensing makes that easy.

The major bump is the breaking change. Before upgrading from 1.x, diff composer.json between the two tags (Symfony constraint, PHP constraint, doctrine/annotations) and read the CHANGELOG if one exists. Expect dropped Symfony 3/4 support and possibly dropped PHP 7.x. Run the full suite after upgrading; route generation failing silently is the usual symptom.

Annotations are still the mechanism. Symfony 5 supports annotations, so 2.0.0 is fine on that stack — but this also means there is still no PHP 8 attribute support. You cannot move @Blaze to #[Blaze] without patching the bundle. If your roadmap is Symfony 6/7 (where annotation routing is deprecated/removed), budget for replacing this package, not upgrading it.

Twig 3 specifics. Twig 3 removed several 2.x deprecations: the spaceless tag, filter/for edge cases, and stricter Twig\Extension\AbstractExtension signatures. If you forked or subclassed the bundle's extension, check getFunctions() return types and Environment argument types against Twig 3. Also confirm how the extension is registered — a bundle that predates Twig bundles may register it manually in the DI config rather than via prependExtension.

Route parameter mismatches fail at generation time. If the annotation maps id but the route expects post_id, or if a getter returns null, you will get a MissingMandatoryParametersException or a malformed URL. Cross-check with bin/console debug:router <route_name>.

Getter requirements. Mapped methods must be public, callable without arguments, and deterministic. A getter that returns an object without __toString() will fail during URL generation. Avoid mapping methods with side effects.

Annotation inheritance. Verify whether annotations on a parent class or mapped superclass are read. If not, annotate the concrete entity or move the mapping into your own resolver.

Cache clearing. Annotation metadata and the compiled container are cached. After changing an annotation, run bin/console cache:clear. In production, ensure the deploy clears cache; otherwise route changes appear not to take effect.

CLI, queue, and email context. Absolute URLs generated outside an HTTP request use the router's default context, which may be localhost. Configure router.request_context (host, scheme, base URL) in framework config, or pass the request context explicitly.

Locale and domain routing. If your routes are localized or host-based, the annotation mapping alone is not enough; pass _locale and ensure the router context has the correct host. Test generation in each supported locale.

Service id/autowiring uncertainty. Do not assume the class is autowirable just because it exists. Check debug:container, alias it explicitly, and prefer constructor injection over $this->get('happyr.blaze').

Do not leak internal identifiers. Generating URLs directly from entity getters can expose sequential IDs or internal route names. Use slugs or UUIDs where appropriate and keep authorization checks in the controller, not in URL generation.

Debugging checklist. Confirm the annotation is imported with the correct namespace, confirm the service id with debug:container, confirm the Twig callable with debug:twig, confirm route placeholders with debug:router, and log or dump the parameters passed to UrlGeneratorInterface::generate(). If the bundle swallows exceptions, temporarily decorate the service to trace the route name and parameter array.

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.
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core
nodisrupt/laravel-agent