alengo / sulu-category-extra-bundle
Additional Data tab for Sulu CMS Categories — generic JSON field with configurable forms
Package info
github.com/alengodev/SuluCategoryExtraBundle
Type:symfony-bundle
pkg:composer/alengo/sulu-category-extra-bundle
Requires
- php: ^8.2
- sulu/sulu: ~3.0
README
Adds an Additional Data tab to the Sulu CMS category admin form. Stores arbitrary extra fields as a JSON column on the existing ca_categories table — no additional tables required.
Features
- Adds a configurable tab to the Sulu category edit form
- Stores extra fields as a JSON blob on the
Categoryentity - Form definition is fully controlled by the project via a standard Sulu form XML file
- Tab title, form key, and resource key are configurable
- Follows the same patterns as
alengo/sulu-contact-account-extra-bundle
Requirements
- PHP 8.2+
- Sulu CMS ~3.0
Installation
1. Add the bundle
From Packagist:
composer require alengo/sulu-category-extra-bundle
2. Register the bundle
Add to config/bundles.php:
Alengo\SuluCategoryExtraBundle\AlengoSuluCategoryExtraBundle::class => ['all' => true],
3. Register the routes
Add to config/routes/sulu_admin.yaml:
CategoryExtraBundle: resource: "@AlengoSuluCategoryExtraBundle/Resources/config/routing_admin_api.yaml" prefix: /admin/api
4. Create the form definition
Create config/forms/category_additional_data.xml in your project:
<?xml version="1.0" ?> <form xmlns="http://schemas.sulu.io/template/template" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://schemas.sulu.io/template/template http://schemas.sulu.io/template/form-1.0.xsd" > <key>category_additional_data</key> <properties> <property name="theme" type="single_select" colspan="12"> <meta> <title lang="de">Theme</title> <title lang="en">Theme</title> </meta> <params> <param name="values" type="collection"> <param name=""> <meta> <title lang="en">Default</title> <title lang="de">Standard</title> </meta> </param> <param name="blue"> <meta> <title lang="en">Blue</title> <title lang="de">Blau</title> </meta> </param> </param> </params> </property> </properties> </form>
Any standard Sulu field type (text_line, single_select, text_editor, media_selection, etc.) can be used. All fields are stored as top-level keys in the JSON blob.
5. Run the database migration
php bin/console doctrine:schema:update --force
This adds an additionalData JSON column to the existing ca_categories table.
Configuration
The bundle works out of the box with its defaults. To override any setting, add to config/packages/alengo_sulu_category_extra.yaml:
alengo_sulu_category_extra: entity_class: Alengo\SuluCategoryExtraBundle\Entity\Category # default form_key: category_additional_data # default resource_key: category_additional_data # default tab_title: sulu_admin.app.additional_data # default
| Option | Description |
|---|---|
entity_class |
The extended Category entity class to use |
form_key |
Must match the <key> in your form XML file |
resource_key |
Resource key used by the Sulu admin frontend |
tab_title |
Translation key or literal string shown as the tab label |
Reading additional data in Twig
The additionalData field is available on every Category entity. To read it in a Twig template, retrieve the category via the Sulu category manager or repository and access the extra fields:
{# category is an instance of the extended Category entity #} {% set theme = category.additionalData.theme ?? '' %}
When categories are passed through Sulu's standard API (e.g. navigation, content types), you may need to load the entity directly to access additionalData:
use Alengo\SuluCategoryExtraBundle\Entity\Category; use Sulu\Bundle\CategoryBundle\Entity\CategoryInterface; $category = $entityManager->getRepository(CategoryInterface::class)->find($id); if ($category instanceof Category) { $theme = $category->getAdditionalData()['theme'] ?? ''; }
API Endpoints
The bundle exposes two admin API endpoints (protected by Sulu's category security context):
| Method | Path | Description |
|---|---|---|
GET |
/admin/api/category-additional-data/{id} |
Load additional data for a category |
PUT |
/admin/api/category-additional-data/{id} |
Save additional data for a category |
Both endpoints return a JSON object with the category id plus all stored additional fields as top-level keys.