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

Presenter Laravel Package

laracasts/presenter

A lightweight presenter layer for Laravel that wraps your models and exposes clean, dedicated methods for formatting and displaying their data. Keep view logic out of models and controllers, with simple, testable presenter classes.

View on GitHub
Deep Wiki
Context7

Product Decisions This Supports

  • Formatting and copy changes become a one-line edit instead of a template audit. Today the same entity — User, Order, Post — gets formatted independently in every Blade view, mail template, admin screen, and export. Name concatenation, currency, date locale, excerpt truncation, PII masking, default avatars. Each of those is a place a stakeholder-visible bug can appear. A presenter is one canonical definition per entity, which directly reduces the recurring "value looks wrong on screen after a release" defect class and its QA and hotfix cost.
  • Multi-surface consistency as a product requirement. The moment the same entity appears in web, transactional email, admin, PDF/export, or a future mobile/partner surface, "how is this displayed" needs exactly one answer. This is the cheapest available way to guarantee that.
  • Cheap optionality for an API-first or headless roadmap. If a SPA, mobile app, or partner integration is on the horizon, presenters create a seam where display logic already lives, so it can later be wrapped by Laravel API Resources without rewriting controllers and views. It buys optionality; it does not commit you to a serialization strategy.
  • Build vs. buy — buy, but treat it as vendored code. The abstraction is roughly a Presenter base class plus attribute proxying via a trait. In-house is genuinely feasible. The case for the package is MIT license, zero dependencies, no service provider, no config, no migrations, and an auditable surface one engineer can review in an afternoon. There is no lock-in; do not evaluate it like a vendor relationship.
  • Testability as a quality lever. Presentation logic becomes unit-testable PHP instead of untestable template logic — coverage on a layer that is currently effectively untested, at near-zero cost.
  • Team scaling. A named app/Presenters convention gives new engineers an obvious home for display logic, reducing senior review burden and review-cycle churn.
  • What this must not be used for: it is not an architecture decision, not a platform bet, and not a substitute for domain rules or authorization. It belongs inside feature work as an implementation convention and should never appear as a roadmap initiative or a funded refactor.

Recommended decision-log entry: approve as a low-cost engineering convention, scoped to a pilot on 1–2 high-complexity models, with a one-page convention doc and a testable success criterion (measurable reduction in conditional formatting logic in those templates). Do not fund a broad refactor, and do not sequence it alongside a framework major upgrade.

When to Consider This Package

Adopt when:

  • Presentation complexity is visibly growing: nested relationships, conditional formatting, computed display fields, or the same entity rendered in several places with subtly different output.
  • Controllers and Blade are accumulating formatting logic, or code review repeatedly flags "this doesn't belong in the view."
  • More than one output channel exists or is planned (web + email + export + API), so a shared presentation layer pays for itself quickly.
  • The team is on Laravel 8–13 and comfortable with framework conventions. Release history (0.2.2 → 0.2.9) is essentially Laravel-version compatibility bumps from 6 through 13, so it tracks the framework predictably — but that is also the entirety of upstream activity.
  • You want a dependency with no operational footprint: no services, queues, storage, migrations, or published config.

Look elsewhere when:

  • The product is simple CRUD with minimal formatting — a handful of Blade helpers is cheaper to own than a new convention.
  • The product is API-only, or the primary consumer is a frontend app. Laravel's built-in API Resources (or spatie/laravel-data) is the better fit; presenters solve a display problem, not a serialization problem.
  • You need typed DTOs, validation-on-hydration, or transformation pipelines.
  • The need is client-side reactivity or locale switching without a reload — solve that in the frontend.
  • You require a vendor with a support contract, active feature development, or a large dependent ecosystem. Be honest in the memo: 863 stars, 0 reported dependents in metadata, upstream activity limited to compatibility bumps. That is acceptable for a ~30-line abstraction; it is not a strategic dependency. (The zero-dependents figure is almost certainly a metadata gap — don't cite it as a health signal either way without checking Packagist install stats.)
  • The team can't absorb another abstraction or won't enforce the convention. An unenforced presenter layer becomes a second, inconsistent home for formatting and is strictly worse than the status quo.

Guardrails to set up front, or the pattern degrades: presenters hold formatting only — never authorization or business rules; eager-load relations before presenting to avoid hidden N+1s; one presenter per model; presenters don't call other presenters; add @property PHPDoc on every presenter and gate CI with PHPStan, since magic-method proxying is opaque to static analysis; and write an explicit accessor-vs-presenter rule so two formatting mechanisms don't silently compete.

How to Pitch It (Stakeholders)

For executives (one paragraph):

We're proposing a small, no-cost engineering convention for how our Laravel app formats data for display. Today that logic is scattered across page templates and controllers, which is why display bugs recur and why minor copy or format changes require touching many files. Consolidating it into dedicated, testable classes makes those changes faster and safer, keeps our web pages, emails, and any future mobile or partner interface consistent, and lowers onboarding cost for new engineers. The package is MIT-licensed, has no dependencies, adds no infrastructure, and integrates in under a day. This is a tactical quality improvement inside existing feature work — not a new platform, not a line on the roadmap — and we're recommending a scoped pilot on two models before any wider rollout.

For engineering (the substance):

laracasts/presenter gives us a Presenter base class so display logic moves out of controllers and Blade into app/Presenters. Instead of Str::limit($post->body, 200) and $post->created_at->format('M d, Y') repeated across templates, we write $post->present()->excerpt and $post->present()->formattedDate once and reuse them everywhere. Benefits: one place to change a format, unit-testable presentation, and a clean seam if we later move to API Resources. Costs: one new class per non-trivial model, a naming convention we must actually enforce, a documented accessor-vs-presenter rule to avoid competing mechanisms, @property annotations plus PHPStan to keep static analysis usable, and a real N+1 risk if presenters touch unloaded relations — so eager-loading becomes part of the convention. The package is tiny and stable but not actively developed beyond Laravel compatibility bumps; since we could rewrite it in an afternoon, that's an acceptable risk. Pin ^0.2, treat it as a thin internal utility rather than a dependency we design around, and write down the copy-into-app/Support escape hatch rather than assuming it. Proposal: pilot on User and Order, document the convention in the repo, and measure whether conditional logic in those templates actually drops. If it doesn't, we stop there — the sunk cost is about a day.

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.
mehedimi/laravel-amp-mail
happones/laravel-vue-i18n-generator
jwerd/inertia-table
siberfx/flysystem-wasabi
hollyit/token-replace
ippanelcom/laravel-sdk
adachsoft/changelog-linter
adachsoft/collection
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