8. Template Engines heute
Klassisches TYPO3 Templating
marker / subpart-basiert
kein Kontrollfluss
nicht erweiterbar
Arbeit mit Arrays oder Objekten schwierig
Inspiring people to
Fluid Templating share
9. Template Engines heute
Klassisches TYPO3 Templating
###CONTENTS###
<h2>###TITLE###</h2>
Text
###CONTENTS###
Inspiring people to
Fluid Templating share
13. Template Engines heute
Smarty
<ul>
{foreach from=$myArray item=foo}
<li>{$foo}</li>
{/foreach}
</ul>
Inspiring people to
Fluid Templating share
14. Template Engines heute
Smarty
PHP4-basiert
eigene {...}-Syntax - keine Autocompletion
Funktionen gehören zum Sprachumfang - keine
Namespaces
alle Funktionen eingebaut
Selbstgeschriebene Funktionen können vom
Namen her miteinander kollidieren
Inspiring people to
Fluid Templating share
15. Template Engines heute
PHPTAL
<div class="item" tal:repeat="item itemsArray">
<span tal:condition="item/hasDate" tal:replace="item/
getDate"/>
<a href="${item/getUrl}" tal:content="item/getTitle"/>
<p tal:content="value/getContent"/>
</div>
Inspiring people to
Fluid Templating share
16. Template Engines heute
PHPTAL
well-formed XML, but NOT VALID (no DTD /
Schema)
Semantik teilweise unintuitiv
PHP im template möglich
Keine autocompletion
Schwer erweiterbar
Inspiring people to
Fluid Templating share
17. Template Engines heute
Nachteile aktueller Engines
Nicht vollständig objektorientiert / brechen
objektorientierte Paradigmen an einigen Stellen
schwer zu benutzen für nicht-HTML-Templates
keine Autocompletion in Editoren
nicht einfach erweiterbar
Inspiring people to
Fluid Templating share
43. Formulare
v4 v5
Inspiring people to
Fluid Templating share
44.
45. Fortgeschrittene Konzepte
Formulare
/**
* Displays a form for creating a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh blog object taken as a basis for the rendering
* @return string An HTML form for creating a new blog
* @dontvalidate $newBlog
*/
public function newAction(F3BlogDomainModelBlog $newBlog = NULL) {
$this->view->assign('newBlog', $newBlog);
}
/**
* Creates a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh Blog object which has not yet been added to the repository
* @return void
*/
public function createAction(F3BlogDomainModelBlog $newBlog) {
$this->blogRepository->add($newBlog);
$this->pushFlashMessage('Your new blog was created.');
$this->redirect('index');
}
Inspiring people to
Fluid Templating share
48. Fortgeschrittene Konzepte
Formulare
/**
* Displays a form for creating a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh blog object taken as a basis for the rendering
* @return string An HTML form for creating a new blog
* @dontvalidate $newBlog
*/
public function newAction(F3BlogDomainModelBlog $newBlog = NULL) {
$this->view->assign('newBlog', $newBlog);
}
/**
* Creates a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh Blog object which has not yet been added to the repository
* @return void
*/
public function createAction(F3BlogDomainModelBlog $newBlog) {
$this->blogRepository->add($newBlog);
$this->pushFlashMessage('Your new blog was created.');
$this->redirect('index');
}
Inspiring people to
Fluid Templating share
49. Fortgeschrittene Konzepte
Formulare
/**
* Displays a form for creating a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh blog object taken as a basis for the rendering
* @return string An HTML form for creating a new blog
* @dontvalidate $newBlog
*/
public function newAction(F3BlogDomainModelBlog $newBlog = NULL) {
$this->view->assign('newBlog', $newBlog);
}
/**
* Creates a new blog
*
* @param F3BlogDomainModelBlog $newBlog A fresh Blog object which has not yet been added to the repository
* @return void
*/
public function createAction(F3BlogDomainModelBlog $newBlog) {
$this->blogRepository->add($newBlog);
$this->pushFlashMessage('Your new blog was created.');
$this->redirect('index');
}
Inspiring people to
Fluid Templating share
66. Fortgeschrittene Konzepte
Cross Site Scripting
<h2>{post.title}</h2>
<p>{post.contents}</p>
automatisch
escaped
Implizit!
Fluid Templating Inspiring people to
share
67. Fortgeschrittene Konzepte
Automatische XSS-Vorbeugung
alle ObjectAccessors, welche nicht in
Argumenten stehen, werden escaped
<f:..... foo="{bar}">{something}</f:...>
nicht escaped
escaped
Inspiring people to
Fluid Templating share
72. Fortgeschrittene Konzepte
Conditions
Boolesche Werte haben immer die Form
XX Operator YY
XX / YY ist Object Accessor, Inline Notation, Zahl,
aber KEIN String.
Operator ist z.B. >, >=, <, <=, %, !=, ==
Dies ist immer möglich, wenn Argument vom
Typ boolean registriert ist
Inspiring people to
Fluid Templating share
74. Fortgeschrittene Konzepte
<f:cObject>
<!-- im Template -->
<f:cObject typoscriptObjectPath="lib.myCounter">{posts.count}</f:cObject>
<!-- oder -->
<f:cObject typoscriptObjectPath="lib.myCounter" data=“{posts.count}“ />
<!-- oder -->
{posts.count->f:cObject(typoScriptObjectPath: 'lib.myCounter')}
<!-- im TypoScript Setup -->
lib.myCounter = TEXT
lib.myCounter {
current = 1
wrap = <strong> | </strong>
}
Inspiring people to
Fluid Templating share
75. Fortgeschrittene Konzepte
<f:cObject>
<!-- im Template -->
<f:cObject typoscriptObjectPath="lib.myCounter">{post}</f:cObject>
<!-- oder -->
<f:cObject typoscriptObjectPath=“lib.myCounter“ data=“{post}“ />
<!-- oder -->
{post -> f:cObject(typoscriptObjectPath: 'lib.myCounter')}
<!-- im TypoScript Setup -->
lib.myCounter = COA
lib.myCounter {
10 = TEXT
10.field = title
20 = TEXT
20.field = author
wrap = <strong> | </strong>
Inspiring people to
}
Fluid Templating share
76. Fortgeschrittene Konzepte
<f:translate>
<f:translate key=“name“ default="Standard" />
{f:translate(key: 'name', default: 'My Name')}
<f:translate key="foo" arguments="{0:post.name,
1:post.author}" />
in der locallang.xml: "%1$s (by %0$s)"
Inspiring people to
Fluid Templating share
77. Fortgeschrittene Konzepte
Zusammenfassung
Formulare
Layouts und Partials
Inline-Notation und Chaining von VHs
XSS-Vorbeugung
intuitive Syntax für boolesche Werte
mächtige Standard-ViewHelper Library
Inspiring people to
Fluid Templating share
79. Eigene ViewHelper
v4 Aufgabe: Gravatar ViewHelper
soll eine E-Mail-Adresse bekommen, und den
Gravatar-ViewHelper ausgeben, falls vorhanden.
Erwartete Ausgabe:
<img src=“http://www.gravatar.com/avatar/md5
($email).jpg“ />
Inspiring people to
Fluid Templating share
80. Eigene ViewHelper
v4 Aufgabe: Gravatar ViewHelper
Erwartete Verwendung:
{namespace blog=Tx_Blog_ViewHelpers}
<blog:gravatar email=“sebastian@typo3.org“ />
Inspiring people to
Fluid Templating share
81. Eigene ViewHelper
v4 1. ViewHelper-Skelett anlegen
class Tx_Blog_ViewHelpers_GravatarViewHelper
extends Tx_Fluid_Core_AbstractViewHelper {
public function render() {
return ‘Hello World‘;
}
}
Inspiring people to
Fluid Templating share
82. Eigene ViewHelper
v4 2. Implementieren!
PHPDoc
muss für Validierung
/** existieren.
* @param string $email The email to render as gravatar
*/
public function render($email) {
return ‘http://www.gravatar.com/gravatar/‘ . md5($email);
}
Alle Methodenparameter
werden automatisch ViewHelper-
Argumente.
Inspiring people to
Fluid Templating share
89. Ressourcen
Forge-Projekte "Fluid" und "MVC Framework"
(und dazugehöriger SVN)
https://svn.typo3.org/TYPO3v4/CoreProjects/
MVC/ -> Extbase, Fluid (v4), Blog Example,
Viewhelpertest
Inspiring people to
Fluid Templating share