Seit kurzem stehen auf typo3.org die Extensions lib und div im TER zum Download bereit, welche das Model-View-Controller Konzept in TYPO3 für die Extensionentwicklung bereitstellt. Diese beiden Extensions(tx_lib, tx_div) sollen in Zukunft eine Alternative zur pi_base bereitstellen. Die Entwicklung wird von der TYPO3-Association geleitet (Newsgroup:Extension-Coordination-Team), Hauptentwickler ist Elmar Hinz.
Das Konzept wurde zuerst von Trygve Reenskaug als Seeheim-Modell beschrieben und wurde für Benutzeroberflächen in Smalltalk genutzt. Das war wohl in den 70ern, und seit dem hat es sich als Standard bei komplexen Softwaresystemen etabliert. TYPO3 ist, wie wir alle wissen, auch eine mittlerweile komplexe Software und arbeitet praktisch auch schon mit diesem Konzept. Bei Desktopanwendungen spricht man meist von "Events". Das kann ein Schieberegler, Mausklick etc. sein, in Webanwendungen von "Actions", das kann ein Formular oder URL-Parameter sein. Meist spielen ein View und ein Controller zusammen, wohingegen das Model nix von beiden weiß.
//hiermit ermöglichen wir das Vererben des "Hauptcontrollers" require_once(t3lib_extMgm::extPath('div') . 'class.tx_div.php'); tx_div::load('tx_lib_controller'); //unsere Klasse vererbt Funktionen die das MVC-Konzept integrieren class tx_mvclogin_controllers_login extends tx_lib_controller{ //der Exension key var $extKey = 'mvclogin'; //die Action wenn keine Action vom View aufgrufen worde var $defaultAction = 'login'; //da lib/div momentan noch recht schmal im Funktionsumfang, hier ein paar Hilfsfunktionen var $functions; //checkt den login state und setzt die defaultAction function tx_mvclogin_controllers_login() { if($GLOBALS['TSFE']->fe_user->user['username']) $this->defaultAction = 'logout'; //instanziere Hilfsfunktionen $this->functions = tx_div::makeInstance('tx_mvclogin_controllers_functions'); } //zeigt ein loginform an function loginAction($out, $conf, $parameters) { //xml von pluginconfig wird hinzugefuegt $conf = $this->functions->flexToConf($conf,$this->cObj->data['pi_flexform']); //wir instanzieren den view $view = tx_div::makeInstance('tx_mvclogin_views_login'); // uebergeben dem view die configuration $view->setConfiguration($conf); //setzen die parameters(get/post) $view->setParameters($parameters); und setzen den pfad wo der view die templates suchen soll $view->setTemplatePath($this->extPath() . 'views/templates/login/'); //mit render wird dann die ausgabe zurueckgegeben return $view->render('login'); } function logoutAction($out, $conf, $parameters) { $conf = $this->functions->flexToConf($conf,$this->cObj->data['pi_flexform']); $view = tx_div::makeInstance('tx_mvclogin_views_login'); $view->setConfiguration($conf); $view->setParameters($parameters); $view->setTemplatePath($this->extPath() . 'views/templates/login/'); return $view->render('logout'); } function forgotAction($out, $conf, $parameters) { $conf = $this->functions->flexToConf($conf,$this->cObj->data['pi_flexform']); //wir brauchen ein model um auf die fe_user tabelle $model = tx_div::makeInstance('tx_mvclogin_models_feuser'); //setzten die pid $model->setFolder((int)$conf['sDEF']['userFolder']); $model->setLanguage(0); //wenn eine emal vorhanden aus paramertrn sicht das model nach dem fe_user if(t3lib_div::validEmail($this->parameters['email'])) $result = $model->select(null,null,$this->parameters['email']); //wir holden uns den view $view = tx_div::makeInstance('tx_mvclogin_views_login'); $view->setConfiguration($conf); $view->setParameters($parameters); //wir uebergeben dem view das db result $view->exchangeArray($result); $view->setTemplatePath($this->extPath() . 'views/templates/login/'); return $view->render('forgot'); } }
tt_content.list.20.mvclogin_login =< plugin.tx_mvclogin_login plugin.tx_mvclogin_login.userFolder = {$plugin.tx_mvclogin.userFolder} plugin.tx_mvclogin_login = USER_INT plugin.tx_mvclogin_login.includeLibs = EXT:any_mvclogin/controllers/class.tx_mvclogin_controllers_login.php plugin.tx_mvclogin_login.userFunc = tx_mvclogin_controllers_login->main plugin.tx_mvclogin_login._CSS_DEFAULT_STYLE ( form.tx_mvclogin_login label{ font-size: 9px; } form.tx_mvclogin_login input { width: 78px; margin: 1px 0 1px 0; padding: 1px 0 1px 0; border: 1px solid #dbdbed; font-size: 9px; color: #333366; } form.tx_mvclogin_login submit{ width: 30px; margin: 0; padding: 0; font-size: 10px; color: #333366; background: #dbdbed; border: 1px solid #dbdbed; } )
//wo soll unser login nach user suchen plugin.tx_mvclogin.userFolder = 204 //hier könnte man auch wrapelemente definieren...
t3lib_div::loadTCA('tt_content'); // list plugins in plugin selection t3lib_extMgm::addPlugin(Array('LLL:EXT:mvclogin/locallang_db.php:loginPluginLabel','mvclogin_login'),'list_type'); //kosmetik $TCA['tt_content']['types']['list']['subtypes_excludelist']['mvclogin_login']='layout,select_key'; // list static templates in templates selection t3lib_extMgm::addStaticFile('mvclogin','static','MVC Login TS');
Um nun selbst mit diesen Extensions zu arbeiten sollte man als Erstes die Quellcodes von tx_lib und tx_div studieren. Desweiteren gibt es auch eine Demoextension, mit Namen tx_articles, welche das MVC-Konzept am Beispiel zeigt. Sehr zu empfehlen, da bisher die einzige Dokumentation, ist das Buch "Typo3 4.0 Handbuch für Entwickler". Hier werden detailliert die Klassen erklärt, und am Beispiel von tx_articles eine Extension Schritt für Schritt erstellt. Sehr zu empfehlen ist auch die Newsgroup des ECT. Lib/Div sind zwar im Moment noch sehr schmal im Funktionsumfang, aber es lohnt sich schon jetzt damit zu arbeiten, da man mit dem MVC-Konzept die Power von PHP5 erst richtig nutzen kann.