Skip to main navigation Skip to main content Skip to page footer

Typed Content Models for TYPO3

Funded through the TYPO3 community budget, the new Content Models extension gives developers a structured way to work with pages, content elements, and other records managed by TYPO3.

The community budget proposal, TYPO3 Delivery API: Step One — Content Models, focused on giving TYPO3 content a typed representation in PHP. The resulting TYPO3 Content Models extension (typo3-content-models) for TYPO3 v13.4 and v14 generates models from the Table Configuration Array (TCA) of a TYPO3 installation.

The extension delivers the main capabilities described in the proposal: generating content models and using them during page and content rendering. The extension includes generators for eager and lazy data transfer objects, and developers can customize them or build their own. Two data processors bring these models into the page rendering workflow. By implementing custom processors, developers can transform the content models further into view models.

Making Content Structure Explicit

The TYPO3 Content Models extension generates PHP classes that make content fields and their value types explicit to humans, development tools, and AI coding assistants. It enables code editors to suggest available fields and tools such as PHPStan to check for potential errors.

Compared with loosely structured collections of data, these models make content easier to work with and help catch mistakes earlier. They also provide a place to keep complex details behind a consistent interface, making projects easier to maintain.

# The constructor of a textmedia content model

#[ContentModel(table: 'tt_content', type: 'textmedia')]
class TextmediaContentModel implements ContentModelInterface
{
	public function __construct(
		public int $uid,
		…
		public readonly string $header,
		public readonly Content_HeaderLayout $header_layout,
		…
		public readonly ?string $bodytext,
		public readonly LazyFileReferenceCollection $assets,
		…
		/** @var LazyContentModelCollection<SysCategoryContentModel> $categories */
		public readonly LazyContentModelCollection $categories,
	) {
	}
	
	…
}

From Content Records to Useful View Models

In TYPO3, pages and content elements are usually handled as untyped arrays or generic, magic Record objects. When working with content, developers need to know which fields exist and what values and types to expect. But the type definitions are spread across TCA, database schema definitions, and possibly other configuration files.

Generated content models make that structure explicit. Typed properties and getters improve PHP code completion, make fields easier to discover, and give static analysis tools something concrete to check. Relations can lead to other content models, while suitable select fields become PHP enums. The content structure becomes easier for new contributors and AI coding assistants to understand. This brings a familiar way of working with typed PHP models to TYPO3 content.

The workflow builds on TYPO3's existing rendering process. TYPO3 retrieves records, and the extension's processors convert them into content models. Projects can then use these models directly in their templates or add processors that transform or wrap the content models in view models designed for their templates. This allows developers to move tasks such as link rendering and rich text rendering out of templates and into testable PHP code, providing a clear interface between backend logic and templates. This separation gives generated models and custom code distinct responsibilities: the generated models describe the available CMS content; the view models contain the content for a particular presentation.

Since Fluid 4.3, templates can use components with explicitly typed arguments, so view models can be designed to match each component’s data requirements.

Decoupling view models from content models can simplify templates by providing data tailored to their needs. For example, backend code can map pages, news, and calendar events to a common teaser view model, allowing a single teaser component to render them all.

The separation of content models and view models also provides a basis for exposing content through an API, either with the same view models used by the templates or with custom API models built on top of the content models.

Lessons Learned

One of the challenges in building the TYPO3 Content Models extension was designing the configuration language for code generation. A setting may need a project-wide default, a different value for one table, and another override for a particular record type or field. Providing those controls means defining how the levels interact, so that specific exceptions remain manageable without repeating the whole configuration. Feedback on how well this approach works in practice is especially welcome here.

Another challenge was obtaining TYPO3's expected database schema without a database connection and without duplicating code from TYPO3 Core classes. The generator uses database column information to infer scalar types where a more specific field handler does not apply. It needs the schema TYPO3 expects from the project's definitions, rather than depending on the state of an installed database.

As backend code generation is not part of most TYPO3 projects yet, the TYPO3 Content Models extension also adds another step to a website’s build process. The content generator needs to run and generate the model classes before other code can use them. For most projects, generation can run during dependency installation and whenever TCA changes.

Looking Ahead

Typed models also create opportunities beyond PHP code completion. If template tooling knows the type of a Fluid variable, it could suggest that model's available properties while editing a template. While the extension itself does not yet deliver that editor integration, the generated classes provide the necessary type information.

The planned next step is an API extension that builds a REST read API on this foundation. Integrators should be able to configure which fields to expose and provide custom API view models suited to their consumers. The content models could become a basis for generating API models, with their type information supporting machine-readable API descriptions.

That API remains future work. The completed content models project provides a useful part of the foundation while already supporting traditional TYPO3 rendering. It moves toward the proposal's broader goal of making content available to headless applications and hybrid setups as well.

The TYPO3 Content Models extension generates PHP models from existing TCA and database schema definitions. A possible future approach, beyond the funded scope, could reverse this direction: defining PHP models with additional metadata for storage and backend field presentation, then generating TCA and the database schema from them. This would keep the definitions for storage, backend forms, and usage in PHP centralized.

Try It and Help Improve It

Completion of the funded scope is a starting point for wider use. You can clone the repository and try the extension with your own TCA and rendering setup. The README provides installation, configuration, and usage instructions. Testing against different projects will help reveal missing field support and assumptions that need revisiting.

Please submit bugs and feature requests for the TYPO3 Content Models extension through GitHub issues. To discuss requirements for future API work or the broader approach, please join the original TYPO3 Talk thread.

Thank You

Thank you to the TYPO3 community for voting for this proposal and supporting it through the community budget. Your support made it possible to build this foundation for typed content models and take the first step toward a TYPO3 Delivery API.