netgen/content-browser-ibexa
Netgen Content Browser Ibexa integrates the Netgen Content Browser with Ibexa, providing a fast, flexible interface for browsing, searching, and selecting content from your Ibexa repository. It connects the browser’s UI to Ibexa’s content model, making content discovery and reuse easier for editors...
Read this before anything else: this is a Symfony/Ibexa DXP package, not a Laravel one. There is no service provider, no config publish tag, no Eloquent, no facades. If you are a Laravel developer, the only honest day-to-day pattern is to run it on a separate Ibexa instance and consume that instance's content (headless or via API) from your Laravel app. Do not try to bolt Ibexa's repository model into a Laravel container — the value is inseparable from ContentService/SearchService and Ibexa's permission tree.
If you are on Ibexa, the setup is short:
Install both parents first. This package is glue; it does nothing without Ibexa DXP and netgen/content-browser already installed and working.
composer require netgen/content-browser
composer require netgen/content-browser-ibexa
Register the bundle in config/bundles.php, after IbexaBundle and the Content Browser bundle. Order matters — the Ibexa backend services reference repository services that must exist first.
Netgen\ContentBrowserIbexa\NetgenContentBrowserIbexaBundle::class => ['all' => true],
Look here first, in this order:
src/ — the actual backend and item handlers. This is the only reliable documentation; there is essentially no public docs and zero community.Resources/config/ (services.yaml / *.yaml) — the service tags that register the Ibexa backend with Content Browser. This is where the wiring actually is; read it before touching config.composer.json — treat the ibexa/*, symfony/* and netgen/content-browser constraints as unverified. A package with no dependents has no tested constraint matrix.First use case: expose the Ibexa content tree to a Content Browser picker — normally a Netgen Layouts block or a custom "insert existing content" field — so editors browse by content type/subtree instead of getting a flat relation list. Configure the Ibexa backend in your Content Browser config, then load the Content Browser route with that backend selected and confirm results render as real content objects.
Pin everything on day one, before you write a line of glue:
"ibexa/core": "4.6.*",
"symfony/framework-bundle": "6.4.*",
"netgen/content-browser": "x.y.z",
"netgen/content-browser-ibexa": "x.y.z"
Exact tags, not ranges, and vendor-fork both Netgen packages into your repo so drift is yours to control.
Backend is selected per picker, not globally. The common workflow is: one picker for "related articles" (restricted to article content types), another for "hero image" (image types under a media subtree). Model this as separate Content Browser item type configs pointing at the Ibexa backend with different content-type / subtree / search criteria, rather than one generic browser with a filter UI.
Map the two ID spaces deliberately. Content Browser deals in its own item IDs; Ibexa deals in content IDs and location IDs. Pick one convention and enforce it:
Whichever you choose, the item handler must round-trip cleanly (id → content/location → id) and the picker's value stored on the block/field must be that same ID. Half the bugs in this kind of adapter come from storing a location ID and later resolving it as a content ID.
Keep the mapping layer thin and testable. Put ID translation, type filtering and criteria-building in a small service of your own, and let the package be the transport. Then write a contract test that asserts: a known content item is discoverable, resolves to the right object, and carries the expected name/type. When either vendor upgrades, that test fails loudly instead of your editors finding out.
Respect Ibexa's permission model in the query path. Ibexa's search results are subject to the current user's limitations only if you go through the repository services with the correct user context. Verify your backend doesn't fall back to an admin/system user. Add a test: log in as a restricted editor, run a browser query whose results include forbidden content, assert they're absent. A permission bypass here is a security finding, not a bug.
Handle language and siteaccess explicitly. Ibexa is multi-language and multi-site by default. Decide:
Encode this in the item type config, not in the editor's UI choices.
Paginate and cap. Every browse interaction hits Ibexa's search backend (Solr or legacy). Deep pagination and broad "search everything" criteria surface as search-cluster load and admin latency. Set a page size, set a hard max results, and prefer narrow subtree/content-type scoping in the item type config.
Wire it into Netgen Layouts blocks as the usual payoff: the block's parameter accepts a Content Browser value, the block view resolves the stored ID to an Ibexa content object and renders. Keep resolution in a block view provider or a small resolver service rather than inside the template, and cache resolved content per request.
Custom extension points. If you need non-standard filtering (e.g. "only content with a specific taxonomy term"), extend rather than fork: register your own item type pointing at the Ibexa backend with a custom criteria builder, or decorate the package's backend service with a Symfony service decorator. This keeps your code in your repo and the shim untouched.
laravel/framework framing in a package catalog is noise. No service provider, no facade, no publishable config. The realistic Laravel pattern is headless: Ibexa + this package as the editorial tool, Laravel as the consumer.NetgenContentBrowserIbexaBundle before Ibexa's bundle produces confusing "service not found" errors at container build, not at runtime.bin/console cache:clear — Symfony config caching in prod masks backend/item-type changes and makes you think the package is broken when it isn't.src/ of the package (copy it to vendor/ and enable path mapping in your IDE), Symfony's profiler for the query count per browse action, and Ibexa's own repository logging. Content Browser's UI gives little feedback beyond "no items" — the profiler is where you'll see whether the backend was called at all.How can I help you explore Laravel packages today?