Configuration 

Enabling the theme for a site 

The theme ships a site set. A site enables it by depending on that set in its config/sites/<identifier>/config.yaml:

dependencies:
  - sbuerk/theme-extension-development
Copied!

Nothing else is required. The set brings the TypoScript, the page rendering and the stylesheet with it, and no sys_template record is needed. The set itself declares neither dependencies nor settings — everything an integrator changes is a TypoScript constant, and those are described below.

In the backend the same set can be selected under Site Management > Sites in the Sets field of the site.

Installations without site sets 

For an installation that does not use site sets, the theme additionally registers a classic static template. Create a sys_template record on the root page and include Theme Extension Development in Include static (from extensions).

Both paths read the same TypoScript files, so what they deliver is identical.

Templates and stylesheet 

The Fluid paths and the stylesheet are TypoScript constants, so an integrator can render their own templates without editing the theme:

Constant Default
theme.templateRootPath EXT:theme_extension_development/Resources/Private/Templates/
theme.partialRootPath EXT:theme_extension_development/Resources/Private/Partials/
theme.layoutRootPath EXT:theme_extension_development/Resources/Private/Layouts/
theme.stylesheet EXT:theme_extension_development/Resources/Public/Css/theme.css
theme {
    templateRootPath = EXT:my_site_package/Resources/Private/Templates/
    partialRootPath = EXT:my_site_package/Resources/Private/Partials/
    layoutRootPath = EXT:my_site_package/Resources/Private/Layouts/
    stylesheet = EXT:my_site_package/Resources/Public/Css/my-theme.css
}
Copied!

The stylesheet is compiled from SCSS sources that ship with the extension, so it can also be rebuilt with different design tokens instead of being replaced — see Feature: Design tokens, with light and dark appearance.

Image width 

The image based elements scale their images to the width the layout gives the content column. That width is a constant, because nothing in TypoScript can read it out of the stylesheet:

theme.media {
    # The width in pixels the gallery is computed for.
    maxGalleryWidth = 1200

    # The same, for an element positioned beside the text.
    maxGalleryWidthInText = 420
}
Copied!

The default matches the 75rem of --theme-content-max-width. Set it too low and images are processed smaller than they are displayed, which shows. Set it far too high and every image is processed at a size no visitor ever sees.

Appearance and palette 

The theme renders in a light and a dark appearance and carries five colour palettes. What is rendered server side — before the frontend switcher can restore a visitor's choice from localStorage — is configured with three constants:

Constant Default Values
theme.appearance.default auto auto, light, dark
theme.appearance.palette neutral neutral, ember, ocean, moss, violet
theme.appearance.contentOutline on on, off

They are written onto the <html> tag as data-theme, data-palette and data-theme-content-outline. Two of those are worth knowing exactly:

  • auto renders no data-theme attribute at all. The appearance is then left to the operating system through color-scheme, which is what light-dark() in the stylesheet resolves against. A palette has no such case, so neutral is still written out.
  • contentOutline draws the labelled outline around every content element. Only off has a rule of its own; on is simply the absence of it. It is a development and staging affordance — a site package rendering for real visitors sets it to off.

See Feature: Appearance switcher for the switcher itself and Feature: Design tokens, with light and dark appearance for what the palettes are built from.

Backend layouts and page templates 

The theme ships five backend layouts through page TSconfig, and the layout an editor selects picks the Fluid template the page is rendered with:

Identifier Backend label Columns (colPos) Page template
default Default main (0) Page/Default.html
content Content page stage (2), main (0), footer 1-4 (11-14), footer meta (10) Page/Content.html
content_sidebar Content page with sidebar stage (2), main (0), sidebar (1), footer 1-4 (11-14), footer meta (10) Page/ContentSidebar.html
start Start page stage (2), main (0), footer 1-4 (11-14), footer meta (10) Page/Start.html
styleguide Styleguide unused (999) Page/Styleguide.html

The colPos numbers are a contract, not an implementation detail: the same number means the same slot in every layout, which is what lets an editor change a page's layout without content disappearing. The footer columns and the footer meta row slide down the rootline, so they are edited once on the start page and appear on every page below it.

The mapping is by convention rather than by configuration: the identifier is upper-camel-cased and prefixed with Page/, so a new layout needs a TSconfig file and a template of the matching name and nothing else. A page without a layout, and a page whose layout is TYPO3's built-in [None], both render with Page/Default.html.

See Feature: Backend layouts decide the page template.

Content elements 

The theme brings its own content element rendering and does not depend on fluid_styled_content — that extension is not required here, and on TYPO3 v14 it is not installed at all. What that covers:

Nothing an editor can create is left without a rendering definition, and a test asserts exactly that: it walks the content types registered in TCA and fails if the core's "no rendering definition" notice appears for any of them.

Demo content 

A page tree to look at is written by a console command rather than by hand:

vendor/bin/typo3 theme:seed
Copied!
Argument or option Default Meaning
definition EXT:theme_extension_development/Configuration/Seeds/Demo.yaml The YAML definition to write. An EXT: path is resolved.
--root-page 0 The page the definition is written below. 0 is the page tree root.
--force Seed even though the page tree is not empty. A definition declaring uids will collide.

The shipped definition seeds a start page, pages for typography and media, one page deliberately without a backend layout, a /elements branch carrying every content type, and a /styleguide page rendering the whole component library — see Feature: A seeded showcase of every element and Feature: A styleguide page. The definition format is described in Feature: Seed a page tree from a definition.