Feature: A seeded showcase of every element
Description
Feature: Seed a page tree from a definition writes a page tree from a YAML definition. The shipped
definition EXT:
now describes a tree that demonstrates the whole theme rather than a handful of
pages:
| Page | Backend layout | What it shows |
|---|---|---|
Theme demo (/) | Start page | The site root, and the footer columns that layout adds. |
Typography (/typography) | Content page | Headings, running text and the inline cases a stylesheet has to answer for. |
Media (/media) | Content page | A single image, and a two column gallery. |
Empty page (/empty) | none | A page with no layout selected, which falls back to the default. |
Elements (/elements) | Content page | The showcase branch, and the parent of the three pages below. |
Core elements (/elements/core) | Content page with sidebar | Every classic content element the theme renders, once each. |
Menu elements (/elements/menu) | Content page with sidebar | All eleven menu elements, each pointed at a different part of the tree so they are told apart by what they list. |
Theme elements (/elements/theme) | Content page | All ten elements the extension registers itself, with their inline children filled in. |
Styleguide (/styleguide) | Styleguide | The component library, rendered from Fluid rather than from content. |
Between them the pages use every backend layout the extension registers and carry every content type it renders, so a single seeded instance answers what the theme does with each. Two of the pages are deliberate special cases: Empty page selects no backend layout at all, which is the only way to see the default fallback, and Styleguide is set to Page not enabled in menus rather than disabled - a disabled page returns 404 in the frontend and is only reachable through a preview link, which defeats the point of seeding a page that exists to be opened.
Inline children in the seed format
Four of the theme's own content elements - Author,
Link list, Social links and Media teaser
grid - read their entries from an inline child table. A seed definition can
now describe those entries with a new structural key, inline: a map of the
field on the parent record to the child records declared for it.
content:
- identifier: showcase-linklist
CType: theme_linklist
header: 'Where to read more'
inline:
tx_theme_list_items:
- identifier: showcase-docs
table: tx_theme_list_item
link: 't3://page?uid=2'
link_label: 'Typography'
- identifier: showcase-media
table: tx_theme_list_item
link: 't3://page?uid=3'
link_label: 'Media'
Each child names the table it belongs to. That is never inferred from the
TCA of the parent's field, so a definition stays readable on its own and a
mistyped field name is reported rather than dereferenced. The children come out
in the order they are declared, and they may carry uid and files like
any other record.
The structural keys of the format are therefore identifier, uid,
children, content, files and inline, plus table on an inline
child. Everything else is a field of the record and is written as it stands -
which is why the backend layout and the "hide in menus" flag of the pages above
need nothing from the seeding at all.
Identifiers may no longer contain an underscore
An identifier in a seed definition may contain letters, digits and dashes,
and has to start with a letter or a digit. A definition using anything else is
now rejected with an exception naming the identifier.
This is not a style rule. The identifier ends up inside the placeholder
DataHandler is given for the record, and a placeholder used as the value of a
relation field is read as the <table>_<uid> form when it contains an
underscore - so NEWtt_content_home is split into a table NEWtt_content
and an id home, neither of which resolves. The relation is then written
empty, with nothing logged. Rejecting the identifier is what turns a seed
that silently loses its relations into one that refuses to run.
Two fixes come with it
Both failed silently, and both are now covered by a regression test:
- A declared
uidwas not honoured. DataHandler reads a suggested uid from the data map row and looks it up under a<table>:<uid>key; the seeding supplied neither, so the next free uid was assigned and the command reported whatever it got. That looked correct only for as long as the declaration order of a definition happened to match its insertion order. - File references were not ordered. The placeholder of a reference had
the same underscore problem, so
sorting_foreignstayed at 0 on every seeded reference and the order of a gallery with more than one image was left to the database.
Known limitation
Categorized pages and Categorized content are part of
the seeded tree but select nothing: the format expresses neither
sys_ records nor the MM rows relating them to a page or a
content element. Both elements render an empty menu, which is the correct
rendering of "no category chosen". Supporting this needs a way to declare
records outside the page tree and a relation between two of them, which is out
of proportion to demonstrating two elements.
Impact
vendor/bin/typo3 theme:seed produces a frontend that exercises the theme
end to end, so a development or test instance no longer needs pages built by
hand to see what an element looks like. Definitions of your own can describe
inline relations, and have to use identifiers without underscores.