idci/merge-token-bundle
The IDCI MergeTokenBundle adds merge-token support to Symfony applications, providing services and integration for defining, resolving, and applying tokens across content and data workflows.
Read the package before installing it. idci/merge-token-bundle is a Symfony bundle, not a Laravel package — there is no ServiceProvider, no extra.laravel block, and no facade, so composer require will not auto-discover or bootstrap anything for you. Day-to-day leverage in a Laravel codebase is almost always pattern-borrowing, not dependency adoption.
Minimal steps:
git clone the repo and read three files first: the *Bundle.php class (to see what services are registered), the DependencyInjection/ extension (to see config shape), and the token parser/resolver classes (the actual algorithm). That's usually the majority of the value.composer.json constraints (symfony/*, php) and run composer require --dry-run idci/merge-token-bundle in the Laravel app. Symfony bundles of this vintage commonly pin EOL stacks; a hard conflict with Laravel 10/11/12's Symfony 6/7 components is the likely outcome.config/bundles.php.Hello [[first_name]], your invoice [[invoice_number]] is ready → Hello Ada, your invoice INV-1042 is ready. Never start with customer-facing PDFs or contract generation.The single most important pattern: isolate the capability behind your own interface so the vendor code — or its absence — is a detail.
interface MergeTokenResolver
{
public function resolve(string $template, array $context): string;
}
Every call site depends on MergeTokenResolver, never on a vendor class. Then:
App\Support\TokenResolver) in a service provider. Its ~200–400 lines: a regex parser for the token syntax the bundle uses (confirm whether it's {{ token }}, [[token]], or %token% — read the parser, don't guess), a lookup against a typed context map, and a formatter hook for dates/currency.Mail::raw/PDF renderers. Do not resolve inside Blade directives — double-rendering and escaping ambiguity follow.invoice_number, first_name, due_date), rejecting anything else. This is both a security control and a documentation artifact.due_date knows it renders as d/m/Y; the template author doesn't specify format. This keeps templates dumb and the resolver testable.local/testing, throw on unknown tokens; in production, log and render a safe placeholder ([[invoice_number]] left visibly intact beats silent empty string).hash(template) + schema(context keys) — not by context values, which would explode the cache. Invalidate on template edit (a Template model saved observer is the natural hook).config/packages/merge_token.yaml, tag your custom resolver services, and add an integration test per resolver so a future dependency bump fails loudly.A useful migration sequence if you ever had adopted it: define the interface → POC vendor code behind it → reimplement in-house → swap the container binding (a one-line config change because call sites only know the interface).
Bundle suffix and IDCI-Consulting namespace are the tells. Expecting Artisan auto-discovery will waste an afternoon.{{ token }}, case sensitivity, trailing newlines).Hello [[first_name]] reaching a customer is the highest-probability embarrassment. Assert on it: a test that renders every template with a synthetic context and fails if any [[ or {{ survives. Gate it in CI.''. Throw (strict) or render a visible placeholder (lenient); never silently produce an empty string.html, text). Token merging is a classic injection surface when templates or values are user-supplied.config.yml the bundle expects must be re-expressed as config/merge_token.php and bound manually in a service provider.Bottom line for day-to-day use: read it once as prior art, then own a small, tested, allowlisted resolver behind your own interface. The feature is a few days of work; inheriting a Symfony bundle into Laravel is not.
How can I help you explore Laravel packages today?