philiplb/crudlex
CRUDlex is a Laravel package for rapidly building CRUD interfaces and admin panels from Eloquent models. Configure fields, validation, filters, and actions with minimal code, then manage records through a clean, customizable UI. It speeds up back-office development while staying flexible for custom...
CRUDlex is a config-driven admin CRUD generator: you describe database tables in a YAML file, point it at a Doctrine DBAL connection, and it gives you list/create/edit/show/delete screens with filtering, sorting, pagination, validation and file uploads — rendered through Twig templates. If you're coming from Laravel, think "backpack/laravel-admin, but for Symfony 4 / Silex 2 and Doctrine DBAL instead of Eloquent."
Since 0.14.0 the core is framework-agnostic: philiplb/crudlex no longer depends on Silex. You install the core plus a thin adapter — philiplb/crudlex-symfony4-bundle for Symfony 4, philiplb/crudlex-silex2 for Silex 2. Everything below assumes you pick one adapter and stay inside it.
Minimal steps:
Install core + adapter, and pin. composer require philiplb/crudlex:^0.14 philiplb/crudlex-symfony4-bundle (or the Silex 2 package). The release is old, so expect to constrain PHP and Doctrine DBAL in composer.json before anything else resolves.
Read the config reference first. The whole package is driven by one YAML file (crud.yml by convention). The README's config table plus one sample entity is enough to start — the Twig templates and the AbstractData/MySQLData classes are your second stop.
Register the adapter. In Silex 2 you register CRUDlex\Silex\ServiceProvider with crud.file and a 'crud.data' => ['<entity>' => new CRUDlex\MySQLData(...)] map. In Symfony 4 you register the bundle and let it read the YAML config. Either way, the wiring is "one data provider per entity, one config key per entity."
Model one table. Start with a single entity and only list + edit. Something like:
entities:
book:
label: Books
fields:
title:
type: string
label: Title
required: true
author:
type: reference
reference:
entity: author
field: name
published:
type: date
label: Published
Mount the routes under a prefix (/admin), and hit the generated list route. That's the first end-to-end smoke test: list → create → edit → delete → pagination → filter.
First useful use case: an internal back-office on top of existing tables. Do not start with file uploads, reference fields and custom validation simultaneously — add those after the list/edit loop is passing.
type (string, text, integer, float, date, datetime, time, boolean, reference, many/set, enum, file). The field type is what selects the form widget and the list rendering, so choosing it correctly is the main design decision.MySQLData is the default; wire a distinct instance per entity so you can override per-table behavior later (see extension points). Keep the DBAL connection shared.$app['crud.layout'] = 'myLayout.twig' and $app['crud.manageI18n'] keys are gone. Use the accessor methods on the crud instance: $app['crud']->setTemplate('layout', 'myLayout.twig'), $app['crud']->setManageI18n(true). This is the single biggest source of "it worked on 0.13" breakage.templates/bundles/<BundleName>/...) to change layout, columns, and button sets. Everything visual is template-level. When you copy a shipped template, rewrite its internals: templates no longer reference app. and all Twig functions/filters are now prefixed crudlex_.required/constraints in YAML for per-field rules; for anything involving two fields, do it in a service/controller wrapping the CRUDlex call rather than fighting the config.security.yaml + ROLE_ADMIN; in Silex put it behind a before middleware. Treat it as "the UI only appears for admins," not "it enforces anything."reference field resolves an entity + display field — there's no lazy loading or cascading. For joins you care about, either model them as references or override the list query in a MySQLData subclass.Attention: lines before upgrading. The concrete breaks: ServiceProvider moved from CRUDlex\ to CRUDlex\Silex\; ControllerProvider split into Controller + Silex\ControllerProvider with Controller now implementing ControllerInterface; PHP ≤ 7.1 dropped; Pimple key configuration replaced by setTemplate() / setManageI18n() / isManageI18n(); Twig functions and filters prefixed crudlex_; framework dependencies moved to CRUDlexSilex2 and CRUDlexSymfony4Bundle.composer update conflicts and type-mapping errors before you see a single page.app. or an unprefixed Twig helper will break on 0.14 — the internals now talk to the crud instance and the crudlex_* helpers. Diff your overrides against the shipped templates after upgrading.type values or misspelled field names degrade the widget or throw at render time. Clear the container/cache after every config change and inspect the parsed definition via the data provider's getDefinition() when a field "disappears."MySQLData — they are not config options.MySQLData and override create, update, delete, listEntries to inject auditing, extra constraints, or custom queries.AbstractData to back an entity with a non-Doctrine source (API, view, CSV).Controller (or implement ControllerInterface) to override actions in a framework-portable way, instead of extending the Silex-specific ControllerProvider.setTemplate() / template overrides for presentation.How can I help you explore Laravel packages today?