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

View Laravel Package

aura/view

Aura.View implements the TemplateView and TwoStepView patterns using PHP itself as the template language, with file-based and closure templates, helpers, and sections. No runtime dependencies; requires PHP 8.4+.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture Fit

  • Release Status — 7.0.0 Is Now Stable (GA): The published 7.0.0 carries forward the beta1 notes verbatim with no code changes. Our evaluation therefore holds unchanged, and the residual "beta may still move" risk is retired. This is a risk reduction, not a scope change — no new engineering work is implied beyond what was already scoped.
  • TemplateView & TwoStepView Patterns: Still an optional, PHP-native alternative to Blade for teams needing dynamic template logic without Blade's syntax (legacy ports, CLI output, non-HTML media types, shared libraries across frameworks).
  • No Runtime Dependencies (unchanged): Confirmed again — still zero runtime deps, still no escaper by design (media-type agnostic). Escaping remains an explicit consumer responsibility.
  • Decoupling Story Improved: The release adds real seams that matter for framework integration:
    • TemplateRegistryInterface (set/has/get) and SearchPathInterface (getPaths/setPaths/prependPath/appendPath/setNamespaces/hasNamespace/getNamespaces/getNamespacePaths/setTemplateFileExtension) — a framework can now substitute a module-aware registry without subclassing TemplateRegistry. Previously setTemplateRegistry() type-hinted the concrete class. Note the deliberate split: path management is not on TemplateRegistryInterface, so a precompiled name-to-file registry remains a valid substitution.
    • HelperRegistryInterface — but the View deliberately does not type-hint it (helpers reached only via __call(), parameter typed ?object), so Aura.Html's HelperLocator wiring keeps working with no adapter. This is a compatibility win for existing installs and removes an adapter from our integration surface.
  • parent() — Template Inheritance for Overrides (new capability): Search paths are first-hit-wins, so a shadowed template was previously unreachable. parent() resumes the search past the current template's directory. This is the single most TPM-relevant feature: package/theme overrides no longer require copying whole files — only the diff. Directly applicable to multi-brand or vendor-package template customisation, and the one feature here with a measurable engineering-hours payback.
  • Registry Now Normalises Callables to \Closure (breaking, previously unassessed): TemplateRegistry::get() returns \Closure, and non-closure callables passed to set() are coerced so the View can bindTo() them. This fixes a latent bindTo() failure for array callables — but it changes stored identity (new finding, added this review). Consequences we must check: anything comparing registry entries by identity (=== on the callable), type-checking for Closure, or serialising/caching the registry (var_export, config-cache style persistence) now breaks, because closures are not serialisable. This is the only release-note item our prior assessment did not cover.
  • Config/DI Coupling Removed (breaking): config/Common.php, the extra.aura block, the Aura\View\_Config\ PSR-4 entry, and the aura/di dev dependency are gone (the config extended an Aura\Di\Config that no longer exists). Wiring is now explicitly the consuming framework's job — neutral-to-positive for Laravel (we never used Aura.Di) but it removes any auto-discovery surface and means our service provider owns all wiring.
  • Licence: MIT, changed from BSD-2-Clause — strictly more permissive, and all 12 src/** headers plus composer.json are consistent. Clears legal/procurement review faster for redistribution or embedding; copyright 2011-2026, Aura for PHP.

Integration Feasibility

  • Laravel Compatibility:
    • Low friction as a sidecar, high friction as a replacement. The package is installable and callable from a Laravel service provider, but Aura\View\ViewFactory does not implement Illuminate\Contracts\View\Factory (no make(), exists(), share() semantics). Aliasing the contract to Aura's factory — as earlier drafts of this assessment suggested — is not viable; it would break every Blade/view() call site.
    • Recommended shape: bind an AuraRenderer service, inject it into the specific controllers/jobs that need it. Coexistence with Blade, not substitution of Laravel's view layer.
    • Data binding: setData() vs View::share(); still manual escaping (no auto-escape, unlike Blade).
    • Layouts/Sections: beginSection()/getSection() map to @section/@yield, but with raw PHP control flow.
  • Signatures (breaking for extenders only): Native parameter and return types throughout under declare(strict_types=1). Direct callers are unaffected; subclasses fatal on load if their overrides don't match.
  • ViewFactory::newInstance() (breaking): The four flat positional arguments collapse into two ViewSpec objects (map, paths, namespaces, extension grouped per registry). newInstance() and newInstance($helpers) are unaffected — only the long form breaks, with a \TypeError naming the parameter.
  • HelperRegistryInterface::set() Gains an override Parameter (breaking for implementors): Anyone who already implements that interface — including internal test doubles or a framework-specific helper registry — must widen the signature. Cheap, but it is a load-time break, not a runtime one.
  • PHP Floor (breaking): ^8.4, up from >=5.4.0. This is the dominant integration constraint — see risk below.
  • Performance: Unchanged — no compilation, no template cache. Runtime execution of closures/PHP templates versus Blade's compiled views. Lightweight (~10KB).
  • Tooling: Unchanged — native IDE support, mockable View for unit tests, no Blade plugins required.

Technical Risk

  • PHP ^8.4 Requirement (highest-severity): Hard floor. Laravel 10 (8.1–8.3) is excluded; Laravel 11/12 support 8.4 but only if our runtime is actually 8.4. Any environment pinned to 8.2/8.3 cannot take 7.x and cannot take 2.x alongside a modern Laravel either. This makes the package viable only where we control the PHP runtime.
  • Ecosystem Gaps:
    • No Blade compatibility — cannot consume Blade templates, components, or Livewire.
    • No built-in cache — mitigated by OPcache only.
    • No escaper shipped — deliberate and reaffirmed, so the XSS surface is a permanent design property, not a bug awaiting a fix.
  • Registry Closure Normalisation (new finding): Array callables become closures; get() always returns \Closure. Breaks identity comparisons, is_array()-style checks, and any attempt to serialise or export the registry (closures cannot be serialised). If we were tempted to cache a resolved registry to disk for boot speed, that door is now closed — we cache at OPcache level only. Low likelihood in a Laravel integration, but it is a boot-time failure if present.
  • Subclass Breakage: If any of our code extends View, TemplateRegistry, or implements HelperRegistryInterface, the strict-types change is a boot-time fatal, not a page-level 500. Must be audited before upgrade.
  • Helper Registration Now Strict: HelperRegistry::set() throws HelperAlreadyRegistered on collision (including registering the identical callable twice). Good for detecting multi-package collisions that were previously silent last-one-wins; bad for any boot sequence that registers without an owner. override: true is the escape hatch and is not an error when the name is free — so asserting our own helper without probing first is safe; use has() only when you need to branch.
  • Silent Empty Render: Invoking a View with no template set returns '' (layout-wrapped) instead of throwing TemplateNotFound — the old behaviour is not expressible under strict types. Misconfiguration surfaces as a blank page rather than an error; needs a lint/assert step.
  • Exception Hierarchy Now Uniform (improvement): Every exception descends from Aura\View\Exception; InvalidTemplateName (name parsing) and HelperNotFound (unresolvable helper, replacing a raw PHP Error) are explicit. InvalidHelpersObject is deprecated (never thrown — the ?object parameter means PHP's own \TypeError fires first) and slated for removal in 8.0 — existing catch blocks still resolve but should be dropped.
  • Setters Are Not Fluent (breaking): Setters return void. Any chained call ($view->setData(...)->setLayout(...)) now fatals. Mechanical grep, but must be in the upgrade checklist.
  • Long-Term Viability — Revised Upward, Now Settled: The earlier "last release 2022 / no active maintenance" finding is superseded. A stable 7.0.0, copyright through 2026, a stated 8.0 deprecation path, and an unchanged beta→GA cut all indicate a project that is alive and deliberately modernised rather than churning. Note the version jump 2.x → 7.x is cosmetic — there is no 3.x–6.x — so composer constraints pinned to ^2.0 will not see it.

Key Questions

  1. Runtime Timeline: What is our PHP 8.4 rollout date, and which Laravel major are we on? 7.x is a non-starter until 8.4 is the floor everywhere.
  2. Subclass & Interface Inventory: Do we extend View, extend TemplateRegistry, or implement HelperRegistryInterface / SearchPathInterface anywhere? This determines whether the upgrade is a config change or a code change — and the interface implementations must now also accept set(..., override: …).
  3. Registry Persistence: Does anything serialise, var_export, or disk-cache the template registry? Closures make that impossible as of 7.0.0; caching stays at OPcache level.
  4. Use-Case Justification: Is the driver decoupling, non-HTML output (PDF/email/CLI), or parent()-based template overrides? If it's "replace Blade," the answer is no.
  5. Escaping Strategy: What enforces escaping — a wrapper trait, a CI lint, or Aura.Html's escapers? "Developer discipline" is not an answer.
  6. Helper Ownership: If more than one module registers helpers, who owns each name, and where is override: true permitted?
  7. Template Override Scope: Does our theming/multi-brand need require parent(), or is copy-and-replace acceptable? (Quantify: how many vendor templates do we currently fork, and how many lines do we actually change?)

Integration Approach

Stack Fit

  • Best For:
    • APIs/CLI/Jobs: dynamic non-HTML output without Blade's HTML assumptions.
    • Legacy ports: PHP apps with bespoke templating being brought under Laravel incrementally.
    • Package/theme overrides: where parent() lets us carry only the diff.
    • Shared libraries: rendered both inside and outside Laravel (no container coupling).
  • Poor Fit:
    • Frontend-heavy apps — Blade ergonomics and component ecosystem win outright.
    • High-traffic HTML rendering — no template cache; Blade's compiled views outperform.
    • Any environment below PHP 8.4 — hard block in 7.x.

Migration Path

  1. Hybrid Adoption (recommended end state, not a stepping stone):
    • Step 1: Introduce Aura.View for non-Blade surfaces only — transactional emails, PDF generation, API payload rendering, CLI reports.
    • Step 2: Adopt parent() for the surfaces where we currently copy a vendor template to change two lines.
    • Step 3: Do not replace Illuminate\Contracts\View\Factory. Keep Blade authoritative for HTTP HTML.
  2. Wiring (corrected for 7.x):
    // app/Providers/AuraViewServiceProvider.php
    public function register(): void
    {
        $this->app->singleton(AuraRenderer::class, function ($app) {
            $factory = new \Aura\View\ViewFactory();
    
            return new AuraRenderer($factory->newInstance(
                $app->make(HelperLocator::class),        // Aura.Html — no adapter needed
                new \Aura\View\ViewSpec(map: $viewMap, paths: $viewPaths),
                new \Aura\View\ViewSpec(map: $layoutMap, paths: $layoutPaths),
            ));
        });
    }
    
    Note the ViewSpec form — the 2.x four-flat-argument call produces a \TypeError. newInstance() / newInstance($helpers) still work unchanged for trivial cases.
  3. Template Conversion:
    Blade Directive Aura.View Equivalent
    @foreach foreach ($this->items as $item)
    @section $this->beginSection('name') (must be paired; unpaired endSection() throws)
    @include('partial') $this->render('partial')
    @yield $this->getSection('name')
    @extends layout registry + parent() for shadowed templates
  4. Data Binding: setData() replaces View::share(); use a ViewHelper wrapper as the single escaper entry point. Setters are not chainable — call them on separate lines.
  5. Helper Registration Convention: Register with an explicit owner; only the owning module uses override: true. Treat HelperAlreadyRegistered as a CI signal, not a runtime nuisance — it is the mechanism that surfaces the collisions we previously could not see.

Compatibility

  • Laravel: Coexists via a dedicated service binding. Contract aliasing is out (see Integration Feasibility).
  • PHP: ^8.4 only. Verify against the Laravel major in use before scheduling.
  • Third-Party: Aura.Html for escapers/helpers remains the documented pairing and is unchanged by 7.0.0 — explicitly called out in the release notes as continuing to work without an adapter.
  • Composer Constraints: Update any ^2.0 pin; there is no 3.x–6.x to step through, so 2.x → 7.x is a single jump.
  • Exception Handling: Re-target catches from \InvalidArgumentException to Aura\View\Exception\InvalidTemplateName; catch HelperNotFound where helpers are dynamic; drop InvalidHelpersObject catches ahead of 8.0.

Sequencing

  1. Phase 0 — Gate: Confirm PHP 8.4 across all target environments. No further work until true.
  2. Phase 1 — Audit: Grep for extends .*View, implements HelperRegistryInterface, implements SearchPathInterface, chained setters (set…->), newInstance( with more than two arguments, array-callable registration passed to TemplateRegistry::set(), and any registry serialisation/export.
  3. Phase 2 — Pilot: One non-critical surface (PDF or email), full wiring, escaper wrapper established.
  4. Phase 3 — Override Use Case: Apply parent() to a real vendor-template override and measure the diff reduction.
  5. Phase 4 — Steady State: Aura.View stays scoped to non-HTML; Blade remains the HTTP view layer.

Operational Impact

Maintenance

  • Pros:
    • No compilation step — no php artisan view:clear equivalent, nothing to rebuild in CI.
    • Pure PHP templates — stack traces point at the template line directly.
    • MIT licence — no redistribution friction; header and manifest are consistent.
    • Uniform exception hierarchy — one catch surface for all package errors, with InvalidTemplateName and HelperNotFound explicit.
    • Stable GA release — no beta tracking risk; 7.0.0 is what beta1 shipped.
  • Cons:
    • Manual escaping — permanent by design; highest ongoing XSS exposure.
    • No template cache — we own caching (OPcache, or a bespoke layer) if volume demands it; registry-level caching is now off the table (closures).
    • No auto-wiring — the removal of config/Common.php and extra.aura means the service provider is the sole source of truth; nothing is discoverable.
    • Helper registry is now strict — boot fails loudly on collisions; requires a deliberate ownership convention across packages.
    • Version-line confusion — 2.x → 7.x with no intervening majors; expect reviewers to ask "what did we miss in 3–6?" (answer: nothing).

Support

  • Documentation: README-led, plus an Escaping Output section referenced directly in the release notes. Still no Laravel-specific guide — our internal runbook is the real documentation.
  • Community: Small (sub-100 stars), but the 7.0.0 GA release materially weakens the "abandoned" assessment: active modernisation, a stated 8.0 deprecation path, and a 2026 copyright. Support volume remains low; expect to self-serve.
  • Debugging: PHP-native traces are clear. Watch for two silent-by-default behaviours — empty render on unset template, and namespace paths only discoverable through the new getNamespacePaths() getter (which returns [] rather than throwing for an unregistered namespace; hasNamespace() distinguishes "unregistered" from "registered but empty").

Scaling

  • Performance: Runtime execution on every request; Blade's compiled views will win on hot HTML paths. Do not place Aura.View on the highest-QPS HTML route.
  • Mitigations: OPcache (mandatory on 8.4), precomputed data, and keep closure-based templates out of loops — closures increase memory.
  • Concurrency: Stateless by design, no shared cache to contend on.
  • Footprint: ~10KB, no dependencies — negligible.

Failure Modes

Risk Impact Mitigation
XSS via unescaped output High — permanent design property Single escaper wrapper (ViewHelper), Aura.Html locators, CI grep for raw <?=
PHP < 8.4 in any environment High — hard boot failure on install Phase 0 runtime gate; pin composer platform config
Subclass signature mismatch High — fatal on class load, not page-level Phase 1 audit; add types to every override
Interface implementor signature drift (HelperRegistryInterface::set() gains override) High — fatal on class load Audit implementations; widen signature with the third parameter
Helper name collision at boot Medium — application fails to start Designate an owner per helper; override: true only where intentional
Registry callable identity / serialisation (new) Medium — closures break ===, is_array(), and disk caching Stop treating registry entries as data; cache via OPcache only
Chained setter call Medium — fatal (void return) Grep set->*->; setters on separate lines
newInstance() long positional form Medium — \TypeError naming the parameter Migrate to ViewSpec
Empty render on unset template Medium — blank output masks misconfiguration Assert template set in the wrapper; smoke test renders
endSection() without beginSection() Low–Medium — now throws Mechanical fix; caught in test
Template not found Medium — runtime error Validate paths in the registry at boot
Unresolvable helper Medium — now HelperNotFound instead of raw PHP Error Catch the package exception at the render boundary
InvalidHelpersObject catch retained Low — dead code, removed in 8.0 Drop catches now
Team adoption resistance High — Blade familiarity Cheat sheet (Blade → Aura.View), scoped to non-HTML surfaces so Blade skills stay relevant

Ramp-Up

  • Onboarding:
    • 1–2 Days: ViewFactory, ViewSpec, templates, setData().
    • 3–5 Days: sections, layouts, helpers, parent()-based overrides, escaping discipline.
    • +1 Day: 7.x specifics — strict types, void setters, interface substitution, closure-normalised registry, exception hierarchy.
  • Training Needs:
    • Escaping as a first-class habit, not an afterthought.
    • Where Aura.View is allowed (non-HTML) versus Blade (HTTP HTML) — the boundary must be written down or it will erode.
    • Helper-namespace ownership convention for anyone adding a module, including when override: true is legitimate.
    • For maintainers only: the registry returns closures and is not serialisable — do not attempt to persist it.
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.
gmostafa/php-graphql-client
xeviant/paystack
snowsoft/faker
meditationsteps/blogetc
animalyoung/laravel-influxdb
onix-solutions/sms-telera
lonely-lights/prosetta
oxygen/data
oxygen/core
jengo/base
xiloryx/log-collector
a21ns1g4ts/filament-stripe
la-php/laravel-admin
artisan-build/community-prompts
vleroy/smart
ayles-software/laravel-australian-public-holidays
cboxdk/laravel-id-spatie
cboxdk/laravel-id-billing
cboxdk/laravel-id-billing-bridge
simple-as-fuck/php-performance-log