Skip to content
234 changes: 234 additions & 0 deletions Documentation/ApiOverview/Fluid/UsingFluidInTypo3.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ Here are some examples of how Fluid can be used in TYPO3:
* :php:`TYPO3\CMS\Extbase\Mvc\View\ViewResolverInterface`
* :php:`TYPO3\CMS\Extbase\Mvc\View\GenericViewResolver`

.. contents::
:local:

.. _fluid-syntax-viewhelpers-import-namespaces:

Expand Down Expand Up @@ -142,6 +144,238 @@ The namespace here is 'my'. For further information visit
`ViewHelper namespaces <https://docs.typo3.org/permalink/fluid:viewhelper-namespaces-syntax>`_
in Fluid explained.

.. _using_fluid_components:

Using Fluid components
======================

.. _description_fluid_components:

Description
-----------

With version 4.3 the concept of components was introduced into Fluid.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe this needs a ".. versionadded:: 14.3" instead of a description?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is about Fluid, I think it is sufficient to just mention it in the text.


.. _what_is_fluid_components:

Introduction to Fluid components
--------------------------------

The typical look of a component is like a normal Fluid template, except
that it defines all of its arguments with the
`Argument ViewHelper <f:argument> <https://docs.typo3.org/permalink/t3viewhelper:typo3fluid-fluid-argument>`_.
The `Slot ViewHelper <f:slot> <https://docs.typo3.org/permalink/t3viewhelper:typo3fluid-fluid-slot>`_
can be used to receive other HTML content. With the Slot ViewHelper it is possible to nest components.

Example: How you could define a Fluid component

.. code-block:: html
:caption: EXT:my_extension/Resources/Private/Components/Molecule/TeaserCard/TeaserCard.fluid.html

<html
xmlns:my="http://typo3.org/ns/MyVendor/MyExtension/Components"
data-namespace-typo3-fluid="true"
>

<f:argument name="title" type="string" />
<f:argument name="link" type="string" />
<f:argument name="icon" type="string" optional="{true}" />

<a href="{link}" class="teaserCard">
<f:if condition="{icon}">
<my:atom.icon identifier="{icon}">
</f:if>
<div class="teaserCard__title">{title}</div>
<div class="teaserCard__content"><f:slot /></div>
</a>

The example also demonstrates that components can (and should) use other components, in this
case :html:`<my:atom.icon>`.
Depending on the use case, it might also make sense to pass the output of one component
to another component via a slot:

.. code-block:: html

<html
xmlns:my="http://typo3.org/ns/MyVendor/MyExtension/Components"
data-namespace-typo3-fluid="true"
>

<my:molecule.teaserCard
title="TYPO3"
link="https://typo3.org/"
icon="typo3"
>
<my:atom.text>{content}</my:atom.text>
</my:molecule.teaserCard>

You can learn more about components in
`Defining Components <https://docs.typo3.org/permalink/fluid:components-definition>`_. Note
that this is part of the documentation of Fluid Standalone, which means that it doesn't mention
TYPO3 specifics.

.. _register_fluid_components:

Registering component collections
---------------------------------

In order to use Fluid components register a component collection
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
In order to use Fluid components register a component collection
In order to use Fluid components, register a component collection

within the file :file:`Configuration/Fluid/ComponentCollections.php`

.. code-block:: php
:caption: EXT:my_extension/Configuration/Fluid/ComponentCollections.php

<?php
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we put this into a separate file? This way, the file is automatically formatted.


return [
'MyVendor\\MyExtension\\Components' => [
'templatePaths' => [
10 => 'EXT:my_extension/Resources/Private/Components',
],
],
];

in which you define the path your Fluid components can be found.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
in which you define the path your Fluid components can be found.
in which you define the path where your Fluid components can be found.

Components in that collections can then be used in any Fluid template.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Components in that collections can then be used in any Fluid template.
Components in these collections can then be used in any Fluid template.


.. code-block:: html
:caption: EXT:my_extension/Resources/Private/Templates/Template.fluid.html

<html
xmlns:my="http://typo3.org/ns/MyVendor/MyExtension/Components"
data-namespace-typo3-fluid="true"
>

<my:organism.header.navigation />

Note that by default, component collections use a folder structure that
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Note that by default, component collections use a folder structure that
Note that, by default, component collections use a folder structure that

requires a separate directory per component.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
requires a separate directory per component.
requires a separate directory for each component.

That means, for example, imagine you defined a navigation Fluid component.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
That means, for example, imagine you defined a navigation Fluid component.
That means, for example, if you have defined a navigation Fluid component

Then the file
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Then the file
then the file

:file:`EXT:my_extension/Resources/Private/Components/Organism/Header/Navigation/Navigation.fluid.html`
should be stored in path `my_extension/Resources/Private/Components/Organism/Header/Navigation`.

All arguments that are passed to a component need to be defined with
:html:`<f:argument>` in the component template, for example
:file:`Navigation.fluid.html`.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mention "Navigation.fluid.html", but is there an example available where someone can see the <f:argument>s?


<<<<<<< HEAD
It is possible to adjust these configurations per collection:
=======
It is possible to adjust these configurations per collection:
>>>>>>> 93252369 (Add changes)

* using `templateNamePattern` allows you to use a different folder structure,
available variables are `{path}` and `{name}`. For example,
with :html:`<my:organism.header.navigation>`, `{path}` would be
`Organism/Header` and `{name}` would be `Navigation`.
* setting `additionalArgumentsAllowed` to `true` allows passing undefined arguments
to components.

Here is an example where these configurations are used.

.. code-block:: php
:caption: EXT:my_extension/Configuration/Fluid/ComponentCollections.php

<?php

return [
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please use a full example so it is clear where to put this snippet.

'MyVendor\\MyExtension\\Components' => [
'templatePaths' => [
10 => 'EXT:my_extension/Resources/Private/Components',
],
'templateNamePattern' => '{path}/{name}',
'additionalArgumentsAllowed' => true,
],
];

Using this example :html:`<my:organism.header.navigation />` would point to
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
Using this example :html:`<my:organism.header.navigation />` would point to
Using this example, :html:`<my:organism.header.navigation />` would point to

:file:`EXT:my_extension/Resources/Private/Components/Organism/Header/Navigation.fluid.html`
(note the missing :file:`Navigation` folder).

It is possible to influence certain aspects of Fluid components using PSR-14 events,
see `PSR-14 events for Fluid components <https://docs.typo3.org/permalink/changelog:feature-108508-1765987847>`_.

.. _history_fluid_components:

History of Fluid components
---------------------------

In TYPO3 v13 it is possible to use components in TYPO3 projects by creating a custom
:php:`ComponentCollection` class that essentially connects a folder of template files
to a Fluid ViewHelper namespace. Using that class it is also possible to use an
alternative folder structure for a component collection and to allow passing
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
alternative folder structure for a component collection and to allow passing
alternative folder structure for a component collection and to allow

arbitrary arguments to components within that collection.
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
arbitrary arguments to components within that collection.
arbitrary arguments to be passed to components in that collection.


.. _migration_co-existence_fluid_components:

Migration and co-existence with class-based collections
-------------------------------------------------------

Since TYPO3 v14 you should use the configuration-based component collections over
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I suggest to first create a PR for v13 and main. When this is merged/backported (and all work done for v13), then the v14 part should be worked on which is then merged only to main.

Otherwise you end up with documentation for v14 in v13 docs - which is not really ideal.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd argue that Fluid Components shouldn't really be documented for TYPO3 v13. The fact that they could be used in v13 was kind of a hack, now official support is added with v14, which is when this should be documented in the TYPO3 documentation.

Nevertheless, if you come from v13, there should be a place that shows how to migrate the old implementation to the new one.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay, fine for me. As a "Releases" line is lacking, it was not obvious for which branches the PR is meant.

the class-based. A configuration-based component collection is a collection defined
by the configuration file :file:`ComponentCollections.php`. In contrast to that, a
class-based component required custom PHP code in TYPO3 v13, see
`Fluid components in Fluid explained <https://docs.typo3.org/permalink/fluid:components-setup>`_.
Most use cases can easily be migrated to the configuration-based approach, since
they usually just consist of boilerplate code around the configuration options.

In fact, you can use both component collection types side by side. For more
advanced use cases, it might still be best to ship a custom class to define
a component collection. Since the configuration-based approach is not available in TYPO3 v13,
it is possible to ship both variants to provide backwards-compatibility:
if a specific component collection is
defined both via class and via configuration, in TYPO3 v13 the class will be used,
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
defined both via class and via configuration, in TYPO3 v13 the class will be used,
defined both by class and by configuration, in TYPO3 v13 the class will be used,

while in TYPO3 v14 the configuration will be used and the class will be ignored completely.

.. _extending_component-collections_fluid_components:

Extending component collections from other extensions
-----------------------------------------------------

It is possible to extend the configuration of other extensions using the
introduced configuration file. This allows integrators to merge their own set of
components into an existing component collection:

.. code-block:: php
:caption: EXT:vendor_extension/Configuration/Fluid/ComponentCollections.php

<?php

return [
'SomeVendor\\VendorExtension\\Components' => [
'templatePaths' => [
10 => 'EXT:vendor_extension/Resources/Private/Components',
],
],
];

.. code-block:: php
:caption: EXT:my_extension/Configuration/Fluid/ComponentCollections.php

<?php

return [
'SomeVendor\\VendorExtension\\Components' => [
'templatePaths' => [
1765990741 => 'EXT:my_extension/Resources/Private/Extensions/VendorExtension/Components',
],
],
];

For template paths, the familiar rule applies: they will be sorted by their
keys and will be processed in reverse order. In this example, if `my_extension`
defines a component that already exists in `vendor_extension`, it will override
the original component in `vendor_extension`.

.. _psr_14_events_fluid_components:

PSR-14 events for Fluid components
----------------------------------

There are three new PSR-14 events to influence the processing and rendering of
Fluid components that can be registered using the new configuration file.
(see `Feature: #108508 - Fluid components integration <https://docs.typo3.org/permalink/changelog:feature-108508-1765987901>`_).

.. _generic-view-factory:

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<?php

return [
'MyVendor\\MyExtension\\Components' => [
'templatePaths' => [
10 => 'EXT:my_extension/Resources/Private/Components',
],
],
];
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,9 @@

.. code-block:: php

'LLL:EXT:core/Resources/Private/Language/locallang_core.xlf:labels.depth_0'
'LLL:core.messages:labels.depth_0'
'core.messages:labels.depth_0' // LLL: prefix is optional
'LLL:EXT:core/Resources/Private/Language/locallang_custom.xlf:labels.depth_0'
'LLL:core.custom:labels.depth_0'
'core.custom:labels.depth_0' // LLL: prefix is optional

This looks up the given .xlf file path or translation domain in the 'core' extension for label labels.depth_0

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

:param $key: The key from the LOCAL_LANG array for which to return the value.
:param $extensionName: The name of the extension or domain name (such as "myextension.messages"), default: NULL
:param $arguments: The arguments of the label, being passed over to sprintf, default: NULL
:param $arguments: The arguments for the label. For sprintf-style labels (e.g., "Downloaded %d times"),use positional arguments [42]. For ICU MessageFormat labels(e.g., "{count, plural, one {# file} other {# files}}"), use named arguments ['count' => 42]., default: NULL
:param $languageKey: The language key or null for using the current language from the system, default: NULL
:param $request: the request, default: NULL
:Return description: The value from LOCAL_LANG or null if no translation was found.
1 change: 1 addition & 0 deletions Documentation/CodeSnippets/Config/Api/Events/All.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
include ('EventsExtbase.php'),
include ('EventsExtensionManager.php'),
include ('EventsFilelist.php'),
include ('EventsFluid.php'),
include ('EventsForm.php'),
include ('EventsFrontend.php'),
include ('EventsFrontendLogin.php'),
Expand Down
40 changes: 40 additions & 0 deletions Documentation/CodeSnippets/Config/Api/Events/EventsFluid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php

return [
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\ModifyComponentDefinitionEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/ModifyComponentDefinitionEvent.rst.txt',
'withCode' => false,
],
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\ModifyNamespacesEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/ModifyNamespacesEvent.rst.txt',
'withCode' => false,
],
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\ModifyRenderedContentAreaEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/ModifyRenderedContentAreaEvent.rst.txt',
'withCode' => false,
],
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\ModifyRenderedRecordEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/ModifyRenderedRecordEvent.rst.txt',
'withCode' => false,
],
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\ProvideStaticVariablesToComponentEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/ProvideStaticVariablesToComponentEvent.rst.txt',
'withCode' => false,
],
[
'action' => 'createPhpClassDocs',
'class' => \TYPO3\CMS\Fluid\Event\RenderComponentEvent::class,
'targetFileName' => 'CodeSnippets/Events/Fluid/RenderComponentEvent.rst.txt',
'withCode' => false,
],
];
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
.. Generated by https://github.com/TYPO3-Documentation/t3docs-codesnippets
.. php:namespace:: TYPO3\CMS\Backend\Controller\Event

.. php:class:: BeforeBackendPageRenderEvent

This event triggers before the main backend page has been rendered.
This event triggers before a page has been rendered.

.. php:attr:: view
:readonly:
:public:

.. php:attr:: javaScriptRenderer
:readonly:
:public:

.. php:attr:: pageRenderer
:readonly:
:public:
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,7 @@
{
public function __construct(
protected readonly ComponentFactory $componentFactory,
) {
}
) }

#[AsEventListener]
public function __invoke(ModifyButtonBarEvent $event): void
Expand Down Expand Up @@ -55,3 +54,6 @@

.. php:method:: getButtonBar()
:returns: `\TYPO3\CMS\Backend\Template\Components\ButtonBar`

.. php:method:: getRequest()
:returns: `\Psr\Http\Message\ServerRequestInterface`
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,6 @@

.. php:method:: getPreparedArguments()
:returns: `array`

.. php:method:: getRequest()
:returns: `\Psr\Http\Message\ServerRequestInterface`
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
.. Generated by https://github.com/TYPO3-Documentation/t3docs-codesnippets
.. php:namespace:: TYPO3\CMS\Fluid\Event

.. php:class:: ModifyComponentDefinitionEvent

Event to modify the static definition of a Fluid component before the
definition is written to cache. The definition must not have any
dependencies on runtime information, such as the request.

.. php:method:: getNamespace()
:returns: `string`

.. php:method:: getComponentDefinition()
:returns: `\TYPO3Fluid\Fluid\Core\Component\ComponentDefinition`

.. php:method:: setComponentDefinition(\TYPO3Fluid\Fluid\Core\Component\ComponentDefinition $componentDefinition)

:param $componentDefinition: the componentDefinition
Loading
Loading