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

Template Guesser Bundle Laravel Package

elnur/template-guesser-bundle

Symfony bundle that automatically guesses which template to render, so you don't have to wire template paths by hand. It applies naming conventions to pick the right view for a request, keeping controller code lean and templates predictable.

View on GitHub
Deep Wiki
Context7

Getting Started

Read this first: the package is a Symfony bundle, not a Laravel package. composer require elnur/template-guesser-bundle will fail or, worse, drag Symfony ~2.x constraints into your tree. Do not install it. What you leverage day-to-day is its idea: a naming convention that turns a controller class + method into a view name without you writing it. Read the guesser source once (it's a few dozen lines) and extract the mapping rules — that's the entire deliverable.

The rules to extract, adapted to Laravel:

  • App\Http\Controllers\Billing\InvoiceController@show → billing.invoice.show
  • Strip the Controller suffix from the class name.
  • Drop the App\Http\Controllers prefix; keep the middle namespace segments as dotted path segments.
  • Lowercase/kebab or snake-case each segment to taste (pick one and document it).
  • Strip an Action suffix from the method if you follow that convention.
  • Resolve the dot path against your normal resources/views loader, so billing.invoice.show means resources/views/billing/invoice/show.blade.php.

First use case: a single pilot controller. Implement a TemplateNameResolver service (or a trait on a base controller) that returns the guessed string, wire it into one controller for one action, and confirm the Blade file is found. Do not spread it to ten controllers until the convention is written down and tested. The point of the exercise is to reduce return view('...') boilerplate — measure that it actually does before rolling out.

Sanity check: if all you want is one line saved per action, stop here. The package exists to solve a bundle-era Symfony problem; in Laravel, explicit view() calls are already the convention and are greppable. Only build this if you have a real convention (bundle-style modular architecture, theming/overrides, or a legacy port) that benefits.

Implementation Patterns

1. Resolver service behind an interface. Bind a TemplateNameResolver interface in a service provider and implement the naming rules once. This gives you a single place to change the convention, a seam for tests, and a one-line rollback (delete the binding) if the experiment fails.

interface TemplateNameResolver { public function resolve(string $controllerClass, string $method): string; }

2. Base controller trait as the ergonomic front door. Controllers call $this->view($data) (no name required) which delegates to the resolver. Keep an explicit override: $this->view('custom.name', $data) always wins. This preserves the escape hatch and prevents the convention from becoming a trap.

3. ResponseFactory macro for call sites that aren't controllers. response()->guessView() is handy inside closures, form requests, and other places where you can't inject a base class. Note this loses the controller/method context, so the macro needs the current route action — pull it from Route::current()->getActionName() and pass it to the resolver. Useful, but keep it out of the hot path unless the controller trait is genuinely unavailable.

4. Resource-controller integration. Laravel's resource controllers already have a strong convention (index, show, create, store, edit, update, destroy). Your guesser should map these to billing.invoice.index, billing.invoice.show, etc., and for multi-word resources (LineItem) choose kebab-case (line-item.index) consistently. This is where the convention pays off most — it's the one place Laravel's own implicit conventions and the guesser line up naturally.

5. Nested resources and dotted paths. Decide early whether Billing\InvoiceLineItemController@show becomes billing.invoice-line-item.show (namespace flattening) or billing.invoice_line_item.show. Pick one, encode it in the resolver, and test it. Getting this "obvious" mapping wrong on day one poisons every view path downstream.

6. Override patterns for theming. If you're porting a bundle-style "app overrides package views" pattern, layer the resolver: try an app-level path first, fall back to the package path. This is the one scenario where the guesser genuinely earns its keep in Laravel — it's the same problem the Symfony bundle solves, just expressed in Blade.

Gotchas and Tips

  • Composer conflicts are real. Don't add it to composer.json even "just to look." Its Symfony ~2.x constraints will fight Laravel 9/10/11's underlying Symfony components. Read it as a reference implementation, cite it in your ADR, move on.

  • Silent misresolution is the failure mode. The guesser fails open: rename a controller and you render the wrong view, or 500 on a missing template, with no compile-time signal. Mitigate by (a) asserting the view exists in the resolver during local/dev and (b) always keeping the explicit view('name') escape hatch.

  • Static analysis can't see guessed strings. phpstan/IDE "go to view" won't trace a resolved string. If your team leans on IDE navigation, a resolver-based convention will feel like a regression. Either accept the trade or keep explicit calls in the controllers people grep most.

  • Two competing patterns are the real cost. Once half the controllers use the guesser and half use explicit view(), new engineers can't predict which. Enforce one pattern per module via a lint rule or code-review note, or the convention quietly dies.

  • Naming edge cases to unit test before rollout: Controller suffix stripping, Action suffix stripping, multi-word class names, acronyms (VATController), nested namespaces, and singular/plural resource naming. A dozen small tests over the resolver are the whole safety net.

  • Route::current() is null outside HTTP. If you use the ResponseFactory macro, guard against console/queue contexts and tests — return a meaningful error rather than a confusing null dereference.

  • Where the extension points are. The resolver interface is your extension point for custom mapping; the override parameter is your extension point for per-action exceptions. Anything beyond those two is scope creep — don't build a config file for a convention that should fit in a paragraph.

  • Benchmark is not the concern. Resolution is string manipulation + one class-name read; it will never be your bottleneck. The cost is cognitive: every new engineer must learn the mapping, and every controller inherits an invisible coupling between class name and template path. That cost scales with headcount, not traffic — factor it into the build-vs-buy call.

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.
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator
equipc/laravel-email-database-log
adedsec/nova-translated-labels
wazza/laravel-db-encryption
hokny/laravel-generator
vonsogt/backup
jengo/queues
jeremykenedy/laravel-observability
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums