Skip to content

Commit 09cec2e

Browse files
linawolffroemken
andauthored
[TASK] Update form ViewHelper page (#112)
* [TASK] Update form ViewHelper page * Use realistic examples together with the corresponding controllers * Warn that it cannot be used without Extbase anymore * Write section about security, content translated and shortened from https://www.typo3lexikon.de/typo3-tutorials/core/systemextensions/fluid/viewhelper/ Releases: main, 13.4, 12.4 * Update Documentation/Global/Form/_codesnippets/_CommentController.php --------- Co-authored-by: Stefan Frömken <[email protected]>
1 parent 49053c6 commit 09cec2e

File tree

8 files changed

+183
-18
lines changed

8 files changed

+183
-18
lines changed

Documentation/Global/Form/Index.rst

Lines changed: 72 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -9,38 +9,92 @@ Form ViewHelper `<f:form>`
99

1010
.. typo3:viewhelper:: form
1111
:source: /Global.json
12-
:display: tags,description,gitHubLink,arguments
12+
:display: tags,description,gitHubLink
13+
:noindex:
14+
15+
.. include:: /_Includes/_ExtbaseFormViewHelpers.rst.txt
16+
17+
.. contents:: Table of contents
1318

1419
.. _typo3-fluid-form-example:
1520

16-
Examples
17-
========
21+
Array parameter passed to Extbase controller action
22+
===================================================
23+
24+
For example a very simplified search form could look like this:
25+
26+
.. literalinclude:: _codesnippets/_PlainParameterForm.html
27+
:caption: packages/my_extension/Resources/Private/Templates/Search/SearchForm.html
28+
29+
The `Extbase controller <https://docs.typo3.org/permalink/t3coreapi:extbase-controller>`_
30+
action could for example look like this:
31+
32+
.. literalinclude:: _codesnippets/_SearchController.php
33+
:caption: packages/my_extension/Classes/Controller/SearchController.php
34+
35+
.. _typo3-fluid-form-example-property:
36+
37+
Property mapping - using the form with a model
38+
==============================================
39+
40+
In most cases you will use the f:form ViewHelper with
41+
`Extbase models <https://docs.typo3.org/permalink/t3coreapi:extbase-model>`_ or
42+
data objects.
43+
44+
For example, user could add a comment in such a form:
1845

19-
A complex form with a specified encoding type
20-
---------------------------------------------
46+
.. literalinclude:: _codesnippets/_CommentForm.html
47+
:caption: packages/my_extension/Resources/Private/Templates/Comment/_CommentForm.html
2148

22-
Form with enctype set::
49+
The Extbase Controller action displaying the form then creates the Domain object
50+
and passes it to the view. In the Fluid template above we use argument
51+
:ref:`object <t3viewhelper:viewhelper-argument-typo3-cms-fluid-viewhelpers-formviewhelper-object>`
52+
to pass any data the object might already contain to the ViewHelper.
2353

24-
<f:form action=".." controller="..." package="..." enctype="multipart/form-data">...</f:form>
54+
By using the argument "property" on the form input elements the properties of
55+
the model are automatically bound to the input elements.
2556

26-
A Form which should render a domain object
27-
------------------------------------------
57+
The controller could look like this:
2858

29-
Binding a domain object to a form::
59+
.. literalinclude:: _codesnippets/_CommentController.php
60+
:caption: packages/my_extension/Classes/Controller/CommentController.php
3061

31-
<f:form action="..." name="customer" object="{customer}">
32-
<f:form.hidden property="id" />
33-
<f:form.textarea property="name" />
34-
</f:form>
62+
If the model is not valid (see `Validation <https://docs.typo3.org/permalink/t3coreapi:extbase-validation>`_)
63+
Extbase will automatically refer the request back to the referring action
64+
(here commentFormAction()). By passing the object with the non-validated object
65+
to the view again, the user can see their faulty inputs and correct them instead
66+
of seeing an empty form.
3567

36-
This automatically inserts the value of ``{customer.name}`` inside the
37-
textarea and adjusts the name of the textarea accordingly.
68+
.. _typo3-fluid-form-security:
69+
70+
Security in Fluid forms
71+
=======================
72+
73+
Fluid automatically adds a hidden field to forms, including an `__hmac`
74+
value. This value lists all allowed fields. If fields are added or
75+
removed via attacks, Extbase detects the mismatch and blocks submission.
76+
77+
Form fields can be grouped in an array for efficient processing. The
78+
receiving action maps the data to a model, where validation occurs if
79+
rules are defined. Only valid data is passed to the action and stored in
80+
the database.
81+
82+
.. _typo3-fluid-form-arguments:
83+
84+
Arguments of the form ViewHelper
85+
================================
86+
87+
.. include:: /_Includes/_ArbitraryArguments.rst.txt
88+
89+
.. typo3:viewhelper:: form
90+
:source: /Global.json
91+
:display: arguments-only
3892

3993

4094
.. _typo3-fluid-form-viewhelpers:
4195

42-
ViewHelpers to be used within the form ViewHelper
43-
=================================================
96+
ViewHelpers for form input elements
97+
===================================
4498

4599
.. toctree::
46100
:titlesonly:
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MyVendor\MyExtension\Domain\Model;
6+
7+
use TYPO3\CMS\Extbase\Annotation\Validate;
8+
use TYPO3\CMS\Extbase\DomainObject\AbstractEntity;
9+
10+
class Comment extends AbstractEntity
11+
{
12+
#[Validate(['validator' => 'EmailAddress'])]
13+
protected string $email = '';
14+
15+
#[Validate(['validator' => 'StringLength', 'options' => ['maximum' => 500]])]
16+
protected string $content = '';
17+
18+
// Getters and setters ...
19+
}
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MyVendor\MyExtension\Controller;
6+
7+
use Psr\Http\Message\ResponseInterface;
8+
use T3docs\BlogExample\Domain\Model\Comment;
9+
use T3docs\BlogExample\Domain\Repository\CommentRepository;
10+
use TYPO3\CMS\Extbase\Annotation\IgnoreValidation;
11+
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
12+
13+
class CommentController extends ActionController
14+
{
15+
public function __construct(
16+
protected readonly CommentRepository $commentRepository,
17+
) {}
18+
19+
#[IgnoreValidation(['argumentName' => 'newComment'])]
20+
public function commentFormAction(?Comment $newComment = null): ResponseInterface
21+
{
22+
if ($newComment === null) {
23+
$newComment = new Comment();
24+
$newComment->setDate(new \DateTime());
25+
}
26+
// The assigned object will be used in argument object
27+
$this->view->assign('newComment', $newComment);
28+
return $this->htmlResponse();
29+
}
30+
31+
public function createAction(
32+
// This parameter must have the same name as argument `objectName` of f:form
33+
Comment $comment,
34+
): ResponseInterface {
35+
$this->commentRepository->add($comment);
36+
$this->addFlashMessage('Comment was saved');
37+
return $this->redirect('show');
38+
}
39+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers"
2+
data-namespace-typo3-fluid="true">
3+
<f:form action="create" controller="Comment" objectName="comment" object="{newComment}" method="post">
4+
<div>
5+
<label for="tx-blogexample-email">E-Mail::</label>
6+
<f:form.textfield property="email" type="email" id="tx-blogexample-email"/>
7+
</div>
8+
<div>
9+
<label for="tx-blogexample-content">Message:</label>
10+
<f:form.textarea property="content" id="tx-blogexample-content" rows="8" cols="46"/>
11+
</div>
12+
<div>
13+
<f:form.submit class="button" value="Submit"/>
14+
</div>
15+
</f:form>
16+
</html>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<f:form action="search" method="post" pageUid="{settings.targetPid}">
2+
<div>
3+
<label for="sword">Search:</label>
4+
<f:form.textfield name="search[sword]" value="{sword}" id="sword" />
5+
</div>
6+
<div>
7+
<f:form.submit name="search[submitButton]" value="Submit" />
8+
</div>
9+
</f:form>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace MyVendor\MyExtension\Controller;
6+
7+
use Psr\Http\Message\ResponseInterface;
8+
use TYPO3\CMS\Extbase\Mvc\Controller\ActionController;
9+
10+
class SearchController extends ActionController
11+
{
12+
public function searchAction(array $search = []): ResponseInterface
13+
{
14+
// TODO: implement search
15+
return $this->htmlResponse();
16+
}
17+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.. admonition:: Allows arbitrary arguments
2+
3+
This ViewHelper allows you to pass arbitrary arguments not defined below
4+
directly to the HTML tag created. This includes custom `data-` arguments.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
.. attention::
2+
.. versionchanged:: 12.0
3+
The f:form ViewHelpers can only be used within the Extbase context.
4+
5+
In a non-Extbase context, for example within a
6+
`FLUIDTEMPLATE <https://docs.typo3.org/permalink/t3tsref:cobj-template>`_
7+
Use plain HTML `<form>` and `<input>` tags.

0 commit comments

Comments
 (0)