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

Ez Bundle Laravel Package

survos/ez-bundle

A Symfony bundle from Survos that bundles the essentials for rapidly building data-driven apps: streamlined admin and CRUD scaffolding, Bootstrap/Tabler-friendly UI helpers, and sensible defaults so you can go from entities to working screens with minimal configuration.

View on GitHub
Deep Wiki
Context7

Getting Started

Install the bundle and register it alongside EasyAdmin:

composer require survos/ez-bundle
// config/bundles.php
Survos\EzBundle\EzBundle::class => ['all' => true],

Where to look first: open src/Attribute/ in the vendor directory. Every attribute in this package maps to a configuration call you'd otherwise make by hand in an AbstractCrudController (configureFields(), configureActions(), configureCrud(), menu items). Read the attribute constructor signature — that is the API surface, and it's the fastest way to learn what the bundle buys you.

First use case — a CRUD with zero boilerplate: the canonical workflow is to skip writing configureFields() by hand and instead decorate your entity (or controller) with the bundle's attributes. Something like:

#[EzCrud(icon: 'fa fa-user', label: 'Customers')]
class Customer
{
    #[EzField(label: 'Full name', sortable: true)]
    private string $name;
}

Then your controller collapses to almost nothing:

class CustomerCrudController extends AbstractCrudController
{
    use EzCrudTrait; // provided by the bundle — adapts attributes to the CRUD
}

Check the bundle's own README or tests/ for the exact trait name and attribute identifiers used in your version — the package is small and has moved quickly, so trust the source over the docs.

Implementation Patterns

Attribute-driven field configuration. The main leverage is that configureFields() and configureActions() become declarative. Annotate properties or getters on the entity, and the trait translates attributes into EasyAdmin Field objects. This keeps entity metadata (name, label, sort order, which fields are searchable) next to the property itself instead of in a controller 200 lines away.

Menu and dashboard wiring. Rather than hand-registering every CRUD in DashboardController::configureMenuItems(), annotate the controller and let the bundle collect them. Typical pattern:

#[EzMenuItem(section: 'Sales', order: 10)]
class OrderCrudController extends AbstractCrudController { ... }

This is where the bundle actually shines: menu sections become greppable from the controller instead of scattered across the dashboard.

Layering with EasyAdmin overrides. Attributes are a default. You can still override in the controller — configureFields() can yield from the parent and then tweak:

public function configureFields(string $pageName): iterable
{
    foreach (parent::configureFields($pageName) as $field) {
        yield $field;
    }
    yield Field::new('internalNote')->hideOnIndex();
}

This is the escape hatch for the 10% of fields that need conditional logic. Keep it small — if you're overriding more than a couple of fields, the attribute config was wrong for that entity.

Integration with existing Symfony features. The attributes are read at container-compile time (via a compiler pass or registerAttributeForAutoconfiguration), which means they compose with the normal DI setup. You can still inject services into the CRUD controller, use voters for security, and rely on EasyAdmin's permission checks. The bundle does not replace the controller lifecycle — it only preloads configuration.

Suggested day-to-day flow:

  1. make:entity as usual.
  2. make:crud for a starting AbstractCrudController.
  3. Move field metadata to the entity as attributes.
  4. Register menu placement with a menu attribute.
  5. Only touch configureFields()/configureActions() for genuinely page-specific logic.

Gotchas and Tips

Cache is everything. Attributes are compiled into the container. After changing an attribute, run bin/console cache:clear — otherwise you'll spend twenty minutes wondering why the label still says the old thing. If you're iterating fast, add a make cache alias.

Attribute names may not match your EasyAdmin version. survos/ez-bundle is small (0 stars, minimal usage) and tracks EasyAdmin 4. If you're on EasyAdmin 3, some Field options (sortable, hideOnForm) behave differently, and the attribute defaults may not map cleanly. Test one CRUD end-to-end before applying the pattern to twenty.

Debugging registration: if crud controllers aren't picked up, check bin/console debug:container --tag=easyadmin.controller — the bundle likely relies on a tag or registerAttributeForAutoconfiguration, and a missing tag means autoconfiguration isn't running (usually because services.yaml excluded the controller namespace or autoconfigure was disabled for that path).

Ordering conflicts. If you define an attribute and override the same method in the controller, the controller wins — but not always predictably if the trait uses __call magic or reflection. Prefer explicit overrides for anything security-relevant (permissions, field visibility), don't rely on attributes alone.

Menu ordering is per-section and easy to break. sort/order values across different attribute classes (menu vs. crud) may live in separate registries. If ordering feels wrong, look at how the bundle merges them — usually it's sorting by a single numeric key, so interleave carefully.

Version pinning. Because the package is low-traffic, pin an exact version in composer.json ("survos/ez-bundle": "1.0.*") rather than ^1. Small unmaintained packages break on minor bumps more often than large ones.

Extension points to know: the attribute classes themselves (extend to add custom attributes), the compiler pass that scans them, and the trait used by controllers. If you need behavior the bundle doesn't cover — say, per-user field visibility — subclass the trait or wrap the attribute in your own, rather than patching vendor.

Don't use it for one controller. If you only have two entities, the boilerplate saved is smaller than the cost of a third-party bundle in your composer.json. Reach for it when you have 10+ CRUDs and menu wiring is genuinely tedious.

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.
elsayed85/laravel-api-exceptions
ouhssini/laravel-demo-mode
daworks/ncloud-outbound-mailer-driver
gp247/cms
ignibyte/aic-gates
nexa-merchant/blog
novasa/laravel-language-center
opencage/geocode
adolfoholzer/parameters
livenetworks/ln-starter
shitoudev/permissionmanager
johannesclimacus/laravel-tui
hocvt/seotools
vitalybaev/sypexgeo
amphibee/themosis-ignition
gito-me/fast-excel
frankyso/laravel-ipaymu
geolize-studio/laravel-chile
boomerangui/chat
cgv/localized-resource