1. Vorarbeiten und Ordnerstruktur erstellen
Grundlegende Ordnerstruktur
- Ordner
Sourceim OrdnerPrivateerstellen → Hier kommt die HTML-Vorlage hin - Ordner
Templatesim OrdnerPrivateerstellen mit den Unterordnern:Layouts→ Definiert den Rahmen einer Website (Struktur)Pages→ Fügen Inhalt in ein Layout ein, mehrere Templates für verschiedene Darstellungen nutzbar (Inhalte)Partials→ Kleinere, wiederverwendbare Abschnitte (Wiederverwendbarkeit)
Hinweis: Der Ordner Pages entspricht in der TYPO3-Ordnerstruktur dem, was hier als Templates beschrieben wurde.
Layout-Datei erstellen
Im Ordner Layout die Datei Default.html erstellen:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:spaceless>
<!-- Hier kommt das HTML aus der Source rein -->
<!-- Gleichbleibende Inhalte, wie Header oder Footer, gehören hier her -->
</f:spaceless>
</html>
Page-Template erstellen
Im Ordner Pages die Datei Default.html erstellen (wie oben, nur kommen hier später Inhalte rein). Für verschiedene Pages sind verschiedene Page-Templates möglich.
2. TypoScript-Konfiguration einrichten
Grunddateien erstellen
setup.typoscriptin Sets im Sitepackage-Ordner nebenconfig.yamlerstellen- Ordner
TypoScripterstellen - Ordner
TsConfigerstellen mit UnterordnernPageundUser
Basis-TypoScript konfigurieren
Im Ordner TypoScript die Datei page.typoscript erstellen:
page = PAGE
page.10 = TEXT
page.10.value = Text aus dem Sitesetup
In der setup.typoscript importieren:
@import "EXT:klht3sitepackage/Configuration/Sets/klht3sitepackage/TypoScript/*.typoscript"
Durch den Stern werden alle Skripte aus dem Ordner importiert, so kann man den Code modularer gestalten.
3. Layout und Template einbinden und verknüpfen
Page.typoscript anpassen
page = PAGE
page {
10 = PAGEVIEW
10 {
paths {
100 = EXT:vtklhsitepackage/Resources/Private/Templates/
}
}
}
Default.html im Pages-Ordner anpassen
Per ViewHelper das Layout einbinden:
<f:layout name="Default"/>
Layout definieren
In der Default.html im Layout-Ordner muss definiert werden, wo Inhalt hinkommen soll:
<f:render section="Main"/>
Complete Page-Template
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:spaceless>
<f:section name="Main">
### Hauptinhalt PAGES ###
</f:section>
</f:spaceless>
</html>
4. Metatags und Favicon einrichten
Metaangaben definieren
Metaangaben können als Eigenschaften des page-Objects im page.typoscript definiert werden:
page = PAGE
page {
meta {
viewport = width=device-width, initial-scale=1.0
}
headerData {
10 = TEXT
10.value (
<link href="{path:EXT:vtklhsitepackage/Resources/Public/img/favicon.png}" rel="icon">
<link href="{path:EXT:vtklhsitepackage/Resources/Public/img/apple-touch-icon.png}" rel="apple-touch-icon">
)
10.insertData = 1
}
10 = PAGEVIEW
10 {
paths {
100 = EXT:vtklhsitepackage/Resources/Private/Templates/
}
}
}
Titel übernimmt TYPO3, description und keywords laufen über die SEO-Extension, sofern sie genutzt wird.
5. Fonts lokal einbinden
Fonts im Public-Ordner unter fonts speichern und CSS vom Google Font Helper in main.css zu Beginn einfügen.
6. CSS und JavaScript einbinden
Im page-Object im page.typoscript mit includeCSS das CSS einbinden, JavaScript mit includeJSFooter. Minifizierte Dateien mit .disableCompression = 1 ausschließen:
page = PAGE
page {
meta {
viewport = width=device-width, initial-scale=1.0
}
headerData {
10 = TEXT
10.value (
<link href="{path:EXT:vtklhsitepackage/Resources/Public/img/favicon.png}" rel="icon">
<link href="{path:EXT:vtklhsitepackage/Resources/Public/img/apple-touch-icon.png}" rel="apple-touch-icon">
)
10.insertData = 1
}
includeCSS {
bootstrap = EXT:vtklhsitepackage/Resources/Public/vendor/bootstrap/css/bootstrap.min.css
bootstrap.disableCompression = 1
bootstrap-icons = EXT:vtklhsitepackage/Resources/Public/vendor/bootstrap-icons/bootstrap-icons.css
aos = EXT:vtklhsitepackage/Resources/Public/vendor/aos/aos.css
swiper = EXT:vtklhsitepackage/Resources/Public/vendor/swiper/swiper-bundle.min.css
swiper.disableCompression = 1
glightbox = EXT:vtklhsitepackage/Resources/Public/vendor/glightbox/css/glightbox.min.css
glightbox.disableCompression = 1
main = EXT:vtklhsitepackage/Resources/Public/css/main.css
}
includeJSFooter {
bootstrap = EXT:vtklhsitepackage/Resources/Public/vendor/bootstrap/js/bootstrap.bundle.min.js
bootstrap.disableCompression = 1
aos = EXT:vtklhsitepackage/Resources/Public/vendor/aos/aos.js
purecounter = EXT:vtklhsitepackage/Resources/Public/vendor/purecounter/purecounter_vanilla.js
waypoints = EXT:vtklhsitepackage/Resources/Public/vendor/waypoints/noframework.waypoints.js
swiper = EXT:vtklhsitepackage/Resources/Public/vendor/swiper/swiper-bundle.min.js
swiper.disableCompression = 1
glightbox = EXT:vtklhsitepackage/Resources/Public/vendor/glightbox/js/glightbox.min.js
glightbox.disableCompression = 1
imagesloaded = EXT:vtklhsitepackage/Resources/Public/vendor/imagesloaded/imagesloaded.pkgd.min.js
imagesloaded.disableCompression = 1
isotope = EXT:vtklhsitepackage/Resources/Public/vendor/isotope-layout/isotope.pkgd.min.js
isotope.disableCompression = 1
main = EXT:vtklhsitepackage/Resources/Public/js/main.js
}
10 = PAGEVIEW
10 {
paths {
100 = EXT:akoesitepackage/Resources/Private/Templates/
}
}
}
7. Inhalte im Template ausgeben
Variables im PAGEVIEW-Object definieren
10 = PAGEVIEW
10 {
paths {
100 = EXT:akoesitepackage/Resources/Private/Templates/
}
variables {
content0 = CONTENT
content0 {
table = tt_content
select {
where = {#colPos} = 0
orderBy = sorting
}
}
}
}
ViewHelper im Fluid-Template integrieren
<f:section name="Main">
<f:format.raw>{content0}</f:format.raw>
</f:section>
Es gibt unterschiedliche Notationen, gegebenenfalls in der Dokumentation nachschauen.
8. Rendering der Content-Elemente anpassen
Layout anpassen
Default.htmlausvendor/typo3/cms-fluid-styled-content/Resources/Private/Layoutskopieren- Im Sitepackage unter
Resources/Private/Extensions/fluid_styled_content/Layoutsablegen lib.contentElement.typoscripterstellen:
lib.contentElement {
layoutRootPaths {
100 = EXT:akoesitepackage/Resources/Private/Extensions/fluid_styled_content/Layouts/
}
}
9. Backend-Layouts erstellen
Backend-Layout definieren
In TsConfig/Page eine Datei backend_layouts.tsconfig erstellen:
mod.web_layout.BackendLayouts {
sidebar {
title = Sidebar right
config {
backend_layout {
colCount = 3
rowCount = 1
rows {
1 {
columns {
1 {
name = Normal
colspan = 2
colPos = 0
}
2 {
name = Sidebar
colPos = 1
}
}
}
}
}
}
}
}
Page.tsconfig einbinden
page.tsconfig auf Ebene von setup.typoscript erstellen:
@import "EXT:akoesitepackage/Configuration/Sets/akoesitepackage/TsConfig/Page/*.tsconfig"
Sidebar-Template erstellen
Sidebar.html unter Templates/Pages erstellen:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:layout name="Default" />
<f:spaceless>
<f:section name="Main">
<div class="container">
<div class="row">
<div class="col-lg-8">
<f:format.raw>{content0}</f:format.raw>
</div>
<div class="col-lg-4">
<f:format.raw>{content1}</f:format.raw>
</div>
</div>
</div>
</f:section>
</f:spaceless>
</html>
Page.typoscript für Sidebar anpassen
variables {
content0 = CONTENT
content0 {
table = tt_content
select {
where = {#colPos} = 0
orderBy = sorting
}
}
content1 < .content0
content1.select.where = {#colPos} = 1
}
10. Logo mit Link im Header-Bereich
Logo einbinden
Slash im href-Attribut führt immer zur Startseite. Image per ViewHelper einbinden:
<f:image src="EXT:akoesitepackage/Resources/Public/img/logo.svg"/>
Wenn height- oder width-Attribute unerwünscht sind:
<img src="{f:uri.resource(path: 'EXT:akoesitepackage/Resources/Public/img/logo.svg')}"
alt="Logo Beschreibung" />
11. Hauptmenü mit dataProcessor
DataProcessing konfigurieren
dataProcessing.typoscript im TypoScript-Ordner erstellen:
page.10.dataProcessing {
10 = menu
10 {
as = mainMenu
expandAll = 1
levels = 3
}
}
Mit <f:debug>{mainMenu}</f:debug> kann im Frontend geprüft werden, ob die Daten übermittelt werden.
MainMenu-Partial erstellen
MainMenu.html im Partials-Ordner erstellen und im Layout mit <f:render partial="MainMenu" arguments="{_all}"/> einfügen:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:spaceless>
<nav id="navmenu" class="navmenu">
<ul>
<f:for each="{mainMenu}" as="item">
<f:render section="MenuItem" arguments="{_all}"/>
</f:for>
</ul>
<i class="mobile-nav-toggle d-xl-none bi bi-list"></i>
</nav>
<a class="btn-getstarted" href="about.html">Get Started</a>
<form id="search-form" name="searchForm" class="search-form ms-4">
<input type="text" name="searchQuery" placeholder="Search..." class="form-control"/>
<button type="submit" class="btn"><i class="bi bi-search"></i></button>
</form>
<f:section name="MenuItem">
<li class="{f:if(condition: item.children, then: 'dropdown')}">
<f:link.typolink parameter="{item.data.uid}" class="{f:if(condition: item.current, then: 'active')}">
<f:if condition="{item.children}">
<span>
</f:if>
{item.title}
<f:if condition="{item.children}">
</span> <i class="bi bi-chevron-down toggle-dropdown"></i>
</f:if>
</f:link.typolink>
<f:if condition="{item.children}">
<ul>
<f:for each="{item.children}" as="item">
<f:render section="MenuItem" arguments="{_all}"/>
</f:for>
</ul>
</f:if>
</li>
</f:section>
</f:spaceless>
</html>
Durch den rekursiven Aufruf der Section können mehrere Ebenen abgebildet werden. Der dataProcessor berücksichtigt die rootPage nicht, daher einen Shortlink anlegen, der auf diese verweist.
12. Metamenü mit dataProcessor
Vorbereitung
- Seitentrenner im Seitenbaum als Einstieg erstellen (nicht in Menüs anzeigen, ID notieren)
- Darunter die Seiten einfügen
Metamenü konfigurieren
In dataProcessing.typoscript das Menü anlegen:
20 = menu
20 {
as = metaMenu
special = directory
special.value = 17
levels = 1
}
Mit <f:debug>{metaMenu}</f:debug> im Frontend prüfbar.
Partial und CSS
<ul class="metaMenu">
<f:for each="{metaMenu}" as="item">
<li>
<f:link.typolink parameter="{item.data.uid}" class="{f:if(condition: item.current, then: 'active')}">{item.title}</f:link.typolink>
</li>
</f:for>
</ul>
/* MetaMenu */
ul.metaMenu {
list-style-type: none;
padding: 0;
}
ul.metaMenu li {
display: inline-block;
padding: 0 .1rem;
}
@media (min-width: 400px) {
ul.metaMenu li {
padding: 0 .5rem;
}
}
13. Settings für das Site Set definieren
Settings.definitions.yaml erstellen
categories:
akoesitepackage:
label: 'Akoe Sitepackage'
akoesitepackage.pageUids:
label: 'Specific Page Uids'
parent: akoesitepackage
akoesitepackage.headerButton:
label: 'Button in main navigation'
parent: akoesitepackage
settings:
akoesitepackage.metaMenuUid:
category: akoesitepackage.pageUids
label: 'UID of the meta navigation separator'
type: int
default: 17
akoesitepackage.buttonText:
category: akoesitepackage.headerButton
label: 'Button text'
type: string
default: ''
akoesitepackage.buttonLink:
category: akoesitepackage.headerButton
label: 'Link target'
type: string
default: ''
Variable im dataProcessor verwenden
20 = menu
20 {
as = metaMenu
special = directory
special.value = {$akoesitepackage.metaMenuUid}
levels = 1
}
Settings in Fluid auswerten
<f:if condition="{settings.akoesitepackage.buttonText} && {settings.akoesitepackage.buttonLink}">
<f:link.typolink class="btn-getstarted" parameter="{settings.akoesitepackage.buttonLink}">
{settings.akoesitepackage.buttonText}
</f:link.typolink>
</f:if>
14. Rootline-Navigation (Breadcrumb)
DataProcessor konfigurieren
Im dataProcessing.typoscript ein neues Menü anlegen:
30 = menu
30 {
as = rootlineMenu
special = rootline
special.range = 0|-1
}
Breadcrumb-Partial erstellen
Die Navigation am besten in ein Partial auslagern, auf der Startseite wird diese über den Vergleich von page.id und rootPageId ausgeblendet:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:spaceless>
<f:if condition="{page.id} != {site.rootPageId}">
<div class="page-title light-background">
<div class="container">
<nav class="breadcrumbs">
<ol>
<f:for each="{rootlineMenu}" as="item">
<li>
<f:if condition="{f:if(condition: item.current, then: 'current')}">
<f:then>{item.title}</f:then>
<f:else>
<f:link.typolink parameter="{item.data.uid}">{item.title}</f:link.typolink>
</f:else>
</f:if>
</li>
</f:for>
</ol>
</nav>
</div>
</div>
</f:if>
</f:spaceless>
</html>
15. Body-Tag erweitern
ID und Klasse hinzufügen
Im page.typoscript:
bodyTagCObject = TEXT
bodyTagCObject.dataWrap = <body id="uid{field:uid}" class="pid{field:pid}">
16. Bildkonfiguration
Ausgabegröße und Lightbox
settings.yaml im Sitepackage:
styles:
content:
textmedia:
maxW: 1296
maxWInText: 648
linkWrap:
lightboxEnabled: true
lightboxCssClass: glightbox
width: 1280m
height: 1280m
Responsive Images
- Ordner
Partials/Media/Renderingerstellen Image.htmlvon fluid-styled-content hineinkopieren- Klasse
img-fluidergänzen:
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true">
<f:media class="image-embed-item img-fluid" file="{file}" width="{dimensions.width}" height="{dimensions.height}" alt="{file.alternative}" title="{file.title}" loading="{settings.media.lazyLoading}" decoding="{settings.media.imageDecoding}" />
</html>
partialRootPathsinlib.contentElementergänzen:
lib.contentElement {
layoutRootPaths {
100 = EXT:akoesitepackage/Resources/Private/Extensions/fluid_styled_content/Layouts/
}
partialRootPaths {
100 = EXT:akoesitepackage/Resources/Private/Extensions/fluid_styled_content/Partials/
}
}
17. 404-Fehlerseite
- 404-Seite anlegen
- In den Site Settings das Error Handling einstellen
18. Code im Head-Bereich
HeaderData konfigurieren
page.headerData.typoscript erstellen (Timestamp als Identifier: date +%s in der Shell eingeben):
page.headerData {
1746805775 = TEXT
1746805775.value (
<!-- Hier könnte dein Code stehen -->
)
}
19. Header-Kommentar ergänzen
Config.typoscript erstellen
Text ganz nach links einrücken, sonst gibt es Darstellungsfehler:
config {
headerComment (
Seite erstellt von Klaus Hesbacher
Web: https://www.klaus-hesbacher.de
Mail: klaus.heba@web.de
)
}
20. Nützliches PageTsConfig
TCEFORM.tsconfig
TCEFORM {
tt_content {
header_layout {
altLabels {
1 = H1 Überschrift
2 = H2 Überschrift
3 = H3 Überschrift
4 = H4 Überschrift
5 = H5 Überschrift
6 = H6 Überschrift
}
}
/* Entfernt Elemente aus der Übersicht
CType {
removeItems = header
}
*/
}
}
TCAMAIN.tsconfig
TCEMAIN {
table {
tt_content {
disableHideAtCopy = 1
disablePrependAtCopy = 1
}
pages {
disableHideAtCopy = 1
disablePrependAtCopy = 1
}
}
}
TCAdefaults.tsconfig
TCAdefaults {
pages {
hidden = 0
}
}
Achtung: Nur während der Entwicklung so verwenden, im Live-System ergibt es Sinn, dass Seiten erst einmal nicht sichtbar sind.
21. Nützliches UserTsConfig
user.tsconfig im Ordner Configuration
## https://docs.typo3.org/m/typo3/reference-typoscript/13.4/en-us/UserTsconfig/Index.html
options {
clearCache.pages = 1
pageTree {
showPageIdWithTitle = 1
}
}
22. CSS für Responsive Videos
Video-Embed CSS
/* Responsive Videos mit Fluid Styled Content */
.video-embed {
position: relative;
padding-bottom: 56.25%;
height: 0;
overflow: hidden;
margin-bottom: 1.5rem;
}
.video-embed iframe,
.video-embed video {
position: absolute;
top: 0;
left: 0;
max-width: 100%;
width: 100% !important;
height: 100% !important;
}
.ce-center:has(.video-embed) .ce-inner {
position: relative;
float: none;
right: -50%;
}
.ce-left:has(.video-embed) .ce-gallery,
.ce-column:has(.video-embed) {
float: none;
}
.ce-center:has(.video-embed) .ce-outer {
position: relative;
float: none;
right: 50%;
}
.ce-center:has(figure.video) figure.video {
display: block;
}