TYPO3

Vererbung von Bildern aus den Seiteneigenschaften

caticonslite_bm_alt

In TYPO3 lassen sich in den Seiteneigenschaften Bilder im Feld „Dateien“ unter „Ressourcen“ hinterlegen. Auf die angegebenen Dateien kann man mit TypoScript zugreifen und somit z.B. je Seite ein individuelles Headerbild darstellen. Häufig ist es ausreichend auf Unterseiten das Bild der übergeordneten Seite anzuzeigen, oder man möchte nicht auf jeder Seite ein Bild hinterlegen müssen. Hierfür bietet sich in TYPO3 die Verwendung von „slide“ an – damit lässt sich eine Vererbung von Bildern realisieren. D.h. es wird ausgehend von der aufgerufenen Seite der Seitenbaum bis zur Rootseite nach einem Bild durchsucht, bis entweder ein Bild gefunden, oder die Rootseite erreicht worden ist.

Bei einer TYPO3 Standard-Installation mit FAL (File Abstraction Layer) (ab TYPO3 6.0) benötigt man folgendes TypoScript:

lib.image = FILES
lib.image {
	references {
		data = levelmedia:-1,slide
	}
	renderObj = IMAGE
	renderObj {
		file.import.data = file:current:publicUrl
		titleText.data = file:current:title
	}
}

Bei einer TYPO3 Standard-Installation ohne FAL (bis TYPO3 6.0) benötigt man folgendes TypoScript:

lib.image = IMAGE
lib.image.file {
	import = uploads/media/
	import {
		data = levelmedia:-1, slide
		listNum = 0
	}
}

Wird DAM verwendet, ist folgende Konfiguration zu verwenden:

lib.image = IMAGE
lib.image.file {
	import.cObject = USER
	import.cObject {
		userFunc = tx_dam_pages->get_media_file
		listNum = 0
		slide = 1
	}
}

Individuelle Marker in Direct Mail

caticonslite_bm_alt

In einem Newsletter werden häufig auch benutzerspezifische Parameter abseits der standardmäßig vorhandenen benötigt, z.B. um die Anrede zu personalisieren (Sehr geehrte Frau bzw. Sehr geehrter Herr,…) oder um Felder aus marketingtechnischen Gründen (z.B. individueller Gewinncode) hinzuzufügen. Dies ist in der Direct Mail-Extension (Extensionkey: direct_mail), dank der Verwendung von Hooks, relativ einfach zu bewerkstelligen.

Zuerst muss man hierfür eine neue Extension erstellen, ich verwende hier den Extensionkey „direct_mail_markers“, um die benötigten Dateien irgendwo ablegen zu können. Als nächstes wird eine Klasse (samt entsprechender Methode), welche benutzerdefinierte Marker generiert, erstellt – im Ordner „Classes/Hooks/“ der Extension legt man eine Datei namens „DirectMailMarkers.php“ mit folgendem Inhalt an:

<?php
namespace WebentwicklerAt\DirectMailMarkers\Hooks;
 
class DirectMailMarkers
{
    /**
     * @param array $params
     * @return array
     */
    function mailMarkersHook(array $params)
    {
        // ###USER_salutation###
        $salutation = '';
        if (in_array($params['row']['gender'], array(0, 'm', 1, 'f')) && !empty($params['row']['last_name'])) {
            // gender
            if ($params['row']['gender'] === 0 || $params['row']['gender'] === 'm') {
                $salutation = 'Sehr geehrter Herr ';
            } else if ($params['row']['gender'] === 1 || $params['row']['gender'] === 'f') {
                $salutation = 'Sehr geehrte Frau ';
            } else {
                $salutation = 'Sehr geehrte(r) Herr/Frau ';
            }
 
            // title
            if (!empty($params['row']['title'])) {
                $salutation .= $params['row']['title'] . ' ';
            }
 
            // last_name
            $salutation .= $params['row']['last_name'];
        } else {
            $salutation = 'Sehr geehrte Damen und Herren';
        }
 
        $params['markers']['###USER_salutation###'] = $salutation;
 
        return $params;
    }
}

Diese Methode erzeugt abhängig vom Feld „gender“ die persönliche Anrede „Sehr geehrter Herr Nachname“„Sehr geehrte Frau Nachname“ oder wenn kein Nachname oder Geschlecht angegeben worden ist „Sehr geehrte Damen und Herren“. Zusätzlich wird der Titel – sofern angegeben – eingefügt.

Damit die soeben erstellte Hook-Methode verwendet wird und der generierte Marker ###USER_salutation### im Newsletter verwendet werden kann, muss diese in der„ext_localconf.php“ registriert werden:

<?php
 
if (!defined ('TYPO3_MODE')) die ('Access denied.');
 
// register directmail markers hook
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['ext/direct_mail']['res/scripts/class.dmailer.php']['mailMarkersHook'][] = 'EXT:' . $_EXTKEY . '/Classes/Hooks/DirectMailMarkers.php:' . \WebentwicklerAt\DirectMailMarkers\Hooks\DirectMailMarkers::class . '->mailMarkersHook';

Nachdem die soeben erstellte Erweiterung über den Extensionmanager installiert worden ist, steht der generierte Marker im Newsletter zur Verfügung.

In der Datei composer.json der Installation ist folgender Eintrag für das Autoloading unter „autoload/psr-4“ zu ergänzen:

"autoload": {
  "psr-4": {
    "WebentwicklerAt\\DirectMailMarkers\\": "typo3conf/ext/direct_mail_markers/Classes/"
  }
}

Abschließend müssen die Autoloading-Informationen noch mit composer dump-autoload aktualisiert werden.

RSS-Feed generieren

caticonslite_bm_alt

Viele TYPO3-Erweiterungen zur Generierung von RSS-Feeds können lediglich Seiten und tt_news-Artikel verwenden – das ist häufig nicht ausreichend. Eine Ausnahme bildet die Extension „in2rss“, welche sich recht flexibel mittels TypoScript konfigurieren lässt und Datensätze aus jeder beliebigen Tabelle darstellen kann.

Nach der üblichen Vorgehensweise zur Installation des Plugins, müssen noch die zu verwendendenTabellen konfiguriert werden. Die Grundkonfiguration samt einem vorkonfigurierten Beispiel lässt sich mittels Static Template einfügen – dieses erscheint mir allerdings als unpraktikabel, daher lege ich alle notwendigen Parameter selbst im Setup fest:

includeLibs.in2rss_main = EXT:in2rss/lib/class.tx_in2rss_main.php
 
rss = PAGE
rss {
	typeNum = 100
 
	config {
		disableAllHeaderCode = 1
		disablePrefixComment = 1
		xhtml_cleaning = 0
		admPanel = 0
		no_cache = 1
	}
 
	10 = USER
	10 {
		userFunc = user_in2rss_main->showRSS
		userFunc.config {
			template = fileadmin/templates/webentwickler/in2rss/template.xml
			sorting = DESC
			limit = 20
			uft8_coding =
 
			10 {
				settings {
					table = pages
					fieldTitle = title
					fieldDescription = description
					fieldBody = description
					fieldImage = media
					fieldSorting = crdate
					fieldCrdate = crdate
					pid =
					pid_recursive = 0
					additionalWhereClause = AND doktype IN (1) AND nav_hide = 0
					cropDescription = 250
					limit = 100
				}
 
				fields {
					rssTitle = TEXT
					rssTitle {
						field = rssTitle
					}
 
					rssDescription = TEXT
					rssDescription {
						field = rssDescription
					}
 
					rssBody = TEXT
					rssBody {
						field = rssBody
					}
 
					rssSorting = TEXT
					rssSorting {
						field = rssSorting
					}
 
					rssCrdate = TEXT
					rssCrdate {
						field = rssCrdate
					}
 
					rssLink = TEXT
					rssLink {
						typolink {
							parameter.field = uid
							returnLast = url
						}
					}
				}
			}
		}
	}
}
 
[globalVar = GP:type = 100]
	config.absRefPrefix = {$baseUrl}
[end]

Die Konfiguration der Tabelle erfolgt in den Zeilen 24-74, in diesem Fall werden alle nicht im Menü versteckten (nav_hide = 0) Seiten (table = pages) vom Typ Standard (doktype IN (1)) verwendet. Die restlichen Zeilen dieses Bereichs enthalten Parameterzuweisungen, damit diese im in Zeile 19 angegebenen Template verwendet werden können:

<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0">
	<channel>
		<title>webentwickler.at</title>
		<link>http://www.webentwickler.at/</link>
		<description>Blog für Webentwickler.</description>
		<language>de</language>
 
		<f:for each="{rssFeed}" as="rss"><f:if condition="{rss.rssTitle}">
			<item>
				<title>{rss.rssTitle}</title>
				<description>{rss.rssDescription}</description>
				<link>{rss.rssLink}</link>
				<pubDate>{rss.rssCrdate}</pubDate>
			</item>
		</f:if></f:for>
	</channel>
</rss>

Statische Dateien von cookie-free Domain bzw. externem Server oder CDN laden

caticonslite_bm_alt

TYPO3 setzt standardmäßig das Cookie „fe_typo_user“ für Frontend-Benutzer, selbst wenn es sich nur um einen Gast handelt und somit kein Login erfolgt ist. Das hat zur Folge, dass für jede statische Datei (z.B. CSS, Bilder und JavaScript) die Cookie-Informationen über den langsamen Upload an den Server übertragen werden müssen. Indem man diese Dateien von einer cookie-free Domain holt, lässt sich etwas Ladezeit einsparen. Außerdem kann man statische Dateien von einemleichtgewichtigeren Webserver (z.B. nginx, Squid, lighttpd) oder CDN (Content Distribution Network) ausliefern lassen und somit den Hauptwebserver von TYPO3 (z.B. Apache, nginx) entlasten.

Für die Umsetzung dieses Vorhabens findet man im TER einige Erweiterungen, welche alle nach dem selben Prinzip funktionieren: Ersetzen der lokalen/relativen Pfade von fileadmin, typo3temp und uploads mittels regulärem Ausdruck. Ich setze hier bewusst nicht auf ein ausschließlich für diesen Zweck zugeschnittenes Plugin, sondern auf die „regex“-Extension, mit der ich bei Bedarf auch noch andere Ersetzungen vornehmen kann.

Nach der üblichen Vorgehensweise zur Installation des Plugins, muss im TypoScript-Setup noch folgende Konfiguration vorgenommen werden:

config.regex {
	pattern1 = /"fileadmin\/([^"]+)"/
	pattern1.replacement = "http://static.webentwickler.at/fileadmin/$1"
 
	pattern2 = /"typo3temp\/([^"]+)"/
	pattern2.replacement = "http://static.webentwickler.at/typo3temp/$1"
 
	pattern3 = /"uploads\/([^"]+)"/
	pattern3.replacement = "http://static.webentwickler.at/uploads/$1"
 
	pattern4 = /"typo3conf\/([^"]+)"/
	pattern4.replacement = "http://static.webentwickler.at/typo3conf/$1"
}

Die Zusatzdomain „static.webentwickler.at“ muss natürlich noch eingerichtet werden und auf das selbe Verzeichnis wie die TYPO3-Hauptdomain „www.webentwickler.at“ verweisen. Setzt man einen leichtgewichtigen Webserver bzw. ein CDN für die Zusatzdomain ein, so muss auf diesem natürlich dasTYPO3-Verzeichnis eingebunden werden (z.B. mittels NFS-Share oder DRBD). In diesem Fall sollte darauf geachtet werden, dass keine PHP-Dateien Plaintext ausgeliefert werden.

„csc-default“-Wrap entfernen

caticonslite_bm_alt

TYPO3 wrapt standardmäßig alle Inhaltselemente mit einem div, die Ausgabe im Frontend sieht in etwa wie folgt aus:

<div id="c1" class="csc-default">
	<p class="bodytext">
		Lorem ipsum dolor sit amet.
	</p>
</div>

Interessant ist die eindeutige ID (aufgebaut aus der Datenbank-UID mit einem vorangestellten „c“) ausschließlich im Zusammenhang mit der Verwendung von Sprungmarken bzw. wenn man Rahmen (Frames) verwendet bzw. benutzerdefinierte Rahmen definiert. Entfernen lässt sich der div-Wrapper mit folgendem TypoScript-Setup:

tt_content.stdWrap.innerWrap >

Als Ergebnis erhält man:

<p class="bodytext">
	Lorem ipsum dolor sit amet.
</p>
1 2 3 4 5  nach oben