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

Data Grid Bundle Laravel Package

makoso/data-grid-bundle

Makoso DataGridBundle provides a reusable data grid for Symfony applications, with configurable columns, sorting, filtering, pagination, and Twig-rendered tables. It helps add searchable, paginated admin lists without custom table code.

View on GitHub
Deep Wiki
Context7

Getting Started

First, the framing: despite the "Laravel developer" lens, makoso/data-grid-bundle is a Symfony bundle, not a Laravel package. There is no service provider, no facade, no config/data-grid.php to publish, and Laravel's package discovery will not find it. Composer will pull in symfony/http-foundation, symfony/dependency-injection, and likely twig/twig as hard requirements. As of v0.2.7, treat symfony/http-foundation's session component as part of the assumed runtime surface too.

What changed in v0.2.7: a single bullet — "Add option to save filters in session." That is a feature addition, not a breaking change: the behaviour is opt-in, so a default-configured grid is still request-driven. But it is the most architecturally significant line in the package's history for porting purposes, because the bundle is no longer purely a function of the current request. It now (optionally) reads and writes session state, which means it needs a live SessionInterface, a RequestStack, and — in a Symfony app — the session service to be wired before the grid is used. Update your portability analysis accordingly.

Minimal steps to evaluate it for a Laravel codebase:

  1. composer require makoso/data-grid-bundle --dry-run and read the dependency tree. If it pins Symfony 4/5 components, you have your answer before writing a line of code. Check specifically whether symfony/http-foundation was bumped in v0.2.7 or left at its 2020 constraint.
  2. Read composer.json require and require-dev first, then src/ — the README is thin, the changelog is one line per release, and there is no evidence of dependency bumps or PHP 8.2/8.3 work in this release, so the source is the documentation.
  3. Look for the bundle's service definition file (Resources/config/services.xml or config/services.yaml) and now also DependencyInjection/Configuration.php — the new session option has to be declared in a config tree somewhere, and that file tells you exactly what is toggleable and what the default is.
  4. Identify whether the grid core is framework-agnostic. If the sorting/filtering logic only depends on Symfony\Component\HttpFoundation\Request and a query builder interface, it is portable. If it is welded to Doctrine ORM QueryBuilder, Twig, and now SessionInterface, it is not. Grep for SessionInterface, RequestStack, and getSession() before you decide.

Where to look first: the grid builder and the column type classes. Those two are the entire conceptual payload of a data-grid bundle — everything else is plumbing. For v0.2.7 specifically, find where the filter array is read from and written to the session; that single method is the whole change and it is also the thing you would most want to copy.

First realistic use case in Laravel: treat this package as a design reference, not a dependency. The pattern it encodes — declare columns once, derive sorting/filtering/pagination from the request, optionally persist filter state, render a table — is exactly what you would build with an Eloquent builder plus a Blade component in about 150 lines. Copy the idea, not the package.

Implementation Patterns

Concept mapping (if you decide to port rather than install):

Bundle concept Laravel equivalent
Symfony\HttpFoundation\Request Illuminate\Http\Request
Doctrine QueryBuilder Illuminate\Database\Eloquent\Builder
Twig datagrid_render extension Blade component / @component
Symfony DI service Container binding or constructor injection
Bundle config tree config/data-grid.php
Session-persisted filters (v0.2.7) session()->get/put('grid.filters.{name}')

Pattern 1 — Thin adapter (only if a hard requirement forces it). Bind Laravel's request into a Symfony Request via Request::createFromGlobals() or by constructing one from $request->query() and $request->all(). Instantiate the grid object manually (the Symfony DI container is not available), pass the adapter request, and render through a Blade view that mirrors the bundle's Twig template. This works for a read-only listing page and nothing more — CSRF and middleware are outside the bundle's model. If you enable the v0.2.7 session option, Pattern 1 gets materially harder: Laravel's Illuminate\Session\Store is not a Symfony\Component\HttpFoundation\Session\SessionInterface, so you need a small bridge class implementing get/set/has/remove/all over the Laravel store, and you must attach it to the Symfony Request you construct ($request->setSession($bridge)). That is real code with real failure modes — a session key collision or a non-serializable filter value will surface as a silent no-op. If you are not enabling the option, skip the bridge entirely and keep the adapter request stateless.

Pattern 2 — Reimplement the pattern (recommended, and now more clearly so). Mirror the bundle's public API so a future drop-in replacement is trivial, and adopt the session-persistence idea deliberately rather than inheriting its implementation:

  • One grid definition class per resource (App\Grids\OrdersGrid), exposing columns(), defaultSort(), apply(Builder $query, Request $request): Builder, and — new — persistFilters(): bool plus a stable sessionKey().
  • Column objects carrying key, label, sortable, filterable, and an optional formatter closure.
  • Query-string conventions matching the bundle's (sort, direction, page, filters[...]) so bookmarks and frontend code stay stable if you ever swap implementations. Session persistence must be a fallback, not a replacement — see gotchas.
  • A single <x-data-grid :grid="$grid" /> Blade component handling the header sort links and pagination.
  • A tiny FilterState value object with fromRequest(), fromSession(), toSession() so the persistence logic is testable without HTTP.

Pattern 3 — Sidecar service. If you already run a Symfony service alongside your Laravel app, keep the bundle there and expose the grid as JSON over HTTP. This preserves the dependency's value without contaminating the Laravel app's dependency graph. Caveat for v0.2.7: session-based filter persistence is a poor fit for a JSON API. Token-authenticated clients have no cookie jar to carry the session, and per-session filter state makes responses non-cacheable and non-idempotent from the client's point of view. If you use this pattern, leave the session option off and keep filters in the query string.

Integration tips:

  • Prefer query-string state; use session persistence only as a memory of the last filter set for UI convenience, never as the source of truth for a shared/bookmarked URL. Encode both: read query string first, fall back to session.
  • Whitelist sortable and filterable columns in the grid definition; do not let the request — or a stale session payload — pick arbitrary column names. This is the one security-relevant behaviour to preserve explicitly, and it matters more with session state, because a session array written before a schema change can outlive the columns it references.
  • Version your session key (grid.filters.orders.v2) or store a schema fingerprint, so renaming a filter does not resurrect a fatal "unknown column" error for every returning user.
  • Add a Grid::toArray() method early so the same definition can drive both the Blade table and a JSON API response.
  • Always ship a "Clear filters" control that explicitly forgets the session key. The bundle adds the write path; the clear path is your responsibility.

Gotchas and Tips

The package is still effectively abandoned, and v0.2.7 does not change that. A one-bullet changelog with no dependency bumps, no PHP 8.2/8.3 notes, and no Symfony 6/7 support is a sign of a single small patch, not a maintained project. Assume no security patches. Treat any transitive dependency it pins as a liability in composer audit.

The session feature inverts one line of the previous assessment. Filters are no longer purely request-derived when the option is on. Consequences worth planning for:

  • Stale filters. A user filters by a status that no longer exists, returns a week later, and gets an empty grid with no visible cause. Show persisted filters as removable chips, prominently, and always render an explicit "state restored from your last visit" affordance.
  • Bookmark and back-button breakage. If filters live only in session, a URL pasted into Slack shows different rows for the sender and the recipient. Never let session state override explicit query-string parameters.
  • Cache pollution. If you cache grid HTML or JSON, a response that depends on session-stored filters now varies per user. Either add Vary: Cookie / a session-derived cache key, or — better — disable the session option on any cached grid.
  • Multi-tab collisions. Two tabs with different filters share one session key; the second tab silently rewrites the first. Namespace the key per grid instance at minimum, and accept the limitation.
  • Sidecar/API mismatch. As above: session persistence and stateless API access are incompatible. Pick one.

Expect the Symfony Kernel assumption. Bundles require Bundle::class registration in config/bundles.php in a Symfony app. Laravel has no equivalent registration path, so new MakosoDataGridBundle() will never be booted for you — any service the bundle expects to be autowired, including the session service the new option reaches for, will simply be missing. Manual instantiation is the only route, and the v0.2.7 option adds one more thing to wire by hand.

Twig is a non-starter. Do not add twig/twig to a Laravel application just to render one table. Extract the markup and rewrite it in Blade; the template is almost certainly a loop over columns with sort-link conditionals — plus, now, a block for rendering active filters.

Doctrine vs. Eloquent is a real impedance mismatch. If the bundle's filtering accepts a Doctrine QueryBuilder, there is no clean bridge to Eloquent. You would be writing a compatibility shim around an unmaintained library — the definition of negative ROI. Note that session persistence does not soften this at all; it only adds state to an object graph you already cannot bridge.

Debugging without documentation: since there is no user guide, trace from the Twig extension or controller-facing service downward. bin/console debug:container makoso (in a Symfony sandbox) will dump the service graph faster than reading XML; bin/console config:dump-reference makoso_data_grid — or whatever the bundle alias is — will now show you the session flag and its default, which is faster than reading Configuration.php. Stand up a throwaway Symfony 5 skeleton to see it work once, then discard it.

Extension points to note if you fork: the grid type / column type classes are the conventional seams, and as of v0.2.7 the filter-state read/write method is a third. Forking to modernize means updating the HttpFoundation and Doctrine calls, swapping the Twig extension for a Blade component, replacing the session coupling with Laravel's session, and deleting the DI bundle wrapper entirely — at which point you have written a new package.

Recommendation: unchanged — do not add this to a Laravel composer.json. Score the concepts, not the code. For production Laravel grids, the maintained options — spatie/laravel-query-builder for the sorting/filtering layer, plus Filament tables or Livewire for the UI layer — give you the same pattern with actual support behind it. v0.2.7 adds one genuinely useful idea (remembering filter state), but it is four lines of Laravel to implement yourself and one bridge class to inherit badly. Read the source for five minutes, take the idea, close the tab.

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.
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib