Typo3 Extensions mit Extbase und Fluid – Ein Basic Plugin mit Controller und View

Da wir jetzt die Basics kennen, starten wir mal wieder von null und bauen eine neue Extension. Dieses Mal noch ohne Model, aber dafür lernen wir hier viel über den Umgang mit Controllern und Views. Zusätzlich geht es um die Steuerung über Flexforms sowie die üblichen Goodies.

Es geht um ein einfaches Plugin, dass einen einfachen Rechner bereitstellt, wie z.B. in der Praxis in einem Bau-Material Shop-System eine Verbrauchsrechnung anhand der Fläche, um die Bestellmenge besser kalkulieren zu können.

Wir nennen das Kind ‚tut23plugin‘ und werfen einen Blick auf seine Struktur.

  • tut23plugin
    • Classes
      • Controller
    • Configuration
      • TypoScript
      • FlexForms
    • Resources
      • Private
        • Layouts
        • Partials
        • Templates
      • Public
    • ext_emconf.php
    • ext_localconf.php
    • ext_tables.php
    • ext_icon.gif

Unsere ext_emconf.php sollte mittlerweile selbst erklärend sein.

$EM_CONF[$_EXTKEY] = array(
    'title' => 'Verbrauchs-Rechner',
    'description' => 'Verbrauchs-Rechner',
    'category' => 'plugin',
    'author' => 'YOUR_NAME',
    'author_email' => 'YOU@YOUR_COMPANY.com',
    'author_company' => 'YOUR_COMPANY',
    'shy' => '',
    'priority' => '',
    'module' => '',
    'state' => 'stable',
    'internal' => '',
    'uploadfolder' => '0',
    'createDirs' => '',
    'modify_tables' => '',
    'clearCacheOnLoad' => 0,
    'lockType' => '',
    'version' => '',
    'constraints' => array(
        'depends' => array(
            'typo3' => '6.2',
        ),
        'conflicts' => array(
        ),
        'suggests' => array(
        ),
    ),
);

Im nächsten Schritt registrieren wir unsere Extension in der ext_tables.php im Typo3 Backend System, damit sie auch in der Plugin Auswahl erscheint. Dies geschieht ganz einfach über die registerPlugin Funktion und dem Globalen Wert $_EXTKEY, sowie dem Extension Identifier und dem Extension Namen.

if (!defined('TYPO3_MODE')) {
	die ('Access denied.');
}
/**
 * Register Plugin
 */

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::registerPlugin(
    $_EXTKEY,
    'Tut23plugin',
    'Tutorial Verbrauchs-Rechner'
);

/**
 * Add TS Config
 */
\TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile($_EXTKEY, 'Configuration/TypoScript', 'Tutorial Verbrauchs-Rechner');

Hier sei mal wieder die Klasse ExtensionUtility erwähnt, um die Ausführung der einzelnen Funktionen zu verstehen. Wir haben natürlich wie schon bekannt auch unser statisches Template integriert, da wir die TypoScript Definitionen unbedingt brauchen.

Unser neues Thema ist jetzt die Einbindung von Controllern und deren Funktionsweise. Starten wir mit der Konfiguration des ersten Extension Controllers. In der ext_localconf.php müssen wir diesen und seine Actions konfigurieren.

\TYPO3\CMS\Extbase\Utility\ExtensionUtility::configurePlugin(
	'Tutorial23.' . $_EXTKEY,
	'Tut23plugin',
	array(
		'Tut23plugin' => 'show',

	),
	// non-cacheable actions
	array(
		'Tut23plugin' => 'show',

	)
);

Die Funktion configurePlugin($extensionName, $pluginName, array $controllerActions, array $nonCacheableControllerActions = array()) wird in Extbase genutzt, um die Controller und deren Actions zu definieren. Die ersten zwei Parameter sind durch unseren Extension Namen eindeutig verstehbar. Im ersten Array bestimmen wir mit dem Array-Key den Controller und dem Inhalt die Actions des Controllers, wobei die Erstgenannte Action als Default Action verwendet wird. Der zweite Array ist dazu da, um Actions aus dem Cache System von Typo3 zu befreien, da es immer wieder Anwendungen gibt, wie z.B. Live Ticker, die außerhalb des Typo3 Cache laufen müssen. Durch weitere Keys können in den Arrays zusätzliche Controller definiert werden und die Extension wachsen lassen.

Also legen wir unseren Controller im Ordner Class/Controller/ an. Die Namensgebung der Datei ist klar durch unsere Definition in der ext_localconf.php vorgegeben. ‚Controller Name‘ plus ‚Controller‘, in unserem Fall also Tut23pluginController.php.

namespace Tutorial23\Tut23plugin\Controller;

class Tut23pluginController extends \TYPO3\CMS\Extbase\Mvc\Controller\ActionController {

	/**
	* @return void
	*/
	public function showAction(){
		$this->view->assign('calcParameter', '2.5');
	}
}

Das sieht erstmal nach wenig aus, doch gibt es hier einiges zu beachten. Als erstes muss der ’namespace‘ vorhanden sein, welcher sich, aus dem Vendor Name, dem registrierten Extension Name und dem Ordner Controller zusammensetzt. Ein Blick in die Typo3 Dokumentation erklärt da einiges.

Unser Controller wird eindeutig mit der Struktur wie im schon beschriebenen Dateinamen als Klasse angelegt und durch die Vererbung mit der ‚\TYPO3\CMS\Extbase\Mvc\Controller\ActionController‘ Standard Klasse erweitert. Jetzt müssen alle in der ext_localconf.php definierten Actions als public function mit dem Titel benannte Action plus Action angelegt werden.

Klingt erstmal kompliziert, aber wenn man das mal gemacht hat, eigentlich ziemlich einfach. Zusätzlich übergeben wir mit $this->view->assign() unserem Template die Variable ‚calcParameter‘ mit dem Wert ‚2.5‘, der den Verbrauchsfaktor für den Verbrauchsrechner darstellt. Auf diesen können wir dann in unserem Template durch die Variablen Schreibweise ‚{calcParameter}‘ zugreifen.

Durch das Anlegen des Controllers wird eine klare Struktur der Template Hierarchie initiiert. Zu jeder Action des Controllers gehört ein View-Template, dass sich nach einem definierten Routing jeweils als Datei mit dem Namen der Action.html (UpperCase) in einem nach dem Controller benannten Ordner (UpperCase) befindet. In unserem Fall also tut23plugin/Resources/Private/Templates/Tut23plugin/Show.html. Diese Datei wird automatisch zu der Action geladen.

<f:layout name="Default" />
<f:section name="main">
<p>Mit diesem Rechner können sie die benötigte Farbmenge berechnen.</p>
<p>
	<label for="distance">Höhe der Wände</label>
	<f:form.textfield id="calcLength" class="calcInput"/>
</p>
<p>
	<label for="value">Umfang des Raumes</label>
	<f:form.textfield id="calcWidth" class="calcInput"/>
</p>
<p>
	Sie brauchen: <span id="calcResult"></span>
</p>

<script>
$(document).ready( function () {
	var calc = '{calcParameter}';
	calc = parseFloat(calc.replace(',', '.'));	

	$('.calcInput').keyup(function(){
		var calcLength = $('#calcLength').val().replace(',', '.');
		var calcWidth = $('#calcWidth').val().replace(',', '.');
		if( isNumeric(calcWidth) && isNumeric(calcLength) ) {
			var calcResult = parseFloat(calcLength) * parseFloat(calcWidth) * 2.5;
			calcResult =  Math.round(calcResult * 100) / 100 ;
			$('#calcResult').text(calcResult + ' Liter');
		} else {
			$('#calcResult').text('Keine gültige Eingabe!');
		}
	});
});

function isNumeric(n) {
  return !isNaN(parseFloat(n)) && isFinite(n);
}
</script>
</f:section>

Hier haben wir gleich auch noch eine Hürde eingebaut, in dem wir über die Fluid Layouts gehen. Man sollte sich angewöhnen dieses System zu berücksichtigen. Alles was es dazu zu tun gibt, ist noch die Default.html in Ressources/Private/Layouts anzulegen.

<f:render section="main" />

Das Template Routing wird durch die Typo3 Constants definiert und muss in unserer Extension noch klar definiert werden. Dafür erweitern wir unsere constants.txt durch die Standard Extbase Fluid Extension Definition für das Template Routing.

plugin.tx_tut23plugin {
    view {
        # cat=plugin.tx_tut23plugin/file; type=string; label=Path to template root (FE)
        templateRootPath = EXT:tut23plugin/Resources/Private/Templates/
        # cat=plugin.tx_tut23plugin/file; type=string; label=Path to template partials (FE)
        partialRootPath = EXT:tut23plugin/Resources/Private/Partials/
        # cat=plugin.tx_tut23plugin/file; type=string; label=Path to template layouts (FE)
        layoutRootPath = EXT:tut23plugin/Resources/Private/Layouts/
    }
}

Die auskommentierten Zeilen haben hier eine wichtige Berechtigung, da sie die Definitionen für den Typo3 Template Konstanten Editor beherbergen und so eindeutig im Editor dargestellt werden können.

Extbas-Fluid-Plugin-Constant-Editor

In der setup.txt müssen wir natürlich die Werte übernehmen, damit sie auch im System jederzeit greifbar sind.

plugin.tx_tut23plugin {
	view {
		templateRootPath = {$plugin.tx_tut23plugin.view.templateRootPath}
		partialRootPath = {$plugin.tx_tut23plugin.view.partialRootPath}
		layoutRootPath = {$plugin.tx_tut23plugin.view.layoutRootPath}
	}
}

Jetzt ist alles soweit fertig und wir können die Extension installieren und unseres kleines Plugin testen. Im Frontend haben wir ein zufriedenstellendes Ergebnis.

Mengenrechner

Das war es dann auch für den ersten Moment. Im nächsten Schritt geht es dann um die Konfigurationen der Extension durch Flexforms und Settings sowie noch das Goodie.