Einstieg in Extbase - ein Typo3-Plugin ohne Models

Einstieg in Extbase - ein Typo3-Plugin ohne Models
Von Lars Ebert am 06.05.13, 11:00
Kategorien: Content Management Systeme, PHP, Programmieren, Tutorials and Typo3

Ich habe mich lange Zeit um Extbase gedrückt—wie immer bei Typo3 findet man zu Extbase keine wirklich guten Tutorials und der Einstieg fällt leider ziemlich schwer. Wenn man dann doch ein Tutorial findet, sind viele Dinge im Tutorial schon wieder veraltet und funktionieren nicht wie erwartet. Das ist für einen Anfänger natürlich immer besonder schlecht.

Jetzt kam ich allerdings nicht mehr drum herum, den Einstieg zu wagen. Als ich eine Webseite mit Typo3 v6 aufsetzen wollte, stellte ich fest, dass viele meiner eigenen Extensions nicht mehr wie gewünscht funktionieren. Also werde ich diese jetzt nach und nach auf Extbase umstellen und dabei hoffentlich einiges lernen.

In diesem Artikel möchte ich versuchen, euch den Einstieg in Extbase so einfach wie möglich zu machen. Dies ist keineswegs ein allumfassendes Tutorial, denn ich bin selbst noch dabei, mich einzuarbeiten. Dieser Artikel ist quasi ein Wegweiser für alle, die wie ich vor der großen Herausforderung mit Namen Extbase stehen.

Ein kleines Bisschen Theorie

Leider kommt man beim Einstieg in Extbase nicht um etwas Theorie herum. Deshalb muss ich hier in Kürze die Grundlagen von MVC erläutern.

MVC ist die Abkürzung für Model-View-Controller und ist eine Methode der Software-Architektur. Kernprinzip ist die Aufteilung der Software in Models, welche für die Verwaltung und Aufbereitung der Daten und für die Kommunikation mit der Datenbank zuständig sind, Views, welche als Templates für die Ausgabe (in unserem Fall den HTML-Content) dienen und Controller, welche den Ablauf der Software und die Kommunikation zwischen allen Komponenten steuern. Das ist eine wirklich sehr knappe Erklärung des Prinzips MVC. Allen Interessierten empfehle ich die Lektüre des Wikipedia-Artikels zum Thema und eine eingehende Web-Recherche. Für diesen Artikel soll das jedoch erst einmal reichen.

Wir können im folgenden die Sache erstmal etwas vereinfachen, indem wir die Models außen vor lassen. Wir werden ein Plugin entwickeln, dass jedoch keine komplizierten Daten verarbeiten muss, deshalb brauchen wir auch kein Model. Wir werden lediglich einen Controller und dazugehörige Views anlegen. Aber dazu später mehr. Zuerst schauen wir uns den Zweck des Plugins an.

Was soll das Plugin eigentlich können?

Schon in meinem Artikel über individuelle Layouts für Unterseiten in Typo3 habe ich einige Dinge gezeigt, die ich bei der Umsetzung der Webseite für Urologie-Curos getan habe, dies will ich auch hier wieder tun. Das Plugin, das wir in diesem Artikel erstellen, soll auf jeder Unterseite eine bestimmte Grafik im Kopf anzeigen, die wir in den Seiteneigenschaften festlegen können.

Das ist eigentlich schon alles, also fangen wir einfach an!

Schritt 1: Aufbau einer Typo3-Extension mit Extbase

Eine Typo3-Extension, die auf Extbase aufsetzt, muss einer genauen Struktur folgen. Das hat den Vorteil, dass wir nicht so schnell den Überblick verlieren, wenn wir komplizierte Erweiterungen entwickeln. Der Nachteil ist, dass wir jetzt erstmal diese Struktur anlegen müssen.

In dem Ordner /typo3conf/ext legen wir einen Ordner, dessen Name den Erweiterungs-Schlüssel darstellt. In meinem Fall ist das »le_curos«.

Innerhalb des Erweiterungs-Ordners legen wir diese Ordner-Struktur an, wobei die Groß- und Kleinschreibung zu beachten ist. Innerhalb des Erweiterungs-Ordners legen wir diese Ordner-Struktur an, wobei die Groß- und Kleinschreibung zu beachten ist.

Nun müssen wir noch drei Dateien anlegen, die jede Typo3-Extension aufweisen muss, nämlich ext_emconf.php, ext_localconf.php und ext_tables.php, welche wir alle drei direkt in den Ordner der Extension legen.

Die Datei ext_emconf.php ist dafür zuständig, dem Erweiterungsmanager alle wichtigen Informationen über die Erweiterung zur Verfügung zu stellen. So sieht meine Datei aus:

<?php
	
	$EM_CONF[$_EXTKEY] = array(
		'title' => 'Curos',
		'description' => 'Plugins für die Curos-Webseite.',
		'category' => 'plugin',
		'author' => 'Lars Ebert',
		'author_email' => 'info@advitum.de',
		'author_company' => 'Advitum.de',
		'shy' => 1,
		'priority' => '',
		'module' => '',
		'state' => 'alpha',
		'internal' => '',
		'uploadfolder' => '0',
		'createDirs' => '',
		'modify_tables' => '',
		'clearCacheOnLoad' => 0,
		'lockType' => '',
		'version' => '0.0.1',
		'constraints' => array(
			'depends' => array(
				'extbase' => '6.0',
				'fluid' => '6.0',
				'typo3' => '6.0',
			),
			'conflicts' => array(
			),
			'suggests' => array(
			),
		),
	);
	
?>

Eigentlich sind alle Schlüssel des Arrays selbsterklärend, aber am wichtigsten ist das Array unter constraints.depends, denn hier definieren wir, welche Komponenten die Erweiterung benötigt.

In der Datei ext_localconf.php können wir grundlegende Einstellungen für unsere Erweiterung festlegen, in der Datei ext_tables.php weiterführende, genauere Einstellungen. Fürs erste reicht es, wenn wir die beiden Dateien mit folgendem Inhalt füllen. Dieser sorgt dafür, dass die Dateien nicht manuell aufgerufen werden können.

<?php
	
	if(!defined('TYPO3_MODE')) die ('Access denied.');
	
?>

Wir haben jetzt unsere erste, eigene Typo3-Extension, die wir natürlich direkt über den Extension-Manager installieren!

Schritt 2: Ein Plugin definieren

Um ein Plugin zu definieren, müssen wir Typo3 eigentlich nur mitteilen, wo das Plugin liegt und was aufgerufen werden soll, um den Inhalt des Controllers auszugeben. Zuerst fügen wir in der Datei ext_tables.php folgende Zeile hinzu:

<?php
	
	if(!defined('TYPO3_MODE')) die ('Access denied.');
	
	Tx_Extbase_Utility_Extension::registerPlugin($_EXTKEY, 'headerimage', 'Titelbild');
	
?>

Damit teilen wir Typo3 mit, dass unsere Extension mit dem Schlüssel $_EXTKEY ein Plugin mit der ID »headerimage« und dem Namen »Titelbild« hat. Jetzt könnten wir das Plugin schon über das Backend in die Seite einfügen. Allerdings wüsste Typo3 dann noch nicht, was es zu tun hat, wenn das Plugin angezeigt wird. Dazu müssen wir noch einige Zeilen zur Datei ext_localconf.php hinzufügen.

<?php
	
	if(!defined('TYPO3_MODE')) die ('Access denied.');
	
	Tx_Extbase_Utility_Extension::configurePlugin(
		$_EXTKEY,
		'headerimage',
		array(
			'Static' => 'headerimage'
		),
		array()
	);
	
?>

Hier definieren wir, dass zur Anzeige des Plugins »headerimage« die Action »headerimage« im Controller »Static« aufgerufen werden soll. Hier kommen wir jetzt endlich mit MVC in Berührung. Deshalb schiebe ich hier jetzt schnell ein paar Grundlagen über Controller ein.

Schritt 3: Einen Controller anlegen

Controller stellen in MVC die Kontroll-Einheiten dar. Sie kontrollieren den Programmfluss, welche Modelle benötigt werden und welcher View aufgerufen werden soll. Ein Controller ist in Extbase einfach eine Klasse, in der sich beliebig viele Aktionen befinden können. Im Normalfall, also wenn wir irgendwelche komplexen Anwendungen entwickeln, gehört zu jedem Controller auch ein Modell.

So könnte es in einer Blogging-Extension zum Beispiel einen Articles-Controller geben, der die Artikel verwaltet. In diesem Article-Controller würde es verschiedene Methoden geben, die als Actions bezeichnet werden. Denkbar wäre hier zum Beispiel eine addAction zum Hinzufügen von Artikeln, eine editAction zum Bearbeiten und eine showAction zum Anzeigen eines einzelnen Artikels. Wird im Frontend dann zum Beispiel der Artikel XYZ aufgerufen, wird intern die Methode showAction im ArticlesController aufgerufen, die dafür sorgt, dass der Artikel XYZ angezeigt wird.

Analog gibt es in unserer Extension einen StaticController. Ich habe diesen Controller »Static« genannt, weil hier eben keine wirkliche Interaktion mit der Datenbank geschieht, der Contoller sorgt wirklich nur für die Darstellung von simplem, statischem Inhalt. Bei der Anzeige unseres oben definierten Plugins wird, so wie wir es angegeben haben, in diesem StaticController die Methode headerimageAction aufgerufen. Was müssen wir also tun? Wir müssen diesen Controller und diese Methode anlegen. Dazu erstellen wir eine neue Datei im Controller-Ordner unserer Extension.

<?php
	
	class Tx_LeCuros_Controller_StaticController extends Tx_Extbase_MVC_Controller_ActionController
	{
		public function headerimageAction() {
			
		}
	}
	
?>

In dieser Datei legen wir eine neue Klasse mit Namen Tx_LeCuros_Controller_StaticController an. Tx ist der allgemeine Prefix für alle Typo3-Extensions, LeCuros ist der Name unserer Extension (aus le_curos wird LeCuros), Controller besagt, dass es sich um einen Controller handelt und am Ende steht der eigentliche Name unseres Controllers.

Die Klasse erstellen wir auf Basis der Klasse Tx_Extbase_MVC_Controller_ActionController was zur Folge hat, dass wir grundlegende Controller-Methoden zur Verfügung gestellt bekommen.

In der Methode headerimageAction können wir uns nun nach belieben austoben. Hier findet die Logik unseres Plugins Platz. Ich habe hier dafür gesorgt, dass das mit der aktuellen Seite verknüpfte Bild an den View übergeben wird.

<?php
	
	class Tx_LeCuros_Controller_StaticController extends Tx_Extbase_MVC_Controller_ActionController
	{
		public function headerimageAction() {
			$image = $GLOBALS["TYPO3_DB"]->exec_SELECTgetSingleRow(
				'sys_file.identifier',
				'sys_file, sys_file_reference',
				"sys_file_reference.tablenames = 'pages' AND sys_file_reference.table_local = 'sys_file' AND sys_file_reference.fieldname = 'media' AND sys_file.uid = sys_file_reference.uid_local AND sys_file_reference.uid_foreign = " . $GLOBALS['TSFE']->id,
				'',
				'sorting_foreign'
			);
			
			if(isset($image) && isset($image['identifier'])) {
				$this->view->assign('image', htmlspecialchars($image['identifier']));
			} else {
				$this->view->assign('image', '/templates/curos/img/home.jpg');
			}
		}
	}
	
?>

Die Variable $GLOBALS['TSFE']->id beinhaltet die UID der Typo3-Seite, auf welcher das Plugin gerade eingebettet wird. Mit der Methode $this->view->assign() können wir Variablen an unseren View übergeben. In diesem Fall speichere ich in einer Variable mit Namen »image« den Pfad des anzuzeigenden Bildes.

Der Controller ruft am Ende der Action automatisch den zugehörigen View auf. Jede Action in jedem Controller hat standardmäßig einen eigenen View, diesen müssen wir allerdings noch schnell anlegen.

<img src="/fileadmin{image}" alt="" /><

Der Inhalt meines Views bleibt relativ leer, da ich wirklich nur ein einziges Bild einfügen will.

Die Views einer Extbase-Extension werden mit Fluid realisiert. Für uns heißt das an dieser Stelle lediglich, dass wir auf die eben definierte Variable über {image} zugreifen können. Mit Fluid könnte man hier noch weitere Dinge anstellen, wie zum Beispiel For-Schleifen, Fallunterscheidungen und vieles mehr. Aber auch hier muss ich mich selbst erst einmal genauer mit befassen. Fürs erste soll diese eine Zeile Code jedoch reichen.

Nun müssen wir das Plugin lediglich noch per TypoScript in unsere Seite einbinden.

Schritt 4: Ein Plugin per TypoScript einbinden

Um ein Plugin per Typoscript einzubinden, reicht seit Extbase leider nicht mehr nur noch eine Zeile. Aber wenn man erst einmal weiß, wie es geht, ist es eigentlich auch wieder ganz einfach.

plugin {
  tx_le_curos {
    view {
      templateRootPath = {$plugin.tx_le_headerimage.view.templateRootPath}
      partialRootPath = {$plugin.tx.le_headerimage.view.partialRootPath}
      layoutRootPath = {$plugin.tx_le_headerimage.view.layoutRootPath}
    }
  }
}

Als erstes müssen wir die gesamte Extension initialisieren. Das müssen wir zum Glück nur einmal pro Extension machen, wenn wir also noch ein zweites Plugin aus der Extension einbinden würden, müssten diese Zeilen nur ein mal im Code stehen.

Nun erstellen wir eine Instanz unseres Plugins innerhalb unserer temp-Variable.

temp {
  headerImage = USER
  headerImage {
    userFunc = tx_extbase_core_bootstrap->run
    extensionName = LeCuros
    pluginName = headerimage
  }
}

Mit userFunc = tx_extbase_core_bootstrap->run rufen wir den Bootstrapper von Extbase manuell auf und übergeben ihm als Parameter die Namen unserer Extension und unseres Plugins.

Nun müssen wir als letztes noch das Plugin an der gewünschten Stelle einbinden. Das geschieht bei mir mit folgender Zeile.

page.10.marks.HEADER_IMAGE < temp.headerImage

Abhängig vom Aufbau eures bisherigen TypoScripts kann es sein, dass ihr das Plugin an einer anderen Stelle einbinden müsst, aber die Grundlagen sollten hier klar sein.

Fazit: Wenn man weiß, wie es geht, ist es einfach

Wir haben soeben unser erstes eigenes Plugin mit Extbase realisiert! Und das tolle ist, dass wir nun endlich einen relativ einfachen Einstieg in die Entwicklung mit Extbase haben. Ich empfehle hier nun dringend weiteren Lesestoff, um das Gelernte weiter zu vertiefen. Dazu gebe ich in den Links zum Thema ein paar Linktipps!

Ich hoffe euch hat mein kleines Mini-Tutorial gefallen. Ich würde mich über ein Feedback in den Kommentaren freuen!