xcore/inline-editing-bundle
Xcore InlineEditingBundle adds in-place editing to PHP applications, letting users update content directly on the page without separate forms. It provides a simple integration for CMS-style interfaces, helping editors and administrators make faster content changes.
xcore/inline-editing-bundle is a Symfony bundle built for XCore CMS — not a Laravel package. Despite the naming and your familiarity with package/, there is no ServiceProvider, no facade, no config/inline-editing.php. A Laravel developer's first decision is whether to (a) study it as reference architecture and port the pattern, or (b) actually run it inside a Symfony/XCore application.
First 15 minutes:
composer.json "type" field — it will be symfony-bundle. This immediately tells you composer require into a Laravel app installs the files but wires up nothing.src/ and find the class that extends Bundle (typically InlineEditingBundle.php). That file lists the service and template wiring.src/Controller/ first — the save endpoint(s) hold the entire feature. This is the piece you are re-implementing.src/Twig/ for the front-end helper (the analogue of a Blade component / directive).src/EventSubscriber/ or src/EventListener/ for cache-invalidation and re-render hooks.Resources/config/ (routes, services) — this is the wiring you need to translate into routes/web.php and a service provider.First use case to target: a single editable field (a blog post title, or body) that an authenticated editor can click into, edit in place, and persist with an AJAX round-trip returning fresh HTML. That is the shortest path to understanding the package's entire value proposition.
If you're building the Laravel equivalent, plan on: a PATCH /inline/{model}/{id}/{field} route, a Gate/Policy for field-level authorization, a Blade component <x-inline-editor :model="$post" field="title" />, and Alpine.js (or Turbo/Hotwire) for the click-to-edit toggle. You are not importing the bundle — you are reading it to copy the shape.
The editable-region helper. The bundle exposes a Twig function that wraps a template region in the metadata required for click-to-edit: content type, identifier, field name, and current value. The Blade equivalent is a component that renders the same data-* attributes and lets your JS controller POST on blur:
<x-inline-editor :model="$post" field="title" :value="$post->title" />
Keep the server-rendered value inside the element so it degrades without JS.
Save endpoint shape. The bundle's controller pattern is: resolve the entity by identifier → check permission → validate the incoming value → persist → return updated payload (or a redirect for non-AJAX). Mirror it exactly in Laravel:
Route::patch('/inline/{model}/{id}/{field}', [InlineEditController::class, 'update'])
->middleware(['auth', 'verified']);
Inside update, resolve through a server-side field whitelist, authorize via $this->authorize('editField', [$model, $field]), sanitize if rich text, and return JSON with rendered HTML or a 204.
Content-type registry (polymorphism). The bundle is designed around multiple content types. In Laravel this is a Relation::morphMap() plus your own registry mapping a client token to a model class. Never trust the client-supplied model string — resolve it through the registry:
$class = ContentTypes::resolve($request->string('type'));
abort_unless($class && class_exists($class), 422);
abort_unless(in_array($field, $class::editableFields(), true), 422);
Event-driven invalidation. The bundle fires events on save so caches can be cleared and derived data re-rendered. Laravel maps this cleanly to an observer plus an event/job:
Post::updated(fn ($post) => ContentUpdated::dispatch($post));
// listeners: CacheBuster, SearchIndexer, SitemapBuilder
Edit-mode toggle. The bundle is typically gated behind an "edit mode" session flag so anonymous traffic gets cached, unadorned HTML. Replicate with middleware that sets session(['edit_mode' => true]) for authorized users, then wrap the edit wrappers in @if (editMode()) so production HTML is not bloated by the wrapper markup.
Progressive enhancement. Keep the inline edit region an actual <form> (even a hidden one) so no-JS submission works, and layer JS on top for the inline UX. This is the pattern the bundle's Twig partials follow and it is the right pattern to carry into Laravel.
type: symfony-bundle means the bundle only auto-registers through config/bundles.php in Symfony. composer require will succeed, but no routes, no Twig helpers, no listeners will exist in a Laravel app. Don't spend an afternoon wondering why the endpoint 404s.attribute() and filter chaining do not map 1:1; rewrite the helpers as Blade components or a custom directive rather than trying to shim Twig into Laravel.Model::find() with findOrFail and a $fillable/$guarded awareness. Whitelist the editable field set explicitly — the Doctrine version relies on entity metadata, which does not exist in Eloquent._token, but they're validated by different middleware. If you lift JS from the bundle, regenerate headers with csrf_token() or @csrf — don't hardcode.mews/purifier or HTMLPurifier directly; strip_tags is not enough and htmlspecialchars will destroy formatting. Sanitize on save, render-safe on display.updated_at (or version) check on save and return 409 Conflict when it moved. This is an improvement to make over copying the bundle's simpler controller.editableFields() list, a malicious client can patch is_admin, price, or published_at. The bundle relies on content-type configuration for this; in Laravel there is no equivalent, so you must build it./edit/{slug}) that bypasses the cache entirely.webpack.config.js and expect it to work.config/services.yaml, override templates in Resources/views/, and decorate the save handler rather than editing the controller directly. In Laravel terms, translate that into a config-driven controller + an interface you can swap.storage/logs.How can I help you explore Laravel packages today?