TYPO3 extension Flux: Dynamic Fluid FlexForms
Flux automates integration of Fluid with TYPO3 and makes Fluid the entry point for developers. The name "Flux" has multiple meanings but in this context, it mainly refers to the gel-like fluid used when soldering components together in electronic hardware, making it easier to create a bond between components and improves the durability of the bond.
Flux has two main purposes:
Bonus feature: nested content areas to create content grids.
Flux has two main modes of operation - either you allow Flux to automatically create a site-wide "design" folder to contain your template files, which provides a 100% out of the box experience. Or you prefer to have a more advanced and controlled integration, in which case you disable the automatic creation of site-wide template folders and provide your own (through an extension).
The automatic mode of operation is the default. This means Flux is an ideal starting point if you have zero knowledge about how to set up TYPO3. You can start with the automation and as you learn more about TYPO3, you can refine your integration and continuously improve how it works. Or keep using the automation in case it fits all your needs.
To get started you only need to know how to install a TYPO3 extension either with Composer or for non-Composer sites, using the Extension Manager.
Flux has multiple ways to store your page- and content templates (which are also type definitions):
Methods 1 and 3 are intended to get you started as quickly as possible. Method 2 is intended to serve more custom setups which ship more than just site templates, through use of a custom TYPO3 extension.
All three methods can be combined or used individually.
Recommended!
composer req fluidtypo3/flux
./vendor/bin/typo3 extension:install flux
# alternatively, instead of extension:install, activate in Extension Manager backend module
NOT recommended!
flux
flux
fluid_styled_content
to be able to render any content at all).Page Layout
when editing a page (start with the top page).Columns from selected "Page Layout"
as the
value of the two Backend Layout
fields in the Appearance
tab.The remaining setup of labels, form fields, grid composition etc. can all be done from within your Fluid templates.
When Flux is installed and enabled in extension manager, and if automatic creation of site-wide Flux templates is enabled (which it is by default), the following happens automatically:
design
is created in the public directory (this directory may differ between TYPO3 versions and can
be changed with configuration, but in most recent TYPO3 versions it is public
in the project public folder).design/Templates/Page
can be selected as page template (Flux adds a Page Layout
tab to pages'
editable properties).design/Templates/Content
becomes a custom content type which can be inserted just like the
standard TYPO3 content types that create text, image, etc.Renaming, removing or adding files in these folders automatically registers the file as either page template or content type, depending on location. Be careful when renaming or removing files: if the page- or content template is already in use this may break your system until you choose another page template and disable/delete removed or renamed content types. There is no warning given about types that are in use!
From that point on, you can create a completely styled site with custom content types to make sliders etc. using your favorite frontend framework (or none) - and you only need to know very basic Fluid (an XML based markup engine which comes with automatically rendered documentation for every tag you can use).
Flux does not remove the need to learn "the TYPO3 way" of doing things - you should still aim to learn more about how
TYPO3 works. Flux only makes it quicker to get started and provides a reasonable level of automation; complex sites will
almost surely still require you to learn a bit about TYPO3 (such as, how to modify the <meta>
section and how to use
third party plugins for news etc.)
Flux is also not a replacement for things like fluid_styled_content
(although it can work without it) - Flux creates
custom content types, it does not replace TYPO3's native content types (although you can hide those and use only your
custom types).
Lastly, Flux only has limited abstraction over how you define form fields. To know all the specific details of what each type of field does, you still need to know TYPO3's "TCA" (which is thoroughly documented). Flux tries as far as possible to use the same names of form field attributes as TCA. If you don't understand an attribute or aren't sure which field type to use, always consult the TCA documentation (keeping in mind not all field types will work: Flux fields are based on FlexForm fields. When FlexForm does not support a field type it is noted so in the TCA documentation).
VHS is another extension in the FluidTYPO3 family, which is highly recommended to use along with Flux. The reason VHS is mentioned here, is that it provides alternatives to TypoScript-based content- and menu-rendering instructions, allowing you to instead use Fluid.
Given that in particular menu rendering setup in TypoScript is notoriously difficult (due to a very old structure which has basically never changed), beginners may prefer to use a special XHTML tag and either a few CSS class properties, or a custom loop to output menu items and their links.
Flux lets you build and modify forms in Fluid, which become form fields in the form that edits content/page properties through the TYPO3 backend:
<flux:form id="myform">
<flux:field.input name="myField" label="My special field" />
</flux:form>
Flux also lets you build a grid for content elements (nested content areas):
<flux:grid>
<flux:grid.row>
<flux:grid.column colPos="0" name="main" label="Main content area" />
</flux:grid.row>
</flux:form>
Flux is then capable of extracting these embedded structures to read form fields, labels, content grids, backend preview output, and more - in short, your template files embed the instructions on how to both integrate and render templates.
As you create more complex projects they usually have more complex requirements - which may still benefit from Flux features such as a way to create Flux forms for custom plugins. Since Flux works by increasingly abstracting the API of TYPO3 core features (with the Fluid "flavor" as the most condensed and abstracted) Flux also declares these increasingly flexible layers of abstraction as public API.
This means Flux also has a good old PHP way to declare forms and so on:
$form = \FluidTYPO3\Flux\Form::create();
$form->setName('myform');
$form->createField('Input', 'myField', 'My special field');
And supports plain arrays (to allow sources like JSON):
$json = '{name: "myform", fields: [{"name": "myField", "type": "Input"}]}';
$asArray = json_decode($json, JSON_OBJECT_AS_ARRAY);
$form = \FluidTYPO3\Flux\Form::create($asArray);
And can use TypoScript:
plugin.tx_flux.providers {
myextension_myplugin {
tableName = tt_content
fieldName = pi_flexform
listType = myextension_myplugin
extensionKey = Vendor.MyPlugin
form {
name = myform
fields {
myField {
type = Input
label = My special field
}
}
}
}
}
All of which create the same form with a single input field called myField
with a label value of My special field
. The last
example shows the form
structure nested in a Provider (another Flux concept) which connects the pi_flexform
field of the
related tt_content
plugin record type to the form.
backend_layout
approach) to any content/plugin.php.ini
configuration setting to think about is
max_input_vars
. If this number is too small then the TYPO3 Backend (being PHP) will decline the submission of the
backend editing form and will exit with an "Invalid CSRF Token" message because of incomplete (truncated) POST
data.public: true
in Service
config of your extension. And 2) if the Provider needs to be used for more than one specific page/content/record type,
make sure you also declare the Provider as shared: false
. You can find an example of such configuration in the
Configuration/Services.yaml
file in Flux.public: true
in Service
config of your extension.__construct
method, make sure that they take the same arguments as the parent class and
that you call parent::__construct()
with those arguments from your overridden __construct
method.