Schritt für Schritt

Schritt 6 : Dokument Titel, Bereichstitel, Seitentitel, Untertitel, Seiten Author, Letzte Aktualisierung, Seiten Inhaltsangabe, Code Highlighter, Fusszeile

In diesem Schritt werden folgende Elemente mit typoscript erstellt. Dokument Titel, Bereichstitel, Seitentitel, Untertitel, Seiten Author, Letzte Aktualisierung, Seiten Inhaltsangabe, Code Highlighter, Fusszeile. Im Bild sieht man wo was sein wird.

Allgemeine Info - Voraussetzung

Vielfach sieht man, das gewisse Elemente welche auf der Seite benötigt werden, jedesmal neu geschrieben werden. Das habe ich früher auch so gemacht, doch mittlerweile bin ich davon abgekommen weil es auch einiges einfacher geht. Wie? Das werde ich euch in diesem Artikel zeigen.

Dazu verwende ich seit einiger Zeit LOAD_REGISTER um Globale Daten im weiteren Verlauf des Template aufbaus verwenden zu können. Folgenes typoscript ist somit Voraussetzung, damit die weiteren Elemente funktionieren. Nicht über alle Felder kann man standardmässig sliden, daher muss die TYPO3_CONF_VARS.FE.addRootLineFields entsprechend angepasst werden.


$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'] .= ',subtitle,author,author_email';
$GLOBALS['TYPO3_CONF_VARS']['FE']['addRootLineFields'] .= ',keywords,description,abstract'; 
anpassung in localconf.php

/*
 Globale Page Daten
 by thefox.ch
*/
temp.pagedata = LOAD_REGISTER
temp.pagedata {

  # page title
  pageTitle.cObject = COA
  pageTitle.cObject {
    10 = TEXT
    10 {
      data = page:title
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

  # page subtitle
  pageSubtitle.cObject = COA
  pageSubtitle.cObject {
    10 = TEXT
    10 {
      # in meinem fall ohne sliden
      # data = levelfield : -1, subtitle, slide
      data = field:subtitle
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

  # page author
  pageAuthor.cObject = COA
  pageAuthor.cObject {
    10 = TEXT
    10 {
      data = levelfield : -1, author, slide
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

  # page author email
  pageAuthorEmail {
    data = levelfield : -1, author_email, slide
  }

  # page keywords
  pageKeywords.cObject = COA
  pageKeywords.cObject {
    10 = TEXT
    10 {
      data = levelfield : -1, keywords, slide
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

  # page description
  pageDescription.cObject = COA
  pageDescription.cObject {
    10 = TEXT
    10 {
      data = levelfield : -1, description, slide
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

  # page abstract
  pageAbstract.cObject = COA
  pageAbstract.cObject {
    10 = TEXT
    10 {
      data = levelfield : -1, abstract, slide
      stripHtml = 1
      htmlSpecialChars = 1
    }
  }

}
Globale Page Daten

Dokument Titel

Der Dokument Titel ( <title> Tag ) soll den Titel der Seite anzeigen und wenn vorhanden mit dem Untertitel ergäzt werden. Damit der Titel beeinflusst werden kann, wird geprüft ob ein Navigationstitel eingegeben wurde. Wenn dieser vorhanden ist, wird nicht der Seiten Titel verwendet.

Suchmaschinen technisch ist es besser, wenn der Projektname nach dem Seitennamen kommt. Hintergrund ist die Suchrelevanz an welcher Stelle das gesuchte Wort im Titel gefunden wird.


# CONFIG Code. Seitentitel von TYPO3 deaktivieren
page.config.noPageTitle = 1

# HTML Code <title>###METATITLE###</title>

# template
temp.htmlTemplate.marks {

	# marker ersetzen
	METATITLE = COA
	METATITLE {

		10 = TEXT
		10.data = page:nav_title // register:pageTitle

		20 = TEXT
		20.data = register:pageSubtitle
		20.noTrimWrap = | :: ||
		20.if.isTrue.data = register:pageSubtitle

		# Projektname am Titelende
		30 = TEXT
		30.value = Projektname
		30.noTrimWrap = | :: ||

		wrap = |
	}

}
typoscript für document title

Bereichstitel

Beim Bereichstitel soll der Seitentitel von einer bestimmten Seite angezeigt werden.

Zuerst wird Basic Code erstellt, welcher immer wieder verwendet werden kann. Im Template wird dieser Code eingebunden und der gewünschte Teil angepasst.


# basic code, titel von home seite
temp.elements {

	# titel von einer bestimmten seite (default = 1)
	pagetitle_from_id = TEXT
	pagetitle_from_id {
		value = 1
		wrap = <h2>{DB:pages:|:title}</h2>
		insertData = 1
	}

}

# template code
temp.htmlTemplate.marks {

	# innerhalb der content spalte einbinden
	COL2 = COA
	COL2 {
		# basis code bereichstitel einbinden
		4 < temp.elements.pagetitle_from_id
		# titel von seite 10 anzeigen
		4.value = 10

		# weiterer code...
		10 < styles.content.get
	}

}

typoscript für bereichs titel

Seitentitel

Der Seitentitel soll es in 2 Varianten geben. Einmal nur der Titel, und einmal mit Untertitel.

Wenn der Bereichstitel verwendet wird, soll der Seitentitel mit Untertitel verwendet werden.


# basic code, titel von home seite
temp.elements {

	# seiten titel der aktuellen seite
	pagetitle = TEXT
	pagetitle {
		data = register:pageTitle
		wrap = <h2>|</h2>
	}

	# seiten titel mit untertitel der aktuellen seite
	pagetitle_with_subtitle = COA
	pagetitle_with_subtitle {
		10 = TEXT
		10.data = register:pageTitle
		10.noTrimWrap = || : |
		10.if.isTrue.data = register:pageSubtitle

		20 = TEXT
		20.data = register:pageSubtitle // register:pageTitle

		wrap = <h3>|</h3>
	}

}

# template code normal
temp.htmlTemplate.marks {
	COL2 = COA
	COL2 {
		# LOAD_REGISTER laden
		1 < temp.pagedata

		5 < temp.elements.pagetitle

		# weiterer code...
		10 < styles.content.get
	}
}

# template code spezial
[PIDinRootline = 10]
temp.htmlTemplate.marks {
	COL2 = COA
	COL2 {
		# LOAD_REGISTER laden
		1 < temp.pagedata

		4 < temp.elements.pagetitle_from_id
		4.value = 10

		5 < temp.elements.pagetitle_with_subtitle

		# weiterer code...
		10 < styles.content.get
	}
}
[global]
typoscript für seitentitel

Untertitel

Untertitel der aktuellen Seite mit typoscript auslesen.


10 = TEXT
10 {
	data = field:subtitle
	stripHtml = 1
	htmlSpecialChars = 1
}
typoscript für seiten untertitel

Seiten Author

Es soll der Author der aktuellen Seite angezeigt werden, wenn die aktuelle Seite keinen Eintrag in den Seiteneigenschaften hat, soll in den Eltern Seiten bis zur HOME Seite gesucht werden.

Damit muss im Grunde nur die erste Seite über einen Author verfügen, jedoch kann man den Author auf jeder Seiten unterschiedlich festlegen.


# element erstellen
temp.elements {
	# author mit letzte aenderung der seiteneigenschaften
	author_with_date = COA
	author_with_date {
		10 = TEXT
		10.data = register:pageAuthor
		10.noTrimWrap = ||: |
		10.if.isTrue.data = register:pageAuthor

		20 = TEXT
		20.data = field:tstamp
		20.strftime = %d.%m.%Y

		wrap = <p class="author">|</p>
	}
}

# im template einbinden
temp.htmlTemplate.marks {
	COL2 = COA
	COL2 {
		# LOAD_REGISTER laden
		1 < temp.pagedata

		3 < temp.elements.author_with_date
	}
}


typoscript für author mit datum

Letzte Aktualisierung

Oft ist die Frage: Die Letzte Aktualisierung von was ? In den meisten Fällen sieht man das register:SYS_LASTCHANGED verwendet wird, wie auch die Top 5 Treffer von Google zeigen.

beim verlinken auf google war ich noch nicht im index. mal schauen ob sich das ädert ;-)

Aber was ist SYS_LASTCHANGED genau und wann ädert sich der Wert ? Das wusste ich bisher auch nicht so genau, deshalb habe ich mir dies mal angeschaut.

Ein Feld mit dem selben Namen findet man in der Datenbank bei der Tabelle pages, also habe ich dieses Feld mit folgendem Ablauf in der Datenbank überwacht.


# Seiten nach SYS_LASTCHANGED
SELECT uid, pid, title, doktype, crdate, tstamp, SYS_LASTCHANGED
FROM `pages`
ORDER BY SYS_LASTCHANGED DESC

# Content Elemente nach tstamp 
SELECT uid, pid, header, bodytext, crdate, tstamp
FROM `tt_content`
ORDER BY tstamp DESC

sql für tests
Test Ablauf

getestet wurde mit TYPO3 4.3.3

  • Seite anlegen und speichern.
    > Seite in Datenbank mit Wert 0 erstellt
  • Neue Seite über ID (index.php?id=X) das erste mal anschauen.
    > Datum mit dem selben Wert wie crdate und tstamp erstellt.
  • Seiteneigenschaften geöffnet, ohne etwas zu ädern gespeichert, über Icon in Navigation Seite ansehen.
    > Datum wurde aktualisiert, gleicher Wert wie Feld tstamp.
  • Seiteneigenschaften geöffnet, etwas geädert, über Icon 'Dokument speichern und Web-Seite anzeigen' gespeichert.
    > Datum wurde aktualisiert, gleicher Wert wie Feld tstamp.
  • Erstes Content Element auf der Seite erfasst, über Icon 'Dokument speichern und Web-Seite anzeigen' gespeichert.
    > Datum wurde aktualisiert, gleicher Wert wie Feld tstamp vom Content Element.
  • Zweites Content Element auf der Seite erfasst, über 'Dokument speichern' gespeichert, Seite über ID aufgerufen.
    > Datum wurde aktualisiert, gleicher Wert wie Feld tstamp vom zweiten Content Element.
  • Erstes Content Element geöffnet, Titel geädert, Element gespeichert.
    > tstamp vom Content Element wurde aktualisiert. Bei der Seite ist SYS_LASTCHANGED unverädert.
  • Erstes Content Element geöffnet, Titel geädert, Element gespeichert, Seite über ID aufgerufen.
    > Das Feld SYS_LASTCHANGED wurde aktualisiert und hat jetzt den selben Wert wie tstamp vom ersten Content Element .
  • Erneut Seiteneigenschaften geöffnet, ohne etwas zu ädern gespeichert,Seite über ID aufgerufen.
    > Datum wurde aktualisiert, gleicher Wert wie Feld tstamp von der Seite.
Fazit Test Ablauf

Es funktioniert so wie ich es erwartet habe. Es ist Gut zu wissen, das man die Seite zuerst im Frontend anschauen muss, bevor der Wert aktualisiert wird.

register:SYS_LASTCHANGED VS field:SYS_LASTCHANGED

Bleibt aber noch eine Frage offen! Ist register:SYS_LASTCHANGED das selbe wie field:SYS_LASTCHANGED ?

Auch dies habe ich mit einem kleinen Test überprüft.


# test 1
temp.elements.test = COA
temp.elements.test {

	10 = TEXT
	10 {
		data = TSFE:id
		wrap = {DB:pages:|:SYS_LASTCHANGED}
		insertData = 1
		outerWrap = DB:pages:X:title = |<br />
	}

	20 = TEXT
	20.field = SYS_LASTCHANGED
	20.wrap = field:SYS_LASTCHANGED = |<br />

	30 = TEXT
	30.data = register:SYS_LASTCHANGED
	30.wrap = register:SYS_LASTCHANGED = |<br />

}

# ergebnis 1
DB:pages:X:title =1277562543
field:SYS_LASTCHANGED =1277562543
register:SYS_LASTCHANGED =1277562586


# test 2 - gleich wie 1, aber mit COA_INT
temp.elements.test = COA_INT 
temp.elements.test {
  # ... code wie bei test 1
}

# ergebnis 2
DB:pages:X:title =1277562586
field:SYS_LASTCHANGED =1277562543
register:SYS_LASTCHANGED =1277562586

# ergebnis beider Tests nach Cache leeren
DB:pages:X:title =1277562586
field:SYS_LASTCHANGED =1277562586
register:SYS_LASTCHANGED =1277562586
typoscript test code für SYS_LASTCHANGED

Die Antwort darauf ist nicht so einfach. Grundsätzlich ist es der selbe Wert. Jedoch ist SYS_LASTCHANGED per field erst gleich wie der Wert aus REGISER, wenn der Seiten Cache im TYPO3 gelöscht wurde.

SYS_LASTCHANGED bezieht sich somit immer auf die aktuelle Seite und ist nicht für die ganze Web-Seite gültig.

Letzte Aktualisierung gibt also nur an, wann das letzte mal auf dieser Seite etwas geädert wurde. Auf meiner Seite will ich jedoch nicht, das jedesmal wenn ich den Text anpasse, sich auch gleich das Datum auf der Seite ädert. Damit ich dies besser beinflussen kann, verwende ich das Feld tstamp von der Seite.


temp.elements {
	date_lastchanged = TEXT
	date_lastchanged {
		data = field:tstamp
		strftime = %e.%m.%Y
	}
}
feld tstamp für letzte äderung verwenden

Seiten Inhaltsangabe

Die Inhaltsangabe soll aus den Seiteneigenschaften ausgelesen werden und als Einführungstext auf der Seite dienen. Wenn kein Text eingegeben wurde, soll das Element nicht auf der Seite angezeigt werden.

Code Highlighter

Für Code Highlighter gibt es einige Extensions im TER und auch JavaScript Code zum einbinden.

Auf der Suche nach dem passenden Highlighter habe ich die Seite 11 Syntax Highlighters To Beautify Code Presentation gefunden.

Jedoch habe ich mich am Schluss für die Extension beautyOfCode Syntax Highlighter (key: beautyofcode) entschieden, weil diese jQuery verwendet und coole Funktionen hat. Ebenfalls gefiel mir die Projektseite, welche für die Blog Funktionalität kein Wordpress, sondern die Extension t3blog einsetzt. Der einzige negative Punkt ist nur, das ich im Blog Eintrag typoscript Schnipsel mit Browser Condition gefunden habe ;-)

Wieso keine Browser Condition ? - findet man im Schritt 5

Fusszeile

In der Fusszeile sollen diverse Informationen zum aktuellen Tag angezeigt werden.

Mit typoscript Code kann man ein Datum Feld aus der Datenbank in ein anschaubares Datum umformatieren. Dabei gibt es 2 Varianten, beide verwenden zum umrechnen die PHP Funktionen date oder strftime.


# Ziel = Freitag, 18. Juni 2010, 19.17 Uhr / 762@time / Woche : 24 / Tag im Jahr : 168

# variante 1 - date
FOOTER = TEXT
FOOTER {
  data = date:U
  date = l , d. F Y, H.i \U\h\r / B@\t\i\m\e / \W\o\c\h\e : W / \T\a\g \i\m \J\a\h\r : z
}
# Ergebnis: Friday, 18. June 2010, 19.17 Uhr / 762@time / Woche : 24 / Tag im Jahr : 168

# variante 2 - strftime
FOOTER = TEXT
FOOTER {
  data = date:U
  strftime = %A, %e. %B %Y, %H.%M Uhr / Woche : %V / Tag im Jahr : %j
}
# Ergebnis: Friday, 18. June 2010, 19.17 Uhr / Woche : 24 / Tag im Jahr : 168

# variante 3 - strftime mit config.locale_all
# zuerst PHP auf deutsch umstellen
config.locale_all = de_DE.UTF-8

FOOTER = TEXT
FOOTER {
  data = date:U
  strftime = %A, %e. %B %Y, %H.%M Uhr / Woche : %V / Tag im Jahr : %j
}
# Ergebnis: Freitag , 18. Juni 2010, 19.17 Uhr / Woche : 24 / Tag im Jahr : 168
spielen mit datum

Wie man im Code (oben) sehen kann, ist auch das schreiben bei der strftime Variante einiges einfacher als bei date. Dies ist sicherlich auch der Grund wieso meistens strftime verwendet wird.

Beim erstellen gab es 2 PHP spezifische Probleme, welche gelöst werden mussten.

Die Probleme
  1. Beim aktuellen Wochentag wurde immer die englische Version (Friday statt Freitag) angezeigt.
  2. Bei der strftime Variante gibt es keine Möglichkeit die @time (Swatch-Internet-Zeit) auszugeben.

Beim Wochentag war es einfach. Auch wenn einige dies jeweiles in PHP mit einer eigenen Funktion versuchen zu umgehen, ist es eine PHP Einstellung, welche man mit typoscript lösen kann.

Die meisten Lösungsvorschläge welche man im Netz findet verweisen auf config.locale_all, was soweit mal richtig ist.

Meistens wird dies Vorgeschlagen:


config.locale_all = de_DE

Man findet aber auch andere Vorschläge. Beispiel von Code welcher nicht geht!


# geht nicht, es wird der letzte wert genommen
config.locale_all = de_DE
config.locale_all = de
config.locale_all = german
config.locale_all = de_DE@EURO

# page config übersteuert config.locale_all
config.locale_all = de_DE@EURO
page.config.locale_all = de_DE

# wenn es für ein Win Server gedacht ist, dann muss es klein geschrieben sein
config.locale_all = Swiss

Die Angabe bei config.locale_all muss genau mit auf dem Server vorhandenen Sprachpacket übereinstimmen. Gibt man zum Beispiel de_DE ein, aber auf dem Server ist das Sprachpacket de_DE.UTF-8 vorhanden, wird die Konfiguration nicht funktionieren!

Für die deutsch Einstellung gibt es einige Möglichkeiten auf Linux Server. de_AT, de_AT.utf8, de_AT@euro, de_BE, de_BE.utf8, de_BE@euro, de_CH, de_CH.utf8, de_DE, de_DE.utf8, de_DE@euro, de_LU, de_LU.utf8, de_LU@euro, eine Ãœbersicht für Linux bietet diese Liste mit möglichen Locales.

Auf einen Windows Server sieht dies anderes aus, da gibt es eine andere Liste für Windows Server.

Aber wie findet man heraus welche Locals auf dem Server zur Verfügung stehen? Bei Linux kann man dies im Shell mit dem Befehl locale -a herausfinden. Wenn man keinen Zugriff per Shell hat, dann gibt es auch Möglichkeiten per PHP dies heraus zu finden.

Es ist somit wichtig, das wenn man eine TYPO3 Installation auf einen neuen Server zügelt, überprüft ob die Config entsprechend richtig ist.

Zugegeben bei der date Variante, kann man soviel mit der Config umstellen wie man will, ich habe es nicht geschaft den Wochentag auf deutsch auszugeben, was zum Problem 2 führte.


# Ziel = Freitag, 18. Juni 2010, 19.17 Uhr / 762@time / Woche : 24 / Tag im Jahr : 168

# variante 4 - data und strftime mit config.locale_all
config.locale_all = de_DE.UTF-8

FOOTER = COA_INT
FOOTER {

  1 = LOAD_REGISTER
  1 {
    atTime {
      data = date:U
      date = B
      wrap = |@time
    }
  }

  10 = TEXT
  10.data = date:U
  10.strftime = %A, %e. %B %Y, %H.%M Uhr / {register:atTime} / Woche : %V / Tag im Jahr : %j
  10.insertData = 1
}
# Ergebnis: Freitag , 18. Juni 2010, 19.17 Uhr / 762@time / Woche : 24 / Tag im Jahr : 168

spielen mit datum

Um das Problem mit @time zu lösen kann man eine Kombo Variante machen, wie in Variante 4 zu sehen ist.

Dies war Schritt 6!

Vielen Dank für's rein schauen.

thefox