diff --git a/.gitattributes b/.gitattributes
new file mode 100644
index 0000000..5e9e6fe
--- /dev/null
+++ b/.gitattributes
@@ -0,0 +1,3 @@
+/.github export-ignore
+/.gitattributes export-ignore
+/.gitignore export-ignore
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
new file mode 100644
index 0000000..9093532
--- /dev/null
+++ b/.github/workflows/ci.yml
@@ -0,0 +1,37 @@
+name: CI
+
+on:
+ push:
+ branches:
+ - master
+ pull_request:
+
+jobs:
+ checks:
+ name: Checks (PHP ${{ matrix.php }})
+ runs-on: ubuntu-latest
+ strategy:
+ fail-fast: false
+ matrix:
+ php: ['8.1', '8.2', '8.3']
+ steps:
+ - name: Checkout
+ uses: actions/checkout@v4
+
+ - name: Setup PHP
+ uses: shivammathur/setup-php@v2
+ with:
+ php-version: ${{ matrix.php }}
+ tools: composer:v2
+ coverage: none
+
+ - name: Validate composer.json
+ run: composer validate --strict
+
+ - name: Lint PHP files
+ run: find . -name '*.php' -path './.git' -prune -o -name '*.php' -print0 | xargs -0 -n1 -P4 php -l
+
+ - name: Lint XLIFF files
+ run: |
+ sudo apt-get update -qq && sudo apt-get install -y --no-install-recommends libxml2-utils
+ find . -name '*.xlf' -print0 | xargs -0 -r -n1 xmllint --noout
diff --git a/Configuration/TCA/Overrides/tt_content.php b/Configuration/TCA/Overrides/tt_content.php
index da5630c..0b0a04b 100644
--- a/Configuration/TCA/Overrides/tt_content.php
+++ b/Configuration/TCA/Overrides/tt_content.php
@@ -37,6 +37,14 @@
'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.h6',
'value' => 6,
],
+ [
+ 'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.p',
+ 'value' => 7,
+ ],
+ [
+ 'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.span',
+ 'value' => 8,
+ ],
],
],
],
@@ -75,6 +83,14 @@
'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.h6',
'value' => 6,
],
+ [
+ 'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.p',
+ 'value' => 7,
+ ],
+ [
+ 'label' => 'LLL:EXT:headertypes/Resources/Private/Language/locallang.xlf:type.I.span',
+ 'value' => 8,
+ ],
],
],
],
diff --git a/README.md b/README.md
index f77bf7d..39752bf 100644
--- a/README.md
+++ b/README.md
@@ -1,7 +1,96 @@
-# EXT:headertypes
+
+
+# EXT:headertypes - Separate the semantic header type from the header layout
+
+## Features
+
+- Adds a dedicated **Header Type** field to content elements to control the semantic HTML tag (`
`–``) of a header
+- Adds a matching **Subheader Type** field for the subheader
+- Decouples the *semantics* of a heading from its *visual appearance*
+- Renames the TYPO3 Core "Header Layout" field to the clearer label **Layout** so editors understand it only affects styling
+- Ships as a lightweight, backend-only extension: it adds the fields, your site package renders them
+- Supports TYPO3 v12.4, v13 and v14 from a single extension version
+
+## Why did we create this extension?
+
+TYPO3 Core ships a single `header_layout` field for content headers. That one field is used for two very
+different things at once: it decides both *how a header looks* and *which HTML tag* is rendered (`` … ``).
+
+In real projects those two concerns pull apart:
+
+- A header that should look like a large "H2" for design reasons might still need to be an `` for a correct
+ document outline.
+- Accessibility and SEO depend on a clean, hierarchical heading structure that editors should not be forced to
+ break just to achieve a certain look.
+- Designers want freedom over typography without side effects on the semantic structure of the page.
+
+EXT:headertypes solves this by splitting the concern in two:
+
+- **Layout** (the existing `header_layout` field, relabeled) keeps controlling the *visual* appearance.
+- **Header Type** / **Subheader Type** (the new fields) control the *semantic* HTML tag.
+
+This lets editors pick, for example, "looks like a Layout 2 heading, but is semantically an ``" — cleanly and
+without templating hacks.
+
+## Installation
+
+Install this extension via `composer req b13/headertypes` or download it from the
+[TYPO3 Extension Repository](https://extensions.typo3.org/extension/headertypes/) and activate the extension in the
+Extension Manager of your TYPO3 installation.
+
+## How it works
+
+The extension adds two select fields to the `tt_content` table:
+
+| Field | Purpose | Values |
+|--------------------------------|-------------------------------|------------------------------------------------------------------------|
+| `tx_headertypes_headertype` | Semantic tag of the header | `0` = Default, `1`–`6` = `h1`–`h6`, `7` = `p`, `8` = `span` |
+| `tx_headertypes_subheadertype` | Semantic tag of the subheader | `0` = Default, `1`–`6` = `h1`–`h6`, `7` = `p`, `8` = `span` |
+
+Both fields are added to the Core `header` and `headers` palettes, so they appear directly next to the header input
+in the backend for every content element that uses those palettes. The value `0` ("Default") means "do not override" —
+your template should fall back to its normal header rendering in that case.
+
+The extension does **not** render anything in the frontend on its own. Rendering the chosen tag is the job of your
+site package or theme, which keeps the extension unopinionated and compatible across TYPO3 versions.
+
+## Frontend rendering
+
+To make the new fields take effect, override the header partial in your site package (for
+`fluid_styled_content` this is `Resources/Private/Partials/Header/Header.html`) and use
+`tx_headertypes_headertype` to choose the tag, while keeping `header_layout` for the visual class.
+
+```html
+EXT:my_sitepackage/Resources/Private/Partials/Header/Header.html
+
+
+
+
+
+
+
+
+
+
+
+ Header Type "Default" (0): fall back to your regular header_layout based rendering.
+
+
+
+```
+
+The same principle applies to the subheader via `{data.tx_headertypes_subheadertype}`.
+
+## Compatibility
+
+| Extension version | TYPO3 versions |
+|-------------------|-----------------------------|
+| 1.x | v12.4, v13, v14 |
## Credits
This extension was created by David Steeb in 2020 for [b13 GmbH, Stuttgart](https://b13.com).
-[Find more TYPO3 extensions we have developed](https://b13.com/useful-typo3-extensions-from-b13-to-you) that help us deliver value in client projects. As part of the way we work, we focus on testing and best practices to ensure long-term performance, reliability, and results in all our code.
+[Find more TYPO3 extensions we have developed](https://b13.com/useful-typo3-extensions-from-b13-to-you) that help us
+deliver value in client projects. As part of the way we work, we focus on testing and best practices to ensure
+long-term performance, reliability, and results in all our code.
diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf
index 88be125..1380287 100644
--- a/Resources/Private/Language/locallang.xlf
+++ b/Resources/Private/Language/locallang.xlf
@@ -1,6 +1,6 @@
-
+
diff --git a/composer.json b/composer.json
index b0f5c1f..41c3275 100644
--- a/composer.json
+++ b/composer.json
@@ -3,9 +3,26 @@
"type": "typo3-cms-extension",
"description": "Add a separate header type field to tt_content for headers and subheaders",
"license": ["GPL-2.0-or-later"],
+ "keywords": ["TYPO3 CMS", "header", "heading", "accessibility", "seo"],
+ "homepage": "https://b13.com",
+ "authors": [
+ {
+ "name": "David Steeb",
+ "email": "typo3@b13.com",
+ "role": "Developer"
+ }
+ ],
+ "support": {
+ "issues": "https://github.com/b13/headertypes/issues",
+ "source": "https://github.com/b13/headertypes"
+ },
"require": {
+ "php": "^8.1",
"typo3/cms-core": "^12.4 || ^13.0 || ^14.0"
},
+ "config": {
+ "sort-packages": true
+ },
"extra": {
"typo3/cms": {
"extension-key": "headertypes"