xrow/xrowmetadata-bundle
A Symfony bundle from XROW for working with content metadata, providing reusable services and configuration to attach, manage, and expose metadata across your application. Suitable for projects that need a structured, framework-integrated metadata layer.
This bundle is a legacy bridge: it wires the xrowmetadata eZ Publish 5 extension (a custom datatype) into the Symfony/eZ Publish 5 kernel so the datatype can be used on content classes. Treat it as maintenance-only — the last tagged release is 2017 and the description literally says [deprecated]. If you are not already on an eZ Publish 5.x / legacy-bridge codebase, do not adopt it.
Minimal steps to get it usable:
composer require xrow/xrowmetadata-bundle
If resolution fails, add a vcs repository pointing at the GitHub repo and pin a commit.app/AppKernel.php:
new Xrow\XrowMetadataBundle\XrowMetadataBundle(),
Place it after the eZ Publish bundles so the legacy extension registration runs correctly.php app/console ezpublish:legacy:script bin/php/ezpgenerateautoloads.php
php app/console cache:clear --env=prod
eZ/Publish/Extension/legacy extension/xrowmetadata directory (the actual datatype definition), its DependencyInjection/ config, and the Resources/config service definitions. The datatype class itself (usually xrowMetadataType) is where the day-to-day behavior lives.First use case: add an xrowMetadata attribute to a content class in the legacy admin, edit a content object to populate it, then read the value back from a Twig/controller to verify the legacy bridge is passing the attribute through. That single round-trip tells you whether the bundle is wired correctly — everything else builds on that.
Because the bundle is a thin bridge, most work happens through the eZ Publish content API and the legacy stack rather than through bundle-specific services.
xrowMetadata attribute via the legacy admin Content classes screen, not via a Symfony form. The datatype needs to be registered in the legacy datatype map (the bundle's extension should handle this on activation). Once registered it appears alongside ezstring, ezxmltext, etc.$content = $contentService->loadContent($contentId);
$field = $content->getField('metadata'); // your attribute identifier
$value = $field->value; // xrowMetadata\Value object
Depending on how the datatype stores data, $value is either a scalar wrapper or an array of sub-attributes; inspect the Value/Type classes before assuming a shape.ez_field_value(content, 'metadata') returns the raw value; for structured metadata you usually serialize it in a small Twig extension or read it via ez_render_field. Avoid relying on the legacy attribute_view_gui templates unless you ship them — the bundle does not guarantee front-end templates.ContentService::createContent / updateContent with a proper FieldValue built from the datatype's Value object. Direct ezcontentobjectattribute writes are the shortcut everyone reaches for and the reason people later can't figure out why the admin UI shows stale data — the datatype's fromString/toString won't have run.content.publish Symfony event subscriber is the right hook; mutate the field on the ContentCreateStruct before publishVersion, not after.Type::initialize* methods (which define the field definition) and mirroring the change in the Value class and the admin template. There is no clean extension point — this is a fork-and-edit datatype, so keep the change list short and documented in your repo.git pull propagates a new attribute.var/cache and ezpublish_legacy/var/cache).--ignore-platform-reqs, a locked PHP version, or a VCS fork. Pin it explicitly.Value object is not well documented. Dump it (var_dump, or dump() in a controller) once per attribute before writing template logic — assumptions about scalar vs. array storage cause silent template errors.ContentService; SQL-level edits skip fromString/toString and the datatype will appear to lose data.ezdebug / debug settings in ezpublish_legacy/settings/override/siteaccess) and error_log inside the datatype methods.Resources/views and the legacy extension's design/ folder, and be prepared to write your own attribute_view_gui template.ezmatrix, or in modern Ibexa a custom FieldType) before you're forced to. The metadata concept maps cleanly onto a Symfony-backed custom FieldType, and doing it now is cheaper than doing it after the legacy kernel is removed.PATCHES.md so future you (or a successor) can rebase on a fork when the upstream repo inevitably goes stale.How can I help you explore Laravel packages today?