---
title: "Migration"
manual: "Headliner"
version: "main"
permalink: "https://docs.typo3.org/permalink/twtgroup/headliner:migration@main"
source: "Migration/Index.rst"
rendered: "2026-11-11T13:53:21+00:00"
---

# Migration {#migration}

## From the Semantilizer (z7_semantilizer) {#migration-semantilizer}

The Semantilizer keeps the type of a header in one field, `header_type` (0 to 6), and leaves `header_layout` for the look.
Headliner does the same with two fields, `header_tag` for the tag and `header_layout` for the look, so the content can be
taken over.

> [!IMPORTANT]
> Do not run both extensions side by side. Both override the header partial of `fluid_styled_content`, and the
> Semantilizer's partial wins, so the tags of headliner would have no effect in the frontend and the editor would see two
> fields for the same thing. Headliner therefore conflicts with `zeroseven/z7-semantilizer` in Composer. The order is:
> remove the Semantilizer, install headliner, run the wizard. The wizard does not need the Semantilizer: it reads the
> column `header_type`, which stays in the database.

> [!WARNING]
> Removing the Semantilizer does not delete its column `header_type`, but a destructive schema update does. Until the
> wizard has run, that column is the only place where the heading types are stored. In this order:
>
> 1.  Make a **backup of the database**.
> 1.  Make sure nothing runs a destructive schema update: `typo3 database:updateschema` without an argument (or with
>     `safe`) only adds and changes fields, while `destructive`, `"*"`, `field.drop` or `table.drop`, and the entries
>     to remove unused fields in **Analyze Database Structure**, delete the column. Look at the deployment
>     script, too.
> 1.  Remove the Semantilizer, install headliner and run the wizard (below).
> 1.  Check the result, and only then delete the unused column `header_type`, if you want to.
>
> The values cannot be taken over once the column is gone: they can then only be restored from the backup.

The upgrade wizard **Headliner: take the heading types of the Semantilizer (z7_semantilizer) into the tags of
headliner** does that:

```bash
vendor/bin/typo3 upgrade:run headlinerMigrateSemantilizerFields
```

You can also run it in **Admin Tools > Upgrade > Upgrade Wizard**. It is listed when the column `header_type` is
still in the database and there is something to change.

| `header_type` | `header_tag` |
| --- | --- |
| 1 to 6 | `h1` to `h6` |
| 0 (none) | `div`, like the Semantilizer, which renders every other value as a `div` |

-   The layout (`header_layout`) is the same field in both extensions and is not changed.
-   The Semantilizer has no field for the subheader (it renders it one level below its header), so there is nothing to take
    over and the subheader is not touched.
-   It fills only what is empty, which is what `header_tag` is until somebody chooses a tag. A tag that somebody has chosen
    since headliner was installed is kept, also an H2.
-   Run the wizard right after the Semantilizer was replaced. The column `header_type` has the default 2 and is no longer
    maintained once the Semantilizer is gone, so an element that is created afterwards has `header_type` 2 and no tag of
    headliner yet: a late run would turn it into an `h2` instead of taking its tag from the layout.
-   The wizard works on the column `header_type` of the database. That stays after the Semantilizer is removed, until the
    unused columns are deleted (**Analyze Database Structure**), so run the wizard before that.
-   It can run again, and changes nothing the second time.

What is left to do by hand:

1.  Remove the Semantilizer (`composer remove zeroseven/z7-semantilizer`) and add the site set
    `twtgroup/headliner` of headliner, then clear the caches (see [Installation](https://docs.typo3.org/permalink/twtgroup/headliner:installation@main)).
1.  Change the templates that use `<semantilizer:headline>` to `<headliner:headline>` (see [Your own templates](https://docs.typo3.org/permalink/twtgroup/headliner:integration-own-templates@main)).
    The simplest is `record="{record}"` (`record="{record}" subheader="1"` for the subheader): the tag, the layout and the
    mark for the page module come from the record. With the values it is `<headliner:headline.values
    tag="{data.header_tag}">` instead of `type="{data.header_type}"`, and `edit="tt_content:{data.uid}:header_tag"` if the
    page module is to change the tag.
1.  Check the CSS: headliner puts the class `ce-headline-layout-N` on a header, the Semantilizer `ce__header--N`.

## Finding the headings in your templates {#finding-the-headings-in-your-templates}

The command `headliner:scan-templates` lists the headings (`h1` to `h6`) in the Fluid templates of a project and says
which of them `headliner:headline` can replace. It only reads: no template is changed.

```bash
vendor/bin/typo3 headliner:scan-templates               # the whole project
vendor/bin/typo3 headliner:scan-templates packages/site # one directory
vendor/bin/typo3 headliner:scan-templates --with-static # also the headings with a fixed text
```

Every heading is listed with its file and line. A heading whose text is a field of a record
(`{record -> f:render.text(field: 'header')}`, `{data.header}`) gets the ViewHelper that replaces it
(`<headliner:headline record="{record}" />`, with `textField` for another field and `subheader="1"` for the subheader).
The attributes of the heading are listed too: a class has to be moved into the template around it or into the CSS,
because the ViewHelper puts the layout class only. A heading with another dynamic text (a translation, a formatted
value, several variables) is listed as needing a decision: there is no record the scanner could name.

The scanner skips comments, HTML files without Fluid, and the directories `vendor`, `node_modules`, `var`, `.Build`,
`typo3temp`, `sysext` and `_assets`. The suggestion assumes the variable is a record object; in a template where it is an
array, see [headliner:headline.row](https://docs.typo3.org/permalink/twtgroup/headliner:integration-headline-row@main) and [headliner:headline.values](https://docs.typo3.org/permalink/twtgroup/headliner:integration-headline-values@main).

> [!NOTE]
> The scanner is a helper, not a guarantee. It reads the markup with patterns, so it can miss a heading (one that is built
> by a partial, a ViewHelper or another extension) and it can suggest a call that does not fit (the variable is no
> record, the heading has markup around the text). Check every suggestion, and the rendered page, before you change a
> template.
