PHPackages                             b13/container - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. b13/container

ActiveTypo3-cms-extension[Utility &amp; Helpers](/categories/utility)

b13/container
=============

Container Content Elements - Create Custom Container Content Elements for TYPO3

4.0.0(2w ago)1823.3M↓16%83[36 issues](https://github.com/b13/container/issues)[7 PRs](https://github.com/b13/container/pulls)20GPL-2.0-or-laterPHPCI failing

Since Jun 10Pushed 2w ago23 watchersCompare

[ Source](https://github.com/b13/container)[ Packagist](https://packagist.org/packages/b13/container)[ Docs](https://b13.com)[ RSS](/packages/b13-container/feed)WikiDiscussions master Synced 1w ago

READMEChangelog (10)Dependencies (45)Versions (74)Used By (20)

[![CI](https://github.com/b13/container/actions/workflows/ci.yml/badge.svg)](https://github.com/b13/container/actions/workflows/ci.yml/badge.svg)

EXT:container - A TYPO3 Extension for creating nested content elements
======================================================================

[](#extcontainer---a-typo3-extension-for-creating-nested-content-elements)

Features
--------

[](#features)

- Simple amazing containers (grids) as custom TYPO3 Content Elements
- No default containers; everything will be built the way it is needed for a project
- Supports multilanguage (connected or free mode (mixed mode not supported))
- Supports workspaces
- Supports colPos-restrictions if EXT:content\_defender is installed
- Frontend Rendering via DataProcessor and Fluid templates

Why did we create another "Grid" extension?
-------------------------------------------

[](#why-did-we-create-another-grid-extension)

At b13, we've long supported gridelements, for which we are thankful, and have used this extension with great pleasure in the past.

However, we had our pain points in the past with all the solutions we've evaluated and worked with. These are our reasons:

- We wanted an extension that works with multiple versions of TYPO3 Core with the same extension to support our company's [TYPO3 upgrade strategy](https://b13.com/solutions/typo3-upgrades).
- We wanted to overcome issues when dealing with the `colPos` field and dislike any fixed value that isn't fully compatible with TYPO3 Core.
- We wanted a thoroughly tested extension with multilingual and workspaces functionality.
- We wanted an extension that only does one thing: EXT:container ONLY adds tools to create and render container elements. There are no FlexForms, no permission handling, or custom rendering.
- We wanted an extension in which every grid has its own Content Type (CType), making it as close as possible to TYPO3 Core functionality.
- We wanted an extension where the configuration of a grid container element is located in one single place, making it easy to create custom containers.
- We wanted an extension with a progressive development workflow. We were working on new projects in TYPO3 v10 sprint releases, needed custom container elements, and did not want to wait until TYPO3 v10 LTS.

Installation
------------

[](#installation)

Install this extension via `composer req b13/container` or download it from the [TYPO3 Extension Repository](https://extensions.typo3.org/extension/container/) and activate the extension in the Extension Manager of your TYPO3 installation.

Once installed, add a custom content element to your site package or theme extension (see "Adding your container element").

Adding your container element
-----------------------------

[](#adding-your-container-element)

1. Register your custom container in your site package or theme extension in `Configuration/TCA/Overrides/tt_content.php` as new Content Type
2. Add TypoScript and your Fluid Template for frontend rendering
3. Add an icon in Resources/Public/Icons/``.svg

See [EXT:container\_example](https://github.com/b13/container-example) for a simple example of a custom container.

### Registration of Container Elements

[](#registration-of-container-elements)

This is an example of creating a two-column container. The code snippet goes into a file in your site package or theme extension in the folder `Configuration/TCA/Overrides/`. The file can have any name, but it is good practice to name it according to the database table it relates to. In this case, this would be `tt_content.php`.

```
\TYPO3\CMS\Core\Utility\GeneralUtility::makeInstance(\B13\Container\Tca\Registry::class)->configureContainer(
    (
        new \B13\Container\Tca\ContainerConfiguration(
            'b13-2cols-with-header-container', // CType
            '2 Column Container With Header', // label
            'Some Description of the Container', // description
            [
                [
                    ['name' => 'header', 'colPos' => 200, 'colspan' => 2, 'allowed' => ['CType' => 'header, textmedia']]
                ],
                [
                    ['name' => 'left side', 'colPos' => 201],
                    ['name' => 'right side', 'colPos' => 202]
                ]
            ] // grid configuration
        )
    )
    // set an optional icon configuration
    ->setIcon('EXT:container_example/Resources/Public/Icons/b13-2cols-with-header-container.svg')
);
```

#### Methods of the ContainerConfiguration Object

[](#methods-of-the-containerconfiguration-object)

Method nameDescriptionParametersDefault`setIcon`icon file, or existing icon identifier`string $icon``'EXT:container/Resources/Public/Icons/Extension.svg'``setBackendTemplate`Template for backend view`string $backendTemplate``EXT:container/Resources/Private/Templates/Container.html'``setGridTemplate`Template for grid`string $gridTemplate``'EXT:container/Resources/Private/Templates/Grid.html'``setGridPartialPaths` / `addGridPartialPath`Partial root paths for grid`array $gridPartialPaths` / `string $gridPartialPath``['EXT:backend/Resources/Private/Partials/', 'EXT:container/Resources/Private/Partials/']``setGridLayoutPaths`Layout root paths for grid`array $gridLayoutPaths``[]``setSaveAndCloseInNewContentElementWizard`saveAndClose for new content element wizard`bool $saveAndCloseInNewContentElementWizard``true``setRegisterInNewContentElementWizard`register in new content element wizard`bool $registerInNewContentElementWizard``true``setGroup`Custom Group (used as optgroup for CType select, and as tab in New Content Element Wizard). If empty, "container" is used as tab and no optgroup in CType is used.`string $group``'container'``setRelativeToField`Add item relative to existing field.`string $relativeToField``''``setRelativePosition`Valid keywords: `'before'`, `'after'`, `'replace'`.`string $relativeToField``''``setDefaultValues`Default values for the newContentElement.wizardItems`array $defaultValues``[]`**Notes:**

- If EXT:content\_defender is installed, you can use `allowed`, `disallowed`, and `maxitems` in the column configuration
- The container registry does multiple things:
    - Adds CType to TCA select items
    - Registers your icon
    - Adds PageTSconfig
    - Sets `showitem` for this CType (`header`)
    - Saves the configuration in TCA in `$GLOBALS['TCA']['tt_content']['containerConfiguration'][]` for further usage
- We provide some default icons you can use; see `Resources/Public/Icons`
    - container-1col
    - container-2col
    - container-2col-left
    - container-2col-right
    - container-3col
    - container-4col

### TypoScript

[](#typoscript)

The TypoScript is necessary to define the rendering of the container in the frontend. Normally, you will place it in your site package or theme extension near where you define other stuff regarding your content elements. `templateRootPaths` must be adapted to reflect the path of the HTML files in your site package or theme extension.

```
// default/general configuration (will add 'children_' variable to processedData for each colPos in container
tt_content.b13-2cols-with-header-container < lib.contentElement
tt_content.b13-2cols-with-header-container {
    templateName = 2ColsWithHeader
    templateRootPaths {
        10 = EXT:container_example/Resources/Private/Templates
    }
    dataProcessing {
        100 = B13\Container\DataProcessing\ContainerProcessor
    }
}

// if needed, you can use ContainerProcessor with explicitly set colPos/variable values
tt_content.b13-2cols-with-header-container < lib.contentElement
tt_content.b13-2cols-with-header-container {
    templateName = 2ColsWithHeader
    templateRootPaths {
        10 = EXT:container_example/Resources/Private/Templates
    }
    dataProcessing {
        200 = B13\Container\DataProcessing\ContainerProcessor
        200 {
            colPos = 200
            as = children_200
        }
        201 = B13\Container\DataProcessing\ContainerProcessor
        201 {
            colPos = 201
            as = children_201
        }
    }
}

```

#### Options for DataProcessing

[](#options-for-dataprocessing)

OptionDescriptionDefaultParameter`contentId`id of container to to processcurrent uid of content element `$cObj->data['uid']``?int``colPos`colPos of children to to processempty, all children are processed (as `children_`)`?int``as`variable to use for proceesedData (only if `colPos` is set)`children``?string``skipRenderingChildContent`do not call `ContentObjectRenderer->render()` for children, (`renderedContent` in child will not exist)empty`?int`### Template

[](#template)

The HTML template file goes in the folder you defined in your TypoScript above (see `templateRootPaths`). It's important to name it exactly as defined in `templateName` in TypoScript, in this case, `2ColsWithHeader.html`. The file name is case-sensitive!

```

    {record.header}

        {record.renderedContent}

    {record.header}

        {record.renderedContent}

```

With explicit colPos defined use `{children_200|201}` as set in the example above

ContentAreaProcessor for TYPO3 v14 or above
-------------------------------------------

[](#contentareaprocessor-for-typo3-v14-or-above)

for TYPO3 v14 or higher you can use the ConentAreaProcessor Automatically detects if content element has container columns adds them lazily to the content variable. The ContentArea can be used in f:render.contentArea or f:render.record ViewHelper

### TypoScript

[](#typoscript-1)

```
tt_content.b13-2cols-with-header-container < lib.contentElement
tt_content.b13-2cols-with-header-container {
    templateName = 2ColsWithHeader
    templateRootPaths {
        10 = EXT:container_example/Resources/Private/Templates
    }
    dataProcessing {
        100 = B13\Container\DataProcessing\ContentAreaProcessor
    }
}

```

### Options for ContentAreaProcessor

[](#options-for-contentareaprocessor)

OptionDescriptionDefaultParameter`contentId`id of container to to processcurrent uid of content element `$cObj->data['uid']``?int``as`variable to use for proceesedData`content``?string`### Template

[](#template-1)

```

  {content.200 -> f:render.contentArea()}

    {record -> f:render.record()}

```

PSR-14 Events
-------------

[](#psr-14-events)

### BeforeContainerConfigurationIsAppliedEvent

[](#beforecontainerconfigurationisappliedevent)

- change container configuration for 3rd-party extensions container you have installed
- apply the same configuration to all or a set of containers (e.g. `gridTemplate`)
- **Note** CType and Grid Structure cannot be changed (but Column Properties of the Grid)

### BeforeContainerPreviewIsRendered

[](#beforecontainerpreviewisrendered)

Change view object, e.g., add variables to view or change paths

Concepts
--------

[](#concepts)

- Complete registration is done with one PHP call to TCA Registry
- A container in the TYPO3 backend Page module is rendered like a page itself (see Backend/Preview/GridRenderer called in PageContentPreviewRenderingEvent Listeners)
- For backend clipboard and drag &amp; drop `_` used in the data-colpos attribute in the wrapping CE-div Element (instead of just the colPos as in the PageLayoutView)
- The `_` parameter is resolved to `tx_container_parent` and `colPos` value in DataHandler hooks
- When translating a container, all child elements also get translated (the child elements are not explicitly listed during the translation dialog)
- Copying or moving children of a container copies or moves translations as well
- Custom definitions make use of custom `colPos` values so site owners build their own elements, no fixed `colPos` given, so no interference with existing solutions
- Each container type is just a definition for its own `CType`

CLI commands
------------

[](#cli-commands)

There are several CLI commands to check/fix the integrity of the containers and their children.

```
# Check the sorting of container children
vendor/bin/typo3 container:sorting

# Fix the sorting of container children on page 123
vendor/bin/typo3 container:sorting --apply 123

# Check the sorting of records in page colPos
vendor/bin/typo3 container:sorting-in-page

# ??
bin/typo3 container:fixLanguageMode
bin/typo3 container:fixContainerParentForConnectedMode
bin/typo3 container:deleteChildrenWithWrongPid
bin/typo3 container:deleteChildrenWithNonExistingParent
bin/typo3 container:deleteChildrenWithUnusedColPos
```

TODOs
-----

[](#todos)

- Integrity proofs
- List module actions

Extension Tests and Coding Guidelines
-------------------------------------

[](#extension-tests-and-coding-guidelines)

You can run our test suite for this extension yourself:

- run `composer install`
- run `Build/Scripts/runTests.sh -s unit`
- run `Build/Scripts/runTests.sh -s functional`
- run `Build/Scripts/runTests.sh -s acceptance`

See Tests/README.md on how to run the tests locally (like how github-actions runs the tests).

To assure coding guidelines are fullfilled:

- run `php -d memory_limit=2G .Build/bin/phpstan analyse -c Build/phpstan14.neon`
- run `php -d memory_limit=2G .Build/bin/php-cs-fixer fix --config=Build/php-cs-fixer.php --dry-run --stop-on-violation --using-cache=no`

Credits
-------

[](#credits)

This extension was created by Achim Fritz in 2020 for [b13 GmbH, Stuttgart](https://b13.com).

Find examples, use cases, and best practices for this extension in our [container blog series on b13.com](https://b13.com/blog/flexible-containers-and-grids-for-typo3).

[Find more TYPO3 extensions we have developed](https://b13.com/useful-typo3-extensions-from-b13-to-you) that help us deliver value in client projects. As part of our work, we focus on testing and best practices to ensure long-term performance, reliability, and results in all our code.

###  Health Score

70

—

ExcellentBetter than 100% of packages

Maintenance92

Actively maintained with recent releases

Popularity62

Solid adoption and visibility

Community51

Growing community involvement

Maturity70

Established project with proven stability

 Bus Factor1

Top contributor holds 63.8% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~41 days

Recently: every ~25 days

Total

54

Last Release

18d ago

Major Versions

1.6.1 → 2.0.02022-08-11

2.3.6 → 3.0.02024-10-15

3.2.2 → v4.x-dev2026-02-23

3.2.x-dev → 4.0.02026-05-22

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/165630?v=4)[Benni Mack](/maintainers/bmack)[@bmack](https://github.com/bmack)

![](https://avatars.githubusercontent.com/u/2851821?v=4)[b13 GmbH](/maintainers/b13)[@b13](https://github.com/b13)

![](https://www.gravatar.com/avatar/e63334d6fdbd8f65eeb10a8e8913dca96a07ec2caffebdb2381c7b573c128237?d=identicon)[ochorocho](/maintainers/ochorocho)

---

Top Contributors

[![achimfritz](https://avatars.githubusercontent.com/u/2152991?v=4)](https://github.com/achimfritz "achimfritz (346 commits)")[![bmack](https://avatars.githubusercontent.com/u/165630?v=4)](https://github.com/bmack "bmack (52 commits)")[![davidsteeb](https://avatars.githubusercontent.com/u/3862523?v=4)](https://github.com/davidsteeb "davidsteeb (22 commits)")[![o-ba](https://avatars.githubusercontent.com/u/8812114?v=4)](https://github.com/o-ba "o-ba (14 commits)")[![lolli42](https://avatars.githubusercontent.com/u/2178068?v=4)](https://github.com/lolli42 "lolli42 (10 commits)")[![achimfritz-b13](https://avatars.githubusercontent.com/u/156071319?v=4)](https://github.com/achimfritz-b13 "achimfritz-b13 (10 commits)")[![georgringer](https://avatars.githubusercontent.com/u/1905663?v=4)](https://github.com/georgringer "georgringer (9 commits)")[![sbuerk](https://avatars.githubusercontent.com/u/1453466?v=4)](https://github.com/sbuerk "sbuerk (8 commits)")[![kitzberger](https://avatars.githubusercontent.com/u/1405149?v=4)](https://github.com/kitzberger "kitzberger (7 commits)")[![kevin-appelt](https://avatars.githubusercontent.com/u/25666167?v=4)](https://github.com/kevin-appelt "kevin-appelt (6 commits)")[![nigelmann](https://avatars.githubusercontent.com/u/10863442?v=4)](https://github.com/nigelmann "nigelmann (6 commits)")[![nhovratov](https://avatars.githubusercontent.com/u/19343425?v=4)](https://github.com/nhovratov "nhovratov (6 commits)")[![ervaude](https://avatars.githubusercontent.com/u/7824856?v=4)](https://github.com/ervaude "ervaude (4 commits)")[![mbrodala](https://avatars.githubusercontent.com/u/5037116?v=4)](https://github.com/mbrodala "mbrodala (4 commits)")[![garbast](https://avatars.githubusercontent.com/u/5036924?v=4)](https://github.com/garbast "garbast (4 commits)")[![jschlier](https://avatars.githubusercontent.com/u/9108576?v=4)](https://github.com/jschlier "jschlier (4 commits)")[![thomasrawiel](https://avatars.githubusercontent.com/u/5371428?v=4)](https://github.com/thomasrawiel "thomasrawiel (3 commits)")[![d-g-codappix](https://avatars.githubusercontent.com/u/179489411?v=4)](https://github.com/d-g-codappix "d-g-codappix (3 commits)")[![peterkraume](https://avatars.githubusercontent.com/u/4234704?v=4)](https://github.com/peterkraume "peterkraume (3 commits)")[![schloram](https://avatars.githubusercontent.com/u/13196174?v=4)](https://github.com/schloram "schloram (3 commits)")

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/b13-container/health.svg)

```
[![Health](https://phpackages.com/badges/b13-container/health.svg)](https://phpackages.com/packages/b13-container)
```

###  Alternatives

[friendsoftypo3/content-blocks

TYPO3 CMS Content Blocks - Content Types API | Define reusable components via YAML

101466.4k44](/packages/friendsoftypo3-content-blocks)[georgringer/news

News system - Versatile news system based on Extbase &amp; Fluid and using the latest technologies provided by TYPO3 CMS.

2985.2M111](/packages/georgringer-news)[wazum/sluggi

TYPO3 extension for URL slug management with inline editing, auto-sync, locking, access control, and redirects

41515.2k](/packages/wazum-sluggi)[fluidtypo3/flux

The flux package from FluidTYPO3

150999.7k24](/packages/fluidtypo3-flux)[typo3/cms-redirects

TYPO3 CMS Redirects - Create manual redirects, list existing redirects and automatically createredirects on slug changes.

167.3M74](/packages/typo3-cms-redirects)[yoast-seo-for-typo3/yoast_seo

Yoast SEO for TYPO3

561.7M9](/packages/yoast-seo-for-typo3-yoast-seo)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
