.. include:: ../Includes.txt
Rendering the output with fluid
===============================
The TemplateView of Fluid now tries to load the corresponding HTML-Template.
Since there is none specified by ``this->view->setTemplatePathAndFilename($template-PathAndFilename)``
Fluid searches at an place defined by conventions.
All front end templates can be found in :file:`EXT:blog_example/Resources/Private/Templates`
by default. There for example are the two subfolders *Blog* and *Post*.
Since the call was made by the ``indexAction()`` of the ``BlogController`` fluid
searches in the folder *Blog* for a file named *Index* and - if not setup up
differently - the suffix *.html*. So every action method has its own template.
Possible other formats are e.g. *.pdf*, *.json* or *.xml*. In table 3.1 you
can find some examples for these convention.
*Table 3-1: Examples for the convention of template paths*
+-----------+------------+------------+--------------------------------------------+
|Controller |Action |Format |Path and filename |
+-----------+------------+------------+--------------------------------------------+
|Blog |index |unspecified |Resources/Private/Templates/Blog/Index.html |
+-----------+------------+------------+--------------------------------------------+
|Blog |index |txt |Resources/Private/Templates/Blog/Index.txt |
+-----------+------------+------------+--------------------------------------------+
|Blog |new |unspecified |Resources/Private/Templates/Blog/New.html |
+-----------+------------+------------+--------------------------------------------+
|Post |unspecified |unspecified |Resources/Private/Templates/Post/Index.html |
+-----------+------------+------------+--------------------------------------------+
In our case the file *Index.html* will be loaded. The content will be parsed step
by step, line by line. Here you see an extract of the template file:
.. code-block:: html
:caption: Index.html
:name: index-html
Welcome to the Blog Example!
Here is a list of blogs:
-
{blog.title} ()
-
{blog.description}
Edit
Delete
-
Create another blog
Create example data
Delete all Blogs [!!!]
Create your first blog
Create example data
At first all the unknown XML tags with namespace »f« stand out, like ``,
`` or ``. These Tags are provided by Fluid and
represent different functionalities.
* `[…]` modifies linebreaks (new lines) to `
` tags.
* `` creates a link tag that links to the :php:`newAction()` of the actual controller.
* `[...]` iterates over all Blog-objects found in Blogs.
Let's have a closer look at the latter example. In the variable `{blogs}` all
blogs are "included". The curly brackets tell Fluid that it is a variable that
was "assigned" to the template before. In our case this was done in the
:php:`indexAction()` of the `BlogController`. With the attribute `each` the
`for` ViewHelper gets the `blog` objects over whom is to be iterated. The
attribute ``as`` holds the name of the variable with which the `blog` object is
available inside of `[...]`. Here it can be called with `{blog}`.
.. note::
The string `"blog"` is *not* surrounded by brackets when assigned to the `as`
attribute since the string is passed as a *name* for the variable and should not be
parsed by Fluid. An `as="{blog}"` would be parsed as if you would have liked
to make the name of the variable configurable. Rule of thumb: Curly brackets in
`each`, none in `as`.
Objects can not be rendered by Fluid directly. An exception make objects that
have a :php:`__toString()` method. The single properties of such an object can be
accessed with a point-notation. If Fluid crosses a string like `{blog.title}` it
tries to parse it. Fluid expects the variable `blog` to be an object. Inside of
this object it searches for a method named :php:`getTitle()`. The name of the method is
created by extracting the part after the point, capitalizes the first letter and
prefixes a »get«. With this the call looks something like this:
:php:`$blog->getTitle()`. The return value will replace `{blog.title}` in the
template. Analogously `{blog.description}` will be replaced with the description.
Parsing the point goes recursively. That means Fluid can parse a string
`{blog.administrator.name}` by calling a method that equals
:php:`$blog->getAdministrator()->getName()`.
.. note::
The return value is "tidied up" by :php:`htmlspecialchars()`. That protects from
Cross Site Scripting-Attacks (XSS).
As soon as Fluid is done with the whole template the result is appended to the
`Response` object. This is done in the :php:`\TYPO3\CMS\Extbase\Mvc\Controller\ActionController`
by the call :php:`$this->response->appendContent($this->view->render())`.
Our journey slowly comes to an end. The *Request* is been fully answered by a
corresponding Action. The `Response` object carries the completely generated
content. We now sally forth heavy hearted the return trip stopping once more at
the dispatcher of Extbase.