================= Render containers ================= This guide shows how to output EXT:container (b13/container) elements with this extension — the container's columns as JSON alongside or inside the container's own `data`. Prerequisites ============= * EXT:container installed (`composer require b13/container`) * Container Content Types defined (e.g. the `b13_2_columns_container` used below, with child columns `colPos` 201 and 202) `b13/container` is a *suggested* dependency — the extension works without it; the `nb-container-json` processor only loads when EXT:container is present. TypoScript setup ================ Variant 1: `left`/`right` parallel to `data` -------------------------------------------- .. code-block:: typoscript lib.content.select.where = colPos NOT IN (201, 202) tt_content.b13_2_columns_container =< lib.contentElement tt_content.b13_2_columns_container { fields { left = TEXT left { dataProcessing { 10 = nb-container-json 10 { colPos = 201 as = left } } } right = TEXT right { dataProcessing { 10 = nb-container-json 10 { colPos = 202 as = right } } } } } Result: the container element carries `left`/`right` next to `data`: .. code-block:: json { "id": 5, "type": "b13_2_columns_container", "colPos": 0, "left": [ { "id": 6, "type": "vendor_text", "data": { "...": "..." } } ], "right": [ { "id": 7, "type": "vendor_image", "data": { "...": "..." } } ] } Variant 2: `left`/`right` inside `data` --------------------------------------- .. code-block:: typoscript lib.content.select.where = colPos NOT IN (201, 202) tt_content.b13_2_columns_container.fields.data.dataProcessing.10 { dataProcessing { 10 = nb-container-json 10 { colPos = 201 as = left } 20 = nb-container-json 20 { colPos = 202 as = right } } } This is the sub data processor pattern from `Add sub data processors `__ — the columns land as keys inside `data`. How it works ============ `nb-container-json` (`ContainerJsonDataProcessor`) fetches the container's children for the given `colPos` via b13/container's `ContainerProcessor` and renders each child through the same conversion as `nb-content-blocks-json` — field identifiers as keys, same `JSON contract <../Reference/JsonContract.rst>`__. Both variants are covered end-to-end by `Tests/Functional/Frontend/ContentBlocksJsonResponseTest.php`. Container as Content Block (variant 2): keep your own fields ============================================================ When the container itself is a Content Block (variant 2), do **not** register it with `Registry::configureContainer()`: b13/container would overwrite the `types[]['showitem']` of the Content Block, and the resolved record (and thereby `data`) would lose the Content Block's own fields. Write the `containerConfiguration` directly into TCA instead — this keeps the Content Block's showitem while b13/container still recognizes the container: .. code-block:: php $configuration = new \B13\Container\Tca\ContainerConfiguration( 'vendor_mycontainer', 'My Container', '', [[['name' => 'main', 'colPos' => 201]]] ); $GLOBALS['TCA']['tt_content']['containerConfiguration']['vendor_mycontainer'] = $configuration->toArray(); The `colPos` exclusion matters ============================== `lib.content.select.where = colPos NOT IN (201, 202)` keeps the container children out of the regular page content query. Without it, children appear twice: once in the page's content array and once in their column. Options ======= The processor accepts `colPos` (container column to fetch, required) and `as` (key of the children array). Children are rendered through their own `tt_content.` mapping, so their conversion options (`processor options <../Reference/ProcessorOptions.rst>`__ like `options.processing` or `options.dateTimeFormat`) are configured there, not on `nb-container-json`. If the container cannot be built (e.g. the record is hidden), `as` is an empty list. Children without a `renderedContent` key — e.g. with b13's `skipRenderingChildContent` and no substitute data processor — become `null` entries.