
Site Sets (TYPO3 13.4+)
| Set | Purpose |
|---|---|
mpc/mp-core (Aggregator) | Includes all subordinate feature sets in a single include |
mpc/mp-core-base (required) | Core functionality, templates, basic styling, shared settings |
mpc/mp-core-container | Container elements (accordion, tabs, sliders, grid) |
mpc/mp-core-news | Integration of the news extension |
mpc/mp-core-form | Configuration of the form framework |
mpc/mp-core-seo | SEO (Open Graph, Twitter Cards, Schema.org, sitemap) |
mpc/mp-core is an aggregator that is based on mpc/mp-core-base as well as all functionalities. All you need to do is mpc/mp-core integrate it into your website. If you require fine-tuned control, add mpc/mp-core-base and select individual features.
Set roles
| Set a role | Role |
|---|---|
mpc/mp-core | Aggregator + shared website settings (settings.yaml, settings.definitions.yaml in this folder) |
mpc/mp-core-base | Loads TYPO3 system extensions; registers the above paths for shared settings; optional integrations, if available |
mpc/mp-core-* (Feature) | Feature-specific TypoScript and settings; each dependent on mpc/mp-core-base only |
Important: When creating a custom site set, you must
dependencies: [mpc/mp-core-base, …]— nevermpc/mp-core. Establishing dependencies on a child set via the aggregator results in a SetRegistry recursion deadlock.
mpc/mp-core-base Dependencies
Required: typo3/form, typo3/redirects, typo3/indexed-search
Optional (used during installation): georgringer/news-recordlinks, georgringer/news-sitemap, mpc/mpc-vidply, mpc/mpc-rss
Enabling sets
Backend: Site management -> Sites -> ‘Sets’ tab -> Enable and organise sets.
YAML (config/sites/[site]/config.yaml):
base: 'https://example.com'
rootPageId: 1
dependencies:
- mpc/mp-core
Or select individual sets specifically:
dependencies:
- mpc/mp-core-base
- mpc/mp-core-container
- mpc/mp-core-seo
Website settings
Can be edited via Website Management → Websites → Settings or config/sites/[site]/settings.yaml.
Regenerate after changes settings.definitions.yaml / settings.yaml:
node Documentation/scripts/sync-site-settings.mjs
Core (shared — mpc/mp-core / registered via mpc/mp-core-base)
Definitions and default values for website settings can be found in Configuration/Sets/mp-core/settings.definitions.yaml and settings.yaml. The base set simply refers to these files.
Source: Configuration/Sets/mp-core/
Schema Standard —
defaultinsettings.definitions.yaml(‘Website Settings’ user interface). Default value provided – value fromsettings.yamlif it overrides the schema (column—= as in the schema).
PIDs
| Key | Type | Default value |
|---|---|---|
PIDs.pidSearch | int | 0 |
PIDs.pidHome | int | 1 |
PIDs.pidMetaNavTop | int | 66 |
PIDs.pidMetaNavFooter | int | 25 |
PIDs.pidMainNavMeta | int | 25 |
PIDs.pidCategories | int | 251 |
PIDs.pidLogosBannerTop | int | 391 |
PIDs.pidSupplement | int | 24 |
PIDs.pidWebFonts | int | 0 |
Configuration
| Key | Type | Default |
|---|---|---|
config.admPanel | bool | false |
config.debug | bool | false |
config.noCache | bool | false |
config.removeDefaultJS | String | external |
config.spamProtectEmailAddresses | bool | true |
config.spamProtectEmailAddresses_atSubst | string | [at] |
config.absRefPrefix | String | auto |
config.headerComment | String | (empty) |
Value
| Key | Type | Default |
|---|---|---|
performance.compressJs | bool | false |
performance.compressCss | bool | false |
performance.concatenateJs | bool | false |
performance.concatenateCss | bool | false |
performance.enableLazyLoading | bool | true |
Navigation
| Key | Type | Schema standard | Default setting |
|---|---|---|---|
navigation.maxDepth | int | 5 | 3 |
navigation.showHiddenPages | bool | false | — |
navigation.enableBreadcrumb | bool | true | — |
Meta
| Key | Type | Schema default value | Default value |
|---|---|---|---|
meta.viewport | String | width=device-width, initial-scale=1 | — |
meta.robots | String | index,follow | — |
meta.appleMobileWebAppCapable | String | no | — |
meta.compatible | String | IE=edge | — |
meta.google | String | notranslate | — |
meta.googleSiteVerification | String | (empty) | zPXbpegj_B5wbUDB7aXteJbnbT0IPiTDgsP53on-gRA |
Templates & Paths
| Key | Type | Default |
|---|---|---|
basePath | String | EXT:mp_core |
pageTemplates | String | EXT:mp_core/Resources/Private/Templates/Page/ |
pagePartials | String | EXT:mp_core/Resources/Private/Partials/Page/ |
pageLayouts | String | EXT:mp_core/Resources/Private/Layouts/Page/ |
pageFaviconsFile | String | EXT:mp_core/Resources/Private/Partials/Page/Favicons.html |
contentElementTemplates | String | EXT:mp_core/Resources/Extensions/fluid_styled_content/Private/Templates/ |
contentElementPartials | String | EXT:mp_core/Resources/Extensions/fluid_styled_content/Private/Partials/ |
contentElementLayouts | String | EXT:mp_core/Resources/Extensions/fluid_styled_content/Private/Layouts/ |
containerElementTemplates | String | EXT:mp_core/Resources/Private/Templates/Container/ |
containerElementPartials | String | EXT:mp_core/Resources/Private/Partials/Container/ |
containerElementLayouts | String | EXT:mp_core/Resources/Private/Layouts/Container/ |
pluginsNewsTemplates | String | EXT:mp_core/Resources/Extensions/news/Templates/ |
pluginsNewsPartials | String | EXT:mp_core/Resources/Extensions/news/Partials/ |
pluginsNewsLayouts | String | EXT:mp_core/Resources/Extensions/news/Layouts/ |
pluginsIndexedSearchTemplates | String | EXT:mp_core/Resources/Extensions/indexed_search/Templates/ |
pluginsIndexedSearchPartials | String | EXT:mp_core/Resources/Extensions/indexed_search/Partials/ |
pluginsIndexedSearchLayouts | String | EXT:mp_core/Resources/Extensions/indexed_search/Layouts/ |
contentTypesTemplates | String | EXT:mp_core/Resources/Private/Templates/Content/ |
contentTypesGalleryTemplates | String | EXT:mp_core/Resources/Private/Templates/Content/ |
resourcesPrivate | String | EXT:mp_core/Resources/Private |
resourcesExtensions | String | EXT:mp_core/Resources/Extensions |
structuredDataEnabled | bool | true |
structuredData.extraEntity.type | String | none |
structuredData.extraEntity.name | String | (empty) |
structuredData.extraEntity.description | String | (empty) |
structuredData.extraEntity.keywords | String | (empty) |
Container (mpc/mp-core-container)
Source: Configuration/Sets/mp-core-container/
| Key | Type | Default value |
|---|---|---|
container.grid.enabled | bool | true |
container.grid.defaultColumns | int | 2 |
container.grid.maxColumns | int | 4 |
container.grid.gutterSize | String | 20px |
container.accordion.enabled | bool | true |
container.accordion.allowMultiple | bool | false |
container.accordion.firstOpen | bool | true |
container.tabs.enabled | bool | true |
container.tabs.position | String | top |
container.wrapper.maxWidth | String | 1200px |
container.wrapper.padding | String | 15px |
Messages (mpc/mp-core-news)
Source: Configuration/Sets/mp-core-news/
| Key | Type | Default |
|---|---|---|
news.list.paginate.itemsPerPage | int | 10 |
news.list.orderBy | String | datetime |
news.list.orderDirection | String | desc |
news.list.dateFormat | String | d.m.Y |
news.list.showCategories | bool | true |
news.list.showTags | bool | true |
news.detail.showBackLink | bool | true |
news.detail.showRelated | bool | true |
news.detail.relatedLimit | int | 3 |
news.detail.enableComments | bool | false |
news.media.maxWidth | int | 1200 |
news.media.maxHeight | int | 800 |
Form (mpc/mp-core-form)
Source: Configuration/Sets/mp-core-form/
| Key | Type | Default value |
|---|---|---|
form.honeypot.enabled | bool | true |
form.confirmationPage.enabled | bool | true |
form.requiredFieldMarker | String | * |
form.email.senderName | String | Website Contact Form |
form.email.senderEmail | String | noreply@example.com |
form.email.replyToEmail | String | info@example.com |
form.validation.clientSide | bool | true |
form.validation.showInlineErrors | bool | true |
form.storage.saveToDatabase | bool | false |
form.storage.uploadFolder | String | 1:/forms/ |
SEO (mpc/mp-core-seo)
Source: Configuration/Sets/mp-core-seo/
| Key | Type | Default |
|---|---|---|
seo.meta.defaultDescription | String | (empty) |
seo.meta.generateDescriptions | bool | true |
seo.meta.maxDescriptionLength | int | 160 |
seo.meta.maxTitleLength | int | 60 |
seo.meta.titleSeparator | String | | |
seo.openGraph.enabled | bool | true |
seo.openGraph.defaultImage | string | (empty) |
seo.openGraph.imageWidth | int | 1200 |
seo.openGraph.imageHeight | int | 630 |
seo.twitter.enabled | bool | true |
seo.twitter.cardType | String | summary_large_image |
seo.twitter.site | string | (empty) |
seo.sitemap.enabled | bool | true |
seo.sitemap.excludeHiddenPages | bool | true |
seo.sitemap.priority | String | 0.5 |
seo.canonical.enabled | bool | true |
seo.schema.enabled | bool | true |
seo.schema.organizationType | String | Organization |
seo.schema.legalName | string | (empty) |
seo.schema.alternateName | String | (empty) |
seo.schema.description | String | (empty) |
seo.schema.foundingDate | String | (empty) |
seo.schema.vatId | String | (empty) |
seo.schema.taxId | String | (empty) |
seo.schema.knowsAbout | String | (empty) |
seo.schema.person.jobTitle | String | (empty) |
seo.schema.email | String | (empty) |
seo.schema.telephone | String | (empty) |
seo.schema.contactPoint.contactType | String | customer service |
seo.schema.contactPoint.telephone | String | (empty) |
seo.schema.contactPoint.email | String | (empty) |
seo.schema.contactPoint.areaServed | String | (empty) |
seo.schema.contactPoint.availableLanguage | String | (empty) |
seo.schema.address.streetAddress | String | (empty) |
seo.schema.address.addressLocality | String | (empty) |
seo.schema.address.postalCode | String | (empty) |
seo.schema.address.addressRegion | String | (empty) |
seo.schema.address.addressCountry | String | (empty) |
seo.robots.enabled | bool | true |
seo.robots.allowAiBots | bool | true |
seo.robots.crawlDelay | int | 0 |
seo.robots.additional | String | (empty) |
seo.llmsTxt.enabled | bool | true |
seo.llmsTxt.intro | text | (empty) |
seo.llmsTxt.news.storagePid | String | (empty) |
seo.llmsTxt.news.detailPageId | int | 0 |
seo.llmsTxt.news.limit | int | 5 |
Using settings in TypoScript
Website settings are defined as simple TypoScript constants under their dotted key (without settings. prefix), e.g. {$navigation.maxDepth}, {$config.admPanel}, {$PIDs.pidWebFonts}. The path settings (pageTemplates, basePath, …) are additionally provided with a settings. prefix, which is why the mpcSitepackage.* path constants must be set to {$settings.pageTemplates}.
For values that need to be resolved at render time (e.g. within config, page.metaor in DataProcessor properties), read them directly via the site:settings.* data getter rather than via a constant:
# Flat constant (resolved at TypoScript parse time)
page.10.dataProcessing.110.levels = {$navigation.maxDepth}
# Runtime getter (preferred for config / meta / processor stdWrap)
config.compressJs.data = site:settings.performance.compressJs // {$config.compressJs}
page.meta.robots.data = site:settings.meta.robots
Font design tokens are not used via TypoScript: they are generated from the web font data sets (see Web Fonts) WebFontProcessor and as custom CSS properties in Resources/Private/Partials/Page/Styles.html.
Web fonts
Editors can host their own fonts (uploaded to or selected from the file manager) instead of using system fonts. This feature replaces the previous design.fonts.* string settings.
Data model
| Record | Table | Purpose |
|---|---|---|
| Web font family | tx_mpcore_domain_model_webfontfamily | A CSS font-family (name + fallback stack), assigned to a target CSS variable |
| Font | tx_mpcore_domain_model_webfontface | One uploaded font file per weight/style (inline child element of a family) |
The ‘Applies to’ field for a family assigns it to a custom CSS property:
| Role | CSS variable |
|---|---|
| Body text | --bs-body-font-family |
| Headings | --bs-font-sans-serif |
| Custom CSS variable | The --… Name entered in the family set |
Editor workflow
- Create a system folder to store the records and set its page ID in the
PIDs.pidWebFontswebsite setting. Leave the setting set to0to store the records on the website’s root page. - In the list module for this folder, create a web font family: enter the font family
name(e.g.Inter), afallbackstack (e.g.sans-serif) and select ‘Applies to’. - Add one font per weight/style. Upload a file via the file manager or select a
woff2file via the file manager and set the weight (100–900) and style (normal/italic). - Clear the front-end cache.
WebFontProcessorThis generates the@font-facerules and the:rootvariable assignments in the nonce-protected inline block<style>block in the page<head>.
rendering pipeline
Webfont records (FAL files)
-> WebFontProcessor (page.headerData.2040.dataProcessing.20)
-> WebFontCssBuilder (validate + sanitize, build @font-face + :root CSS)
-> {webFontsCss} in Styles.html
-> <f:asset.css useNonce="1"> + mpc:format.cssSanitize
All values are checked against fixed whitelists in terms of WebFontCssBuilder (weighting, style, font-display, file format, custom variable name, unicode-range), and the family name, fallback and URL are sanitised to remove any characters that might fall outside the scope of the CSS declaration, ensuring that a value provided by an attacker can never be used in the inline <style> .
Restrictions
- CSP: Self-hosted fonts with
fileadminare ‘Same-Origin’ and are already restricted byfont-src 'self'inConfiguration/ContentSecurityPolicies.php. To serve fonts from a different domain, that origin must befont-srcvia a site-specificconfig/sites/<id>/csp.yaml. - Backend permissions: Administrators can edit the entries immediately. Backend groups without administrator rights require
tables_modify(andtables_select) fortx_mpcore_domain_model_webfontfamilyandtx_mpcore_domain_model_webfontface. - A family is only displayed if it contains at least one face with a resolvable font file; otherwise, the
:rootassignment is skipped (the family name alone would not load anything).
Website configuration (config.yaml)
In addition to the website settings, mp-core extends the website data set and website language by Configuration/SiteConfiguration/Overrides/sites.php. Configure these under ‘Site Management’ → ‘Sites’ → [Site] → ‘Configuration’ (or under config/sites/[site]/config.yaml).
| Section | Fields (examples) | Notes |
|---|---|---|
| Customisation | navType, subnav, subnavOrder, search, copyrightText | navType: 1 primary, 2 secondary, 3 tertiary |
| Favicons | favicon-96x96-png, faviconIco, faviconSvg, apple-touch-icon, webmanifest, … | File associations → Resources/Private/Partials/Page/Favicons.html (Favicons & Web App Manifest) |
| Colours & Styles | color-toggle, color-1…color-8, color-primary, styles | styles adds custom :root CSS; can be used with ColorPickerValueItems in TCA |
| Social Media | socialMediaSwitch, fields for platform URLs | are converted into SocialMediaProcessor / structured data |
| Logos | logoBig, logoSmall, logoSvg, logoText, logoTextHidden | Language-specific overrides for the website’s languages; implemented via HeaderLogoProcessor |
| structured data entity | extraEntityImage | FAL file reference for optional additional Schema.org entity (StructuredDataProcessor); type/name/keywords in the website settings |
Language-specific palettes: copyrightText, logo fields and logoText / logoTextHidden may vary depending on the website’s language.
TypoScript structure
Configuration/
├── ContentSecurityPolicies.php # Frontend CSP mutations auto-applied when
│ # the `security.frontend.*ContentSecurityPolicy`
│ # feature toggle is on (see "Content Security
│ # Policy" below)
├── Services.yaml # PSR-4 autowiring for `Mpc\MpCore\*`; explicit
│ # `public: true` for DataProcessors and the
│ # `ColorPickerValueItems` itemsProcFunc; optional
│ # `Services.local.yaml` import (see below)
├── Services.local.yaml # (optional, gitignored) local-only DI overrides
├── Sets/
│ ├── mp-core/
│ │ ├── config.yaml # Aggregator (depends on all feature sets)
│ │ ├── settings.yaml # Shared Site Settings defaults
│ │ ├── settings.definitions.yaml # Shared Site Settings schema
│ │ ├── constants.typoscript, setup.typoscript, page.tsconfig
│ ├── mp-core-base/
│ │ └── config.yaml # System deps + pointers to mp-core settings
│ ├── mp-core-container/
│ │ ├── config.yaml, settings.yaml, settings.definitions.yaml
│ │ ├── constants.typoscript, setup.typoscript
│ ├── mp-core-news/
│ │ ├── config.yaml, settings.yaml, settings.definitions.yaml
│ │ ├── constants.typoscript, setup.typoscript
│ ├── mp-core-form/
│ │ ├── config.yaml, settings.yaml, settings.definitions.yaml
│ │ ├── constants.typoscript, setup.typoscript
│ └── mp-core-seo/
│ ├── config.yaml, settings.yaml, settings.definitions.yaml
│ ├── constants.typoscript, setup.typoscript
├── TypoScript/
│ ├── constants.typoscript, setup.typoscript
│ ├── VueComponents.typoscript
│ ├── Helper/PageClass.typoscript
│ ├── Constants/*.typoscript
│ └── Setup/
│ ├── 10.Config, 20.Page, 30.Page.Styles, 40.Page.Scripts
│ ├── 50.Page.Navigation, 60.Lib, 90.CleanupRTE
│ ├── Page/*.typoscript
│ └── ContentElements/tt_content/*.typoscript
└── Extensions/
├── constants.typoscript, setup.typoscript
| File | Purpose |
|---|---|
10.Config | Basic TYPO3 configuration (character set, language, cache) |
20.Page | Page object, template paths, data processors |
30.Page.Styles | CSS inclusions |
40.Page.Scripts | JavaScript inclusions |
50.Page.Navigation | Bundles for conditional navigation |
60.Lib | Shared lib.* objects |
95.SitePresentationOverrides | SocialMediaProcessor, StructuredDataProcessor |
ContentElements/tt_content/* | Rendering of content elements, HeaderLogoProcessor |
Dependency injection (Services.yaml)
Configuration/Services.yaml automatically binds the Mpc\MpCore\* namespace and registers the services that TYPO3 needs to resolve outside the container as public: true:
| service | Why public: true |
|---|---|
Mpc\MpCore\DataProcessing\HeaderLogoProcessor | Is used by TypoScript via GeneralUtility::makeInstance() |
Mpc\MpCore\DataProcessing\SocialMediaProcessor | Immediately |
Mpc\MpCore\DataProcessing\StructuredDataProcessor | Equivalent |
Mpc\MpCore\Middleware\RobotsTxtMiddleware | Is resolved via the DI container from the PSR-15 middleware stack |
Mpc\MpCore\Middleware\LlmsTxtMiddleware | Equal |
Mpc\MpCore\UserFunc\ColorPickerValueItems | itemsProcFunc Callback |
DI overrides that are only valid locally (Services.local.yaml)
The delivered Services.yaml imports an optional sibling file with ignore_errors: not_found, so that projects can register locally scoped services (tooling commands, ad hoc helpers) without modifying the published file or interrupting container compilation if the file is missing:
# Configuration/Services.local.yaml (gitignored)
services:
Mpc\MpCore\Command\ImportDocumentationCommand:
tags:
- { name: console.command, command: 'docsite:import' }
Configuration/Services.local.yaml is listed in .gitignore listed for precisely this pattern.
Content Security Policy (ContentSecurityPolicies.php)
Configuration/ContentSecurityPolicies.php contains a strict front-end CSP, which
is automatically applied by TYPO3 13.4+ as soon as one of these feature toggles is enabled
(System -> Settings -> Feature Toggles):
security.frontend.enforceContentSecurityPolicy-- Enforcement modesecurity.frontend.reportContentSecurityPolicy-- Report-only mode
The included policy modifies the default TYPO3 front-end settings as follows:
| Directive | Change | Reason |
|---|---|---|
default-src | Set 'self' | Strict basic rule; anything for which there is no specific directive must come from the same source. |
script-src | Extend nonceProxy | Inline <script> Blocks (ThemeInit.html, JSON-LD <script type="application/ld+json">) are enclosed in <f:security.nonce()>. |
style-src | Extend nonceProxy | inline <style> blocks (colour overrides in Styles.html, element-specific background image in fluid_styled_content/Layouts/Container.html) <f:asset.css useNonce="1">. |
img-src | Extend data: | ‘Allow SCSS-emitted inline SVG fallbacks’ (svg-load) and Base64 placeholders. |
font-src | Set 'self' | All web fonts are self-hosted at Resources/Public/Fonts/. |
connect-src | Set 'self' | No XHR/fetch/WebSocket calls outside one’s own origin. |
object-src | Set 'none' | Block obsolete plugins (<object>, <embed>, <applet>). |
base-uri | Set 'self' | Preventing <base href> injection attacks. |
form-action | Set 'self' | Form postbacks are restricted to the same origin only. |
frame-ancestors | Set 'self' | Protection against clickjacking: no cross-origin embedding. |
Overrides per website
Operators can configure the policy per website via
config/sites/<id>/csp.yaml:
inheritDefault: true
mutations:
- mode: extend
directive: img-src
sources: ["https://cdn.example.com"]
- mode: extend
directive: form-action
sources: ["https://newsletter.example.com"]
configuration of the trust boundary colour for the website
inline CSS variables in Resources/Private/Partials/Page/Styles.html are now
forwarded via the mpc:format.cssColor ViewHelper, which is passed to
Mpc\MpCore\Service\CssColorValidator. Only syntactically valid CSS colours
(named, #rgb[a], #rrggbb[aa], rgb()/rgba()/hsl()/hsla()) are output;
incorrect or attacker-provided website configuration entries are silently
discarded, so that they never leave the inline <style> .
The same validator is also used in Mpc\MpCore\UserFunc\ColorPickerValueItems
, so that the backend colour picker’s drop-down menu also filters out invalid slots and
limits the labels to 200 characters.
Template path configuration
page.10 = FLUIDTEMPLATE
page.10 {
templateRootPaths {
0 = EXT:mp_core/Resources/Private/Templates/Page/
10 = {$settings.pageTemplates}
}
partialRootPaths {
0 = EXT:mp_core/Resources/Private/Partials/
10 = {$settings.pagePartials}
}
layoutRootPaths {
0 = EXT:mp_core/Resources/Private/Layouts/
10 = {$settings.pageLayouts}
}
}
Path priority: 0 = Core, 10 = Extension, 20+ = Project. Higher numbers take precedence over lower ones.
Overrides by extensions
plugin.tx_news.view.templateRootPaths.10 = EXT:mp_core/Resources/Extensions/news/Templates/
plugin.tx_form.view.templateRootPaths.10 = EXT:mp_core/Resources/Extensions/form/Templates/
plugin.tx_indexedsearch.view.templateRootPaths.10 = EXT:mp_core/Resources/Extensions/indexed_search/Templates/
Conditional configuration
Navigation bundles depend on the ‘Site Configuration’ field navType (see Configuration/SiteConfiguration/Overrides/sites.php):
navType | Layout |
|---|---|
1 | Primary navigation |
2 | Secondary navigation |
3 | Tertiary navigation |
[traverse(site("configuration"), "navType") == "1"]
page.includeJSFooter.navigationPrimary = EXT:mp_core/Resources/Public/JavaScripts/navigationPrimary.js
[END]
TCA overwrites
Quick overview
| File | Purpose |
|---|---|
tt_content_00_base.php | Wizard for global links, palettes, Vue TodoList CType |
tt_content_00_header.php | Advanced header options |
pages.php | Function button, teaser description, link icon |
sys_category.php | Assignment to main category on pages |
sys_file_metadata.php | RTE description, accessibility flag |
sys_file_reference.php | Outline and download options |
sys_template.php | Static TypoScript registration |
Page fields (pages.php)
| Field | Type | Description |
|---|---|---|
newsletter | Button to enable/disable | Newsletter sign-up field |
socialmedia | Checkbox | Social media sharing bar |
breadcrumb | Activation field | Breadcrumb navigation |
headercontainer | Enable/disable button | Header container layout |
teaser_description | Text field | Teaser/map description |
link_icon | File (SVG) | Icon for custom page link |
link_icon_background | Button to enable/disable | Icon background |
Global Link Wizard (tt_content_00_base.php)
| Field | Type | Options |
|---|---|---|
tx_link_switch | Toggle button | Enable/disable link |
tx_link | Link wizard | Page, file, URL, record |
tx_link_layout | Select | Primary/secondary/tertiary button, link styles |
tx_link_text | Text input | Custom link text |
tx_link_position | Select | Centre, Left, Right |
Palette: link_config
Custom content elements
| Element | File | Description |
|---|---|---|
| Gallery | tt_content_gallery.php | Responsive image galleries + lightbox |
| Stage | tt_content_stage.php | Hero sections (image/video backgrounds) |
| Banners | tt_content_banner.php | Customisable banner sections |
| Single teaser | tt_content_singleteaser.php | Content teasers with images/links |
| Accordion | tt_content_accordion.php | Collapsible sections (b13/container) |
| Tabs | tt_content_tabs.php | Tabs (b13/container) |
| Sliders | tt_content_slider.php | Swiper carousels (b13/container) |
| Grid | tt_content_grid.php | Flexible column layouts (b13/container) |
| Container | tt_content_container.php | Generic wrapper (b13/container) |
| To-Do list | tt_content_00_base.php | Vue.js 3 To-Do List (CType: mpcore_todolist) |
| Menu subpages | tt_content_menu_subpages.php | Extended subpage menu |
File metadata / links
| Table | Field | Description |
|---|---|---|
sys_file_metadata | description | RTE text description |
sys_file_metadata | is_accessible | Accessibility indicator |
sys_file_reference | outline | Show with border |
sys_file_reference | allow_download | Show download button |
Common customisation patterns
Adding a field to an existing element
$myColumns = [
'tx_my_field' => [
'label' => 'My Field',
'config' => ['type' => 'input', 'size' => 30],
],
];
ExtensionManagementUtility::addTCAcolumns('tt_content', $myColumns);
ExtensionManagementUtility::addToAllTCAtypes('tt_content', 'tx_my_field', 'textmedia', 'after:bodytext');
Database schema
Add columns ext_tables.sqland then run ‘Admin Tools’ -> ‘Maintenance’ -> ‘Analyse database structure’.
CREATE TABLE tt_content (
tx_my_field varchar(255) DEFAULT '' NOT NULL
);
Tips
- Use existing pallets from
tt_content_00_base.phpandtt_content_00_header.php - Prefix custom fields with
tx_to avoid conflicts - Use ‘
LLL:EXT:...’ references for all labels - Use ‘
displayCond’ for conditional field visibility:'displayCond' => 'FIELD:my_toggle:=:1' - Use ‘Site Settings’ instead of hard-coded TypoScript values
- Observe the path numbering:
0(Core),10(Extension),20+(Project)
Further information
- Backend – RTE, ‘TSconfig’ page, content preview
- Content elements – TCA field reference per CType
- Frontend – Build system and asset pipeline
- Favicons – Favicon generation
- TYPO3 TCA Reference
- TYPO3 Site Sets
- TYPO3 TypoScript Reference
- b13/container