Seitentemplate mit Typo3 10.4
Im Web findet man an vielen Stellen vorgefertigte Templates aus HTML und CSS, die man für eigene Projekte nutzen kann. Eine Recherche mit den Stichworten free css template führt schnell zu einer Reihe von Ergebnissen. Unter https://cms-1.org/dokumentation/cmsms-templates/freie-templates.html findet sich eine Übersicht über mehrere derartige Angebote.
Eine schöne Quelle für ein funktionsfähiges System ist unter https://www.bootstrap-package.com/de/ zu finden.
Nach meinen Erfahrungen mit Typo3 ist es aber sinnvoll auf Extensions möglichst zu verzichten, die nicht zu Typo3 gehören. Zu oft habe ich schon erlebt, dass eine für meine Konfiguration wichtige Erweiterung nicht mehr weiter gepflegt wird. Ganz ohne fremde Extension komme ich aber auch nicht aus, momentan sind die gridelements die Extension von der meine Layouts abhängen.
Der folgende Text beschreibt den Aufbau meiner Seiten, wobei ich dafür noch auf Bootstrap3 setze, aus Kompatibilitätsgründen mit den vorhandenen Installationen. Die Änderungen im Bootstrap4 habenn nämlich eine Reihe von Veränderungen im Typoscript zur Folge, speziell bei den Menüs und natürlich im CSS.
Die Vorlage
Die folgende Beschreibung geht von einem selbst erstellten Template auf Basis von Twitter Bootstrap aus, die folgendes Aussehen hat.
Die Farben folgen keinen künstlerischen Ansprüchen, sondern sollen nur das Auffinden der einzelnen Elemente in der CSS-Datei erleichtern und damit auch die individuelle Anpassung.
Alle individuellen Dateien befinden sich im Verzeichnis nettemplate unterhalb von fileadmin. Das hat den Hintergrund, dass ich das Layout auch als Distribution anbieten möchte und dabei gibt es die Möglichkeit bei der Installation Dateien in einen Unterordner von fileadmin kopieren zu lassen, der den gleichen Namen hat wie die Distribution. In diesem Bereich hat man auch vom Backend aus einfachen Zugriff auf die Dateien, ohne unnötig die Zugriffspfade erweitern zu müssen.
Das Paket ist im TER unter https://typo3.org/extensions/repository/view/nettemplate herunter ladbar.
Ich habe möglichst viele Dateien in das Verzeichnis fileadmin/nettemplate gelegt, damit sie bequem über die Funktion Dateiliste editierbar werden. Dazu muss man die Dateien in der Distribution nur im Verzeichnis Initialisation/Files ablegen. Beim Aktivieren der Extension wird dieser Ordner dann unter dem Namen der Extension nach fileadmin kopiert. Manche Typoscript-Dateien habe ich unter EXT:nettemplate/Configuration belassen, sie binden dann von dort aus die entsprechenden Dateien im fileadmin Bereich ein.
fileadmin/nettemplate
|-- Resources
|-- indexed_search
|-- news
|-- gridelements
|-- Private
|-- Layouts
|-- Partials
|-- Templates
|-- Public
|-- Bilder
|-- Css
|-- Fonts
|-- JavaScript
|-- Configuration
|-- TypoScript
Das Archiv beinhaltet einige Unterordner, die sich im Prinzip an die Konventionen halten. Das eigene Layout befindet sich im Verzeichnis Resources und den Unterordnern. Die Ordner indexed_search, news und gridelements enthalten die Dateien zur Anpassung der Gestaltung der entsprechenden Extensionen.
Das Verzeichnis Initialisation/Files aus der Erweiterung wird bei der Installation in den Ordner fileadmin/ kopiert, als Unterordner nettemplate.
Was bisher nicht klappt, ist das Kopieren der Site-Einstellungen, das muss man also per Hand nachholen:
cd typo3conf cp -a ext/nettemplate/Initialisation/sites/ .
Layouts mit Fluid
Ein Fluid-Layout findet sich üblicherweise in einem Verzeichnis Resources. Dieses Verzeichnis besitzt dann die beiden Unterordner Private und Public. Im Ordner Public befinden sich alle Dateien, die unverändert an den Browser ausgeliefert werden, also Bilder, Css, Fonts und Javascript. Der Übersichtlichkeit halber befinden sich diese Elemente jeweils wieder in eigenen Unterverzeichnissen.
Der Aufbau des Layouts wird über die Elemente im Ordner Private definiert. Direkt referenziert werden die Templates aus dem gleichnamigen Ordner. Jedes dieser Templates ist dann Teil eines Layouts, hier werden die Dinge festgelegt, die bei allen Templates gleich sind. Im Ordner Partials finden sich dann Teile des Layouts, die in mehreren Templates identisch benötigt werden, also z.B. die Beschreibung für den Footer.
Die Dateinmane, z.B. der Partials, müssen auf .html enden. Aber beim Aufruf des Partials muss man jeweils die Endung weglassen.
Für diese Distribution habe ich möglichst alle Dateien entsprechend im Verzeichnis fileadmin/nettemplate angelegt.
Hinweis: Seit Typo3 8.7.x müssen die Dateinamen der Partials mit einem Großbuchstaben beginnen.
ext_emconf.php
<?php
/***************************************************************
* Extension Manager/Repository config file for ext "nettemplate".
*
* Auto generated 08-11-2020 18:00
*
* Manual updates:
* Only the data in the array - everything else is removed by next
* writing. "version" and "dependencies" must not be touched!
***************************************************************/
$EM_CONF[$_EXTKEY] = array (
'title' => 'Netthelp Template',
'description' => 'Fluid Templates from Netthelp. Please read the documentation before installing.',
'category' => 'distribution',
'author' => 'Uwe Debacher',
'author_email' => 'typo3@debacher.de',
'state' => 'beta',
'uploadfolder' => false,
'createDirs' => '',
'clearCacheOnLoad' => 0,
'version' => '2.0.3',
'constraints' =>
array (
'depends' =>
array (
'typo3' => '7.6.0-10.9.99',
'gridelements' => '',
'news' => '',
'indexed_search' => '',
'recycler' => '',
'filemetadata' => '',
),
'conflicts' =>
array (
),
'suggests' =>
array (
),
),
'clearcacheonload' => false,
'author_company' => NULL,
);
ext_localconf.php
In dieser Datei können Typoscript-Dateien aufgerufen werden.
<?php
if (!defined('TYPO3_MODE')) { die('Access denied.'); }
call_user_func(
function ($extConfString) {
// Add pageTS config
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPageTSConfig('<INCLUDE_TYPOSCRIPT: source="FILE:EXT:nettemplate/Configuration/TypoScript/tsconfig.ts">');
// Setup (nicht notwendig, geht automatisch über Statische Templates einschließen ...)
// \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('nettemplate','setup',' <INCLUDE_TYPOSCRIPT: source="FILE:EXT:nettemplate/Configuration/TypoScript/setup.txt">');
//Konstanten (nicht notwendig, geht automatisch über Statische Templates einschließen ...)
// \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addTypoScript('nettemplate','constants',' <INCLUDE_TYPOSCRIPT: source="FILE:EXT:nettemplate/Configuration/TypoScript/constants.txt">');
// Get ext configuration
// strlen($extConfString)?$extConf = unserialize($extConfString):$extConf = array();
},$_EXTCONF
);
?>
ext_tables.php
<?php
defined('TYPO3_MODE') || die();
call_user_func(function()
{
/**
* Extension key
*/
$extensionKey = 'nettemplate';
/**
* Default TypoScript
*/
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
$extensionKey,
'Configuration/TypoScript',
'Netthelp Template'
);
});
Layout und Templates
Die Templates beziehen sich alle auf ein Layout. Dieses Layout befindet sich im Ordner
fileadmin/nettemplate/Resources/Private/Layouts/
Die Templates bfinden Sich dann im Ordner
fileadmin/nettemplate/Resources/Private/Templates
Layout: DefaultLayout.html
Das einzige Layout baut sich momentan nach folgendem Schema auf.
<f:render section="inhalt" />
Hier könnte man natürlich deutlich mehr Zeilen unterbringen, z.B. für den Kopf der Seite.
Template: zweispaltig.html
<f:layout name="DefaultLayout" />
<f:section name="inhalt">
<div id="zweispaltig">
<div class="container">
<div class="row" id="header">
<div class="col-md-12"><f:cObject typoscriptObjectPath="lib.field_headerimage" /></div>
</div>
<f:render partial="navbar" />
<f:render partial="service" />
<f:render partial="rootline" />
<div id="inhalt" class="row equalheight">
<div class="col-md-3 equal" id="spalte-links">
<div id="menu-links">
<a id="subnav" name="subnav"></a><ul class="nav nav-pills nav-stacked" role="tablist">
<f:cObject typoscriptObjectPath="lib.field_submenu" />
</ul>
</div>
<div id="inhalt-links">
<!--TYPO3SEARCH_begin-->
<f:format.raw>{inhaltLinks}</f:format.raw>
<!--TYPO3SEARCH_end-->
</div>
</div>
<div class="col-md-9 equal" id="hauptinhalt">
<a id="content" name="content"></a>
<!--TYPO3SEARCH_begin-->
<f:if condition="{data.subtitle}">
<f:then><h1 class="pagetitle">{data.subtitle}</h1><br></f:then>
<f:else><h1 class="pagetitle">{data.title}</h1><br></f:else>
</f:if>
<f:format.raw>{hauptInhalt}</f:format.raw>
<!--TYPO3SEARCH_end-->
<p style="font-size:0px"> <p>
</div>
</div>
<f:render partial="footer" />
</div>
</div>
</f:section>
In meinem Ordner Templates habe ich noch zwei weitere Vorlagendateien liegen.
Template: einspaltig.html
<f:layout name="DefaultLayout" />
<f:section name="inhalt">
<div id="einspaltig">
<div class="container">
<div class="row" id="header">
<div class="col-md-12"><f:cObject typoscriptObjectPath="lib.field_headerimage" /></div>
</div>
<f:render partial="navbar" />
<f:render partial="service" />
<f:render partial="rootline" />
<div id="inhalt" class="row equalheight">
<div class="col-md-12 equal" id="hauptinhalt">
<a id="content" name="content"></a>
<!--TYPO3SEARCH_begin-->
<f:if condition="{data.subtitle}">
<f:then><h1 class="pagetitle">{data.subtitle}</h1><br></f:then>
<f:else><h1 class="pagetitle">{data.title}</h1><br></f:else>
</f:if>
<f:format.raw>{hauptInhalt}</f:format.raw>
<!--TYPO3SEARCH_end-->
<p style="font-size:0px"> <p>
</div>
</div>
<f:render partial="footer" />
</div>
</div>
</f:section>
Template: dreispaltig.html
<f:layout name="DefaultLayout" />
<f:section name="inhalt">
<div id="dreispaltig">
<div class="container">
<div class="row" id="header">
<div class="col-md-12"><f:cObject typoscriptObjectPath="lib.field_headerimage" /></div>
</div>
<f:render partial="navbar" />
<f:render partial="service" />
<f:render partial="rootline" />
<div id="inhalt" class="row equalheight">
<div class="col-md-3 equal" id="spalte-links">
<div id="menu-links">
<a id="subnav" name="subnav"></a>
<ul class="nav nav-pills nav-stacked" role="tablist">
<f:cObject typoscriptObjectPath="lib.field_submenu" />
</ul>
</div>
<div id="inhalt-links">
<!--TYPO3SEARCH_begin-->
<f:format.raw>{inhaltLinks}</f:format.raw>
<!--TYPO3SEARCH_end-->
</div>
</div>
<div class="col-md-6 equal" id="hauptinhalt">
<a id="content" name="content"></a>
<f:if condition="{data.subtitle}">
<f:then><h1 class="pagetitle">{data.subtitle}</h1><br></f:then>
<f:else><h1 class="pagetitle">{data.title}</h1><br></f:else>
</f:if>
<!--TYPO3SEARCH_begin-->
<f:format.raw>{hauptInhalt}</f:format.raw>
<!--TYPO3SEARCH_end-->
<p style="font-size:0px"> <p>
</div>
<div class="col-md-3 equal" id="spalte-rechts">
<!--TYPO3SEARCH_begin-->
<f:format.raw>{inhaltRechts}</f:format.raw>
<!--TYPO3SEARCH_end-->
</div>
</div>
<f:render partial="footer" />
</div>
</div>
</f:section>
Auswahl und Zuordnung der Templates
Da anscheinend keine direkte Auswahl des Templates im Backend vorgesehen ist, geht man hier einen kleinen Umweg. Für die Auswahl zwischen mehrspaltigen Templates ist es generell sehr praktisch, wenn auch im Backend nur die benötigte Anzahl an Spalten vorhanden ist. Die Gestaltung solcher Backend-Layouts ist vorgesehen. Für die Auswahl des Backend-Layouts gibt es auch ein Feld in den Seiteneigenschaften. Im Typoscript zur Gestaltung kann man dann auf diese Einstellung Bezug nehmen.
Erstellung von Backend-Layouts - tsconfig.ts
Für die Distribution habe ich drei Layouts in die Datei EXT:nettemplate/Configuration/Typoscript/tsconfig.ts ausgelagert:
mod.web_layout.BackendLayouts {
Einspaltig {
title = Einspaltig
icon = fileadmin/nettemplate/Resources/Public/Bilder/lspalten1.png
config {
backend_layout {
colCount = 1
rowCount = 1
rows {
1 {
columns {
1 {
name = Hauptinhalt
colPos = 0
allowed = header,text,textpic,image,textmedia,bullets,table,uploads,menu_abstract,menu_categorized_content,menu_categorized_pages,menu_pages,menu_subpages,menu_recently_updated,menu_related_pages,menu_section,menu_section_pages,menu_sitemap,menu_sitemap_pages,shortcut,list,div,html,login,form_formframework,gridelements_pi1
}
}
}
}
}
}
}
Zweispaltig {
title = Zweispaltig
icon = fileadmin/nettemplate/Resources/Public/Bilder/lspalten2.png
config {
backend_layout {
colCount = 3
rowCount = 1
rows {
1 {
columns {
1 {
name = Inhalt unter linkem Menü
colPos = 1
allowed = header,text,textpic,image,textmedia,bullets,table,uploads,menu_abstract,menu_categorized_content,menu_categorized_pages,menu_pages,menu_subpages,menu_recently_updated,menu_related_pages,menu_section,menu_section_pages,menu_sitemap,menu_sitemap_pages,shortcut,list,div,html,login,form_formframework,gridelements_pi1
}
2 {
name = Hauptinhalt
colspan = 2
colPos = 0
allowed = header,text,textpic,image,textmedia,bullets,table,uploads,menu_abstract,menu_categorized_content,menu_categorized_pages,menu_pages,menu_subpages,menu_recently_updated,menu_related_pages,menu_section,menu_section_pages,menu_sitemap,menu_sitemap_pages,shortcut,list,div,html,login,form_formframework,gridelements_pi1
}
}
}
}
}
}
}
Dreispaltig {
title = Dreispaltig
icon = fileadmin/nettemplate/Resources/Public/Bilder/lspalten3.png
config {
backend_layout {
colCount = 4
rowCount = 1
rows {
1 {
columns {
1 {
name = Inhalt unter linkem Menü
colPos = 1
### allowed = undefined das muss weg
}
2 {
name = Hauptinhalt
colspan = 2
colPos = 0
### allowed = undefined das muss weg
}
3 {
name = Rechte Spalte
colPos = 2
}
}
}
}
}
}
}
}
Mir ist nicht ganz klar, ob man bei allowed alle Typen angeben muss, oder undefined stehen lässt oder ganz auf die Zeile verzichtet. Damit werde ich mich aber erst später auseinander setzen.
Das Typoscript dazu
Das Typoscript-Template auf der Root-Seite (s.u.) muss nun erweitert werden:
file.stdWrap.cObject = CASE
file.stdWrap.cObject {
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
# key.data = pagelayout
default = TEXT
default.value = {$resDir}/Private/Templates/einspaltig.html
pagets__Einspaltig < .default
pagets__Zweispaltig < .default
pagets__Zweispaltig.value = {$resDir}/Private/Templates/zweispaltig.html
pagets__Dreispaltig < .default
pagets__Dreispaltig.value = {$resDir}/Private/Templates/dreispaltig.html
}
Siehe oben in der Datei fileadmin/nettemplate/Configuration/TypoScript/setup.txt
Jetzt kann man z.B. in den Seiteneigenschaften der Ausgangsseite die Spaltenzahl einstellen, die man als Vorgabe für alle späteren Seiten machen möchte.
Die Vorgabe lässt sich natürlich auf jeder Seite individuell überschreiben, sofern die Rechte dazu nicht eingeschränkt wurden.
Partials
Die Partials befinden sich alle im Verzeichnis
fileadmin/nettemplate/Resources/Private/Partials/
<div class="row" id="footer">
<div class="col-md-12"><f:cObject typoscriptObjectPath="lib.field_footer" /></div>
</div>
Dieses Partial legt den Aufbau des Footers fest. Dabei greift es auf den Viewhelper f:cObject zurück, über den ein Typoscript-Objekt aufgerufen wird, welches sich in diesem Beispiel im Backend auf der Seite mit den Templates befindet.
<div id="navbar">
<nav class="navbar navbar-default" role="navigation">
<a id="navigation" name="navigation"></a>
<!-- Titel und Schalter werden für eine bessere mobile Ansicht zusammengefasst -->
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#navbar-collapse-1">
<span class="sr-only">Navigation ein-/ausblenden</span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="#">Hauptmenü</a>
</div>
<!-- Alle Navigationslinks, Formulare und anderer Inhalt werden hier zusammengefasst und können dann ein- und ausgeblendet werden -->
<div class="collapse navbar-collapse" id="navbar-collapse-1">
<ul class="nav navbar-nav">
<f:cObject typoscriptObjectPath="lib.mainnav" />
</ul>
</div> <!-- /.navbar-collapse -->
</nav>
</div>
Partial: Rootline.html
<div class="row" id="rootline"><f:cObject typoscriptObjectPath="lib.field_rootline" /></div>
Partial: Service.html
<div class="row" id="service"><f:cObject typoscriptObjectPath="lib.field_service" /></div>
Ein Teil der Partials ruft Typoscript-Code auf.
Typoscript
Auf der Datei fileadmin/nettemplate/Configuration/TypoScript/constants.txt habe ich folgenden Inhalte stehen.
Datei: constants.txt
resDir = fileadmin/nettemplate/Resources
confDir = fileadmin/nettemplate/Configuration
defaultDescription = Das ist eine von Netthelp erstellte Seite
styles.content.textmedia.maxW = 800
plugin.tx_indexedsearch.view.templateRootPath = {$resDir}/indexed_search/Private/Templates/
plugin.tx_indexedsearch.view.partialRootPath = {$resDir}/indexed_search/Private/Partials/
plugin.tx_indexedsearch.view.layoutRootPath = {$resDir}/indexed_search/Private/Layouts/
plugin.tx_news.view.templateRootPath = {$resDir}/news/Private/Templates/
plugin.tx_news.view.partialRootPath = {$resDir}/news/Private/Partials/
plugin.tx_news.view.layoutRootPath = {$resDir}/news/Private/Layouts/
plugin.tx_news.settings.cssFile = {$resDir}/news/Public/Css/news-basic.css
Diese Datei wird von EXT:nettemplate/Configuration/TypoScript/constants.txt aus includiert und dort wird auch der Konstanten-Editor konfiguriert.
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/constants.txt">
plugin.nettemplate {
# cat=plugin.nettemplate/other; type=int+; label=Startseite Service Menu
ServicePid = 4
# cat=plugin.nettemplate/other; type=int[1-3]; label=Hauptmenu Klasisch (1), DropDown (2), DropDown responsive (3)
MenuArt = 2
#cat=plugin.nettemplate/other; type=boolean; label=aktiviere RealURL (realurl_conf.php kopiert)
useRealURL = 0
# cat=plugin.nettemplate/other; type=string; label=Title Text
TitleText = Netthelp.de:
# cat=plugin.nettemplate/other; type=string; label=Standard-Text für Metatag description
defaultDescription = Dies ist eine von Netthelp erstellte Seite
# cat=plugin.nettemplate/other; type=string; label=Standard Keywords
defaultKeywords = Netthelp, Richard-Linde-Weg, Lohbrügge
# cat=plugin.nettemplate/other; type=string; label=Footer Text
FooterText = <br />© Netthelp.de
}
Die nächste Datei ist fileadmin/nettemplate/Configuration/TypoScript/setup.txt
Datei: setup.txt
Hinweis: In der hervorgehobenen Zeile 30 macht sich wieder mal eine der beliebten kleinen Änderungen bemerkbar. Hier muss description durch abstract ersetzt werden.
page = PAGE
page {
# der Body-Tag bekommt die Seiten-ID als id
bodyTag >
bodyTagCObject = TEXT
bodyTagCObject.dataWrap = <body id="uid-{field:uid}">
config.index_enable = 1
# Seite: subtitle als titel
headerData.112 = TEXT
headerData.112.field = title
headerData.112.wrap = <title>{$plugin.nettemplate.TitleText}|</title>
# es ist noch config.noPageTitle = 2 notwendig (s.u.)
# hier binden wir die CSS-Datein im Head-Bereich ein
includeCSS {
bootstrap = {$resDir}/Public/Css/Bootstrap/css/bootstrap.css
magnific = {$resDir}/Public/Css/magnific-popup.css
anpassung = {$resDir}/Public/Css/anpassung.css
} # Ende includeCSS
# Meta-Tags und Informationen
meta {
X-UA-Compatible = IE=edge,chrome=1
X-UA-Compatible.httpEquivivalent=1
viewport = width=device-width,initial-scale=1
keywords.field = keywords
keywords.ifEmpty = {$plugin.nettemplate.defaultKeywords}
description.field = abstract
description.ifEmpty = {$plugin.nettemplate.defaultDescription}
} # Ende meta
# wir arbeiten mit Fluid-Templates
10 = FLUIDTEMPLATE
10 {
partialRootPath = {$resDir}/Private/Partials
layoutRootPath = {$resDir}/Private/Layouts
variables {
inhaltLinks < styles.content.get
inhaltLinks.select.where = colPos = 1
inhaltLinks.slide = -1
hauptInhalt < styles.content.get
hauptInhalt.select.where = colPos = 0
inhaltRechts < styles.content.get
inhaltRechts.select.where = colPos = 2
inhaltRechts.slide = -1
} # Ende variables
#file = {$resDir}/Private/Templates/zweispaltig.html
file.stdWrap.cObject = CASE
file.stdWrap.cObject {
key.data = levelfield:-1, backend_layout_next_level, slide
key.override.field = backend_layout
# key.data = pagelayout
default = TEXT
default.value = {$resDir}/Private/Templates/einspaltig.html
pagets__Einspaltig < .default
pagets__Zweispaltig < .default
pagets__Zweispaltig.value = {$resDir}/Private/Templates/zweispaltig.html
pagets__Dreispaltig < .default
pagets__Dreispaltig.value = {$resDir}/Private/Templates/dreispaltig.html
}
} # Ende FLUIDTEMPLATE
# Einstellunge für alte Browser
headerData.20 = TEXT
headerData.20.value (
<!-- Unterstützung für Media Queries und HTML5-Elemente im Internet Explorer über HTML5 shim und Respond.js -->
<!-- ACHTUNG: Respond.js funktioniert nicht, wenn du die Seite über file:// aufrufst -->
<!--[if lt IE 9]>
<script src="{$resDir}/Public/JavaScript/html5shiv.js"></script>
<script src="{$resDir}/Public/JavaScript/respond.min.js"></script>
<style type="text/css">
ul.nav {height: auto;}
.equal { margin-bottom: -99999px; padding-bottom: 99999px;}
.equalheight { overflow: hidden; }
</style>
<![endif]-->
)
} # Ende Page
config {
# moderne Einstellung
doctype = html5
htmlTag_setParams = lang="de" dir="ltr"
xhtml_cleaning = none
# gehört zum subtitle als titel (s.o.)
noPageTitle = 2
# in den einleitenden Typo3-Kommentar
headerComment = Templates von Netthelp.de
# einfach alle Einstellmöglichkeiten nutzen
language = de
htmlTag_langKey = de
sys_language_uid = 0
locale_all = de_DE
# kein Hochskalieren von Abbildung
noScaleUp = 1
sendCacheHeaders = 1
# css und js Dateien von Typo3 werden je in einer temp-Datei zusammengefasst
inlineStyle2TempFile = 1
# removeDefaultJS = external
# removeDefaultJS = 1
#neu
# compressJs = 1
# compressCss = 1
# concatenateCss = 1
# concatenateJs = 1
# für die Suche
index_enable = 1
sword_standAlone = 0
sword_noMixedCase = 0
# für die Ziele von Links
intTarget = _self
extTarget = _blank
# spamProtectEmailAddresses = 1
spamProtectEmailAddresses = ascii
spamProtectEmailAddresses_atSubst = (at)
spamProtectEmailAddresses_lastDotSubst = (dot)
prefixLocalAnchors = 1
simulateStaticDocuments = 0
tx_realurl_enable = {$plugin.nettemplate.useRealURL}
absRelPath = /
absRefPrefix = /
disablePrefixComment = 1
} #Ende config
# hier binden wir weiteres Typoscript ein, thematisch gegliedert
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/headerimage.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/rootline.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/servicemenu.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/untermenulinks.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/footer.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/magnificpopup.txt">
# drei Alternativen für das Hauptmenü
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/mainmenu.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/dropdownmenu.txt">
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/dropdownmenuresp.txt">
# welche Art von Hauptmenü, Klassisch (1), DropDown (2) oder DropDown responsive (3)
lib.mainnav < lib.mainNav{$plugin.nettemplate.MenuArt}
#config.contentObjectExceptionHandler = 0
# Einstellungen für die Suche
plugin.tx_indexedsearch {
# search.rootPidList=1
# Anzeige der Regeln unter dem einfachen Formular
settings.displayRules = 0
# erweiterte Suche abschalten
settings.displayAdvancedSearchLink = 1
# show the number of results
settings.displayResultNumber = 0
}
# Einstellungen für die news
plugin.tx_news.settings.detail.showSocialShareButtons = 0
plugin.tx_news.settings.detail.media.image.lightbox.enabled = 1
lib.contentElement.settings.media.popup {
JSwindow = 0
directImageLink = 1
linkParams.ATagParams.dataWrap = class="lightbox" rel="lightbox{field:uid}" title="{file:current:title}"
}
Diese Datei wird von EXT:nettemplate/Configuration/TypoScript/setup.txt aus includiert
<INCLUDE_TYPOSCRIPT: source="FILE:fileadmin/nettemplate/Configuration/TypoScript/setup.txt">
Ohne Javascript geht das nicht - magnificpopup.txt
Den folgenden Code habe ich zusammen mit den Einstellungen für das Popup in das zusätzliche Template-Script fileadmin/nettemplate/Configuration/TypoScript/magnificpopup.txt ausgelagert:
page.footerData.10 = TEXT
page.footerData.10.value (
<!-- jQuery (wird für Bootstrap JavaScript-Plugins benötigt) -->
<script src="{$resDir}/Public/JavaScript/jquery.min.js" type="text/javascript"></script>
<!-- Binde alle kompilierten Plugins zusammen ein (wie hier unten) oder such dir einzelne Dateien nach Bedarf aus -->
<script src="{$resDir}/Public/JavaScript/bootstrap.min.js" type="text/javascript"></script>
<script type="text/javascript">
(function($){
$(document).ready(function(){
$('ul.dropdown-menu [data-toggle=dropdown]').on('click', function(event) {
event.preventDefault();
event.stopPropagation();
$(this).parent().siblings().removeClass('open');
$(this).parent().toggleClass('open');
});
});
})(jQuery);
</script>
<script src="{$resDir}/Public/JavaScript/jquery.magnific-popup.min.js" type="text/javascript"></script>
<script type="text/javascript">
$(function() {
$('a[rel*="lightbox"]').magnificPopup({
type: 'image',
tLoading: 'Lade Bild...',
tClose: 'Schließen (Esc)',
image: {
titleSrc: function(item) {
var title = item.el.attr('title');
var description = item.el.attr('alt');
return ((title)?title:'') + ((description)?'<small>'+ description +'</small>':'');
}
},
gallery: {
enabled: true,
navigateByImgClick: true,
preload: [0, 1],
tCounter: '%curr% von %total%',
tPrev: 'Zurück (Linke Pfeiltaste)',
tNext: 'Vorwärts (Rechte Pfeiltaste)'
},
mainClass: 'mfp-with-zoom', // this class is for CSS animation below
zoom: {
enabled: true, // By default it's false, so don't forget to enable it
duration: 300, // duration of the effect, in milliseconds
// easing: 'ease-in-out', // CSS transition easing function
}
});
});
</script>
)
Der erste Code-Teil ist für das Responsive-Layout auf kleinen Displays wichtig. Damit wird das Menü geöffnet und geschlossen. Das Script sucht dazu auf der Seite bestimmte Klassen, die im Layout gesetzt sein müssen. Wenn das alles richtig eingegeben ist, dann sollte auch das Frontend der Seite bereits aufrufbar sein, da das benötigte Css ja eingebunden ist.
Typoscript: headerimage.txt
Für das header-Bild dient folgender Code:
# Dieser Code wird von den Templates aus angesprungen
lib.field_headerimage = IMG_RESOURCE
lib.field_headerimage {
file.import.data = levelmedia:2, slide
file.treatIdAsReference = 1
file.import.listNum = 0
stdWrap.wrap (
<div id="skiplink">
<a class="skip" title="Direkt zur Navigation springen" href="#navigation">Zur Navigation springen</a><br>
<a class="skip" title="Direkt zum Content springen" href="#content">Zum Content springen</a>
</div>
<div id="headerimage" style="background-image:url('/|'); "><a href="/">
<img src="data:image/gif;base64,R0lGODlhAQABAIAAAP///wAAACH5BAEAAAAALAAAAAABAAEAAAICRAEAO2lmDQ==" alt="Zur Startseite" width="135" height="135">
</a></div>
)
}
Hinweis: aktuell müsste es heißen file.import.data = levelmedia:-1, slide
Der Code ist mit einem Content-Slide verbunden, das heißt immer dann, wenn auf der aktuellen Seite kein Header-Bild gefunden wird, dann geht das Tool im Seitenbaum hoch, bis es eine Seite mit Header-Bild findet. Man sollte also in den Seiteneigenschaften der root-Seite eine passende Datei hinterlegen, z.B.:
Typoscript: rootline.txt
# Dieser Code wird vom Partial rootline angesprungen
lib.field_rootline = HMENU
lib.field_rootline {
special = rootline
wrap=<ol class="breadcrumb"><li> <a href="/index.php">Klickpfad</a> </li>|</ol>
special.range = 2 | -1
1 = TMENU
1.NO = 1
1.NO.linkWrap = <li><span class="pfrechts"></span> |</li>
}
# Dieser Code wird vom Partial service aus angesprungen
# Hier muss unter special.value die ID der Oberseite angegeben werden
lib.field_service = HMENU
lib.field_service {
special = directory
special.value = {$plugin.nettemplate.ServicePid}
entryLevel = 1
wrap = <ol class="breadcrumb">|</ol>
1 = TMENU
1.NO = 1
1.NO.linkWrap = <li>|</li>
}
Hier muss man darauf achten, hinter special.value die ID der dem Menü übergeordneten Seite angegeben werden muss, dies ist über den Konstanten-Editor einstellbar.
# dieser Code wird vom Root Template aus angesprungen
# zur Auswahl stehen drei Arten des Menüs
# das Hauptmenü hat drei Ebenen
#
lib.mainNav2 =HMENU
lib.mainNav2 {
entryLevel = 1
1 = TMENU
1 {
expAll = 1
NO = 1
NO.linkWrap = <li>|</li>
NO.stdWrap.htmlSpecialChars = 1
ACT = 1
ACT.linkWrap = <li class="active">|</li>
IFSUB = 1
IFSUB.wrapItemAndSub = <li>|</li>
IFSUB.stdWrap.dataWrap = |<b class="caret"></b>
ACTIFSUB = 1
ACTIFSUB.wrapItemAndSub = <li class="active">|</li>
ACTIFSUB.stdWrap.dataWrap = |<b class="caret"></b>
}
2 < .1
2 {
IFSUB = 1
IFSUB.wrapItemAndSub = <li class="dropdown dropdown-submenu">|</li>
IFSUB.stdWrap.dataWrap= |
ACTIFSUB = 1
ACTIFSUB.wrapItemAndSub = <li class="dropdown dropdown-submenu active">|</li>
ACTIFSUB.stdWrap.dataWrap= |
wrap = <ul class="dropdown-menu">|</ul>
}
3 < .2
3 {
ACT = 1
ACT.wrapItemAndSub = <li class="active">|</li>
wrap = <ul class="dropdown-menu">|</ul>
}
}
# Dieser Code wird von den Template zweispaltung und dreispaltig aus angesprungen
#
lib.field_submenu = HMENU
lib.field_submenu {
entryLevel = 2
1 = TMENU
1 {
expAll = 0
noBlur = 1
NO.linkWrap = <li role="presentation" class="ebene1">|</li>
NO = 1
}
1.RO < .1.NO
1.ACT < .1.NO
1.ACT.linkWrap = <li role="presentation" class="ebene1 active">|</li>
1.IFSUB < .1.NO
1.IFSUB.stdWrap.dataWrap = |<span class="caret"></span>
1.ACTIFSUB < .1.ACT
1.ACTIFSUB.stdWrap.dataWrap = |<span class="caret white"></span>
2 = TMENU
2 < lib.field_submenu.1
2.NO.linkWrap = <li role="presentation" class="ebene2">|</li>
2.RO < .2.NO
2.ACT.linkWrap = <li role="presentation" class="ebene2 active">|</li>
2.IFSUB < .2.NO
2.IFSUB.stdWrap.dataWrap = |<span class="caret"></span>
2.ACTIFSUB < .2.ACT
2.ACTIFSUB.stdWrap.dataWrap = |<span class="caret white"></span>
3 = TMENU
3 < lib.field_submenu.1
3.NO.linkWrap = <li role="presentation" class="ebene3">|</li>
3.RO < .3.NO
3.ACT.linkWrap = <li role="presentation" class="ebene3 active">|</li>
3.IFSUB < .3.NO
3.IFSUB.stdWrap.dataWrap = |<span class="caret"></span>
3.ACTIFSUB < .3.ACT
3.ACTIFSUB.stdWrap.dataWrap = |<span class="caret white"></span>
}
# Dieser Code wird vom Partial footer angesprungen
lib.field_footer = TEXT
lib.field_footer {
data = date : Y
wrap (
{$plugin.nettemplate.FooterText} (|)
)
}
# alternativ
#lib.field_footer = CONTENT
#lib.field_footer {
# table = tt_content
# select.pidInList = 21
# select.uidInList = 143
# select.languageField = sys_language_uid
# }
Der Footer-Text ist über den Konstanten-Editor konfigurierbar.
Mögliche Anpassungen
Es gibt an vielen Stellen Variationsmöglichkeiten für das System
Fluid-Elemente anpassen
Passt einem irgendeine Einstellung aus den Standard-Fluid-Elementen nicht, so kann man dieses Überschreiben. Dazu hängt man z.B. die folgenden Zeilen an die Datei setup.txt an:
lib.contentElement {
partialRootPaths {
200 = {$resDir}/Private/Partials/
}
}
Dann kopiert man das Partial, welches man anpassen möchte von EXT:fluid_styled_content/Resources/Private/Partials/ in das eigene Verzeichnis fileadmin/nettemplate/Resources/Private/Partials und passt es an. Wichtig ist, dass der Name identisch bleibt.
Eine Accordion-Variation
Auch Teile der nettgrids kann man entsprechend umschreiben, wenn man sie sich in den eigenen Bereich kopiert.
cp typo3conf/extnettgrids/Resources/gridelements/Private/accordion.html fileadmin/nettemplate/Resources/gridelements/Private/
dann zu dieser Version bearbeiten:
<div id="accordion-{data.uid}" class="panel-group">
<f:for each="{data.tx_gridelements_view_children}" as="content" iteration="iterator">
<div class="panel panel-default">
<div class="panel-heading" id="heading{content.uid}" style="overflow: auto;">
<h4 class="panel-title">
<a data-toggle="collapse" data-parent="#accordion-{data.uid}" href="#collapse{content.uid}" class="collapsed">
<div style="width: 90%;float: left;">{f:if(condition: content.header, then: '{content.header}', else: 'Element{iterator.cycle}')}</div>
<i class="glyphicon glyphicon-menu-down pull-right" style="font-size: 28px;"></i>
<i class="glyphicon glyphicon-menu-up pull-right" style="font-size: 28px;"></i>
</a>
</h4>
</div>
<div id="collapse{content.uid}" class="panel-collapse collapse">
<div class="panel-body">
<f:format.raw>
{data.tx_gridelements_view_child_{content.uid}}
</f:format.raw>
</div>
</div>
</div>
</f:for>
</div>
Und dann hängt man an die Typoscript-Datei setup.txt folgende Zeilen an:
tt_content.gridelements_pi1.20.10.setup.accordion < lib.gridelements.defaultGridSetup
tt_content.gridelements_pi1.20.10.setup.accordion {
cObject = FLUIDTEMPLATE
cObject.file = {$resDir}/gridelements/Private/accordion.html
}
PDF einbinden
<div class="kontainer" style="justify-content: center; display: flex; ">
<embed src="/fileadmin/user_upload/mein.pdf#view=FitH&page=1"
type="application/pdf"
width="50%"
height="780px" />
</div>
oder
<button class="btn btn-primary" data-toggle="collapse" data-target="#4711">Preliminary agenda</button>
<div id="4711" class="collapse">
<br>
<embed src="/fileadmin/user_upload/mein.pdf#toolbar=0&navpanes=0&scrollbar=0" type="application/pdf" width="100%" height="1000px" />
</div>
Eventuell nutzt man auch https://pdfobject.com/ um die Einbindung flexibel zu gestalten.
Noch zu korrigierende Fehler V2.0.5
In der Datei headerimage.txt muss es heißen:
file.import.data = levelmedia:-1, slide
in der Datei setup.txt den Kommentar tauschen
spamProtectEmailAddresses = 1 # spamProtectEmailAddresses = ascii
Ebenfalls in der setup.txt in Zeile 30 macht sich wieder mal eine der beliebten kleinen Änderungen bemerkbar. Hier muss description durch abstract ersetzt werden
description.field = abstract description.ifEmpty = {$plugin.nettemplate.defaultDescription}