Fluid 3.0: Workshop Summary & Important Updates for Users

Categories: Development, Community Created by Claus Due
View down a long table with food in a restaurant. People seated and looking at the camera.
Photo: Claus Due
The Fluid 3.0 workshop has ended and it’s time to summarise what we achieved during the workshop and what to expect from the up-coming 3.0 version of Fluid.

As the new features are completed I will follow up with short, dedicated articles to give developers and users advance knowledge about what to expect when upgrading to Fluid 3.0, plus inspiration for new ways to structure your projects using Fluid.

We had two main topics for the workshop:

  1. Documentation

  2. Development: specifically a reduction and unification of Fluid’s developer and user-facing APIs

First I would like to thank Systime for their longstanding commitment to TYPO3 and for generously offering their space, time, food and all the effort that went into coordinating the workshop! An additional thank you to Unikka for sponsoring a round of pizzas, and to Felix Jacobi for sponsoring coffee for our participants. My company, NamelessCoder, sponsored a restaurant visit, but that’s me saying thank you to participants, not the other way around.

Fluid 3.0 Workshop Recap and Results

Improvement to Fluid Documentation 

  • We chose a strategy to use a landing page and separate Fluid’s documentation into two main parts: the quick “getting started” documentation to boot new users and get them familiar with syntax etc. and the more extensive API documentation for old and new developers who need to extend Fluid with things like custom ViewHelpers

  • We investigated how to improve the XSD files that Fluid generates with ViewHelper documentation to be much more informative and precise about argument types (adding things like PHP class names to the standard set of XSD properties like string, integer, etc.)

  • We also discussed the goal of rendering additional Fluid documentation to XSD files. For example, a manifest of template files and their required arguments

  • We briefly touched on a strategy to document the differences that will be introduced in Fluid 3.0 in a way that makes it easy to consume for anyone migrating. For example, by providing them with an “if you did this before, you need to do this now” type documentation to list the new practices that 1:1 replace old practices.

Improvements to Fluid Development 

  • We prepared to introduce strict types in as many places as possible with the least amount of breaking changes to users. This work also revealed a number of smaller issues with tests in particular and allowed us to improve both code and tests

  • We also refined a solution to replace the use of regular expressions in Fluid. Historically, Fluid has been affected by a couple of issues related to regular expressions and recently a couple of serious problems were detected. The new solution will no longer use regular expressions to do template splitting, instead, a much more linear and platform-independent solution will be implemented. This new solution also facilitates a couple of new features which will be described in more detail later on

  • We discussed possibly viable alternatives to the fairly complex logic Fluid uses to compile templates to PHP classes, which in turn would allow us to simplify ViewHelpers to no longer distinguish between compiled/uncompiled states of execution and in turn reduce the complexity of ViewHelpers’ APIs

  • We then began work on unifying the internal API of Fluid. This work is the precursor to some essential features of Fluid 3.0, for example, parameterized templates and sections. We were not able to finish this part but are continuing with this topic following the workshop

  • We prepared to rename the Fluid composer package to typo3/fluid-engine. More information to follow about this change later on!

After the workshop, I have continued to work on everything that was discussed and planned during the session. This work is now almost concluded and has ended up being a more or less complete rewrite of every part of Fluid from the ground up.

Looking Forward: Fluid 3.0 Deprecations and Best Practices

This means that version 3.0 brings a lot of deprecations, though of course all of the deprecated API now has new and better alternatives. The deprecations and future best practices are:

  • A breaking change to solve parsing issues: This was the most critical, and a breaking change was necessary because the template parser has been completely rewritten. The breaking change affects cases where previously you had to intentionally break the parser’s detection. For example, when writing JS objects you may have needed to do something like <f:format.raw>{</f:format.raw> to escape opening curly braces. Note this specific use now causes a parsing error! This only affects this use case and only when used on the opening curly brace. If you used it around a closing curly braces. there should be no problem at all. The reason is that Fluid’s parser is now sensitive to sequence alone and cannot be intentionally disrupted with enclosing tags. In the future, inline expressions which are not desired to be parsed as Fluid can be escaped by simply adding a backslash in front. For example, writing \{“foo”: “bar”} means the curlies’ content will be taken completely literally as a string

  • Fluid no longer uses caching. The Compiler scope is deleted and compile() methods will no longer be called. No PHP class versions of the template are created and there is only one representation of a template or component (ViewHelper or other) used within a template. This also means there is no cache warmup: new methods may be added to configure Fluid with complete class and file maps to make lookups static, but the impact would be minor.

  • The entire concept of partials, layouts and templates being different is deprecated. This three-way concept is reduced to a single concept: Atoms. The new concept serves the same purpose as partials and layouts.

  • The entire View scope—interfaces, abstract classes, and the TemplatePaths class—have all been deprecated. Fluid 3.0 will no longer impose any decisions whatsoever on how a template is rendered. This entire scope is replaced with a FluidRenderer class that takes a filename as the entry point. Just the file and context, no MVC orientation or anything else. This combined with the Atoms concept completely replaces Fluid’s old template resolving and layout/partial usages.

  • There are no more template pre-processors and the feature itself is removed.

  • ViewHelpers are completely reworked and offer a lot of new abilities. The most important change is the removal of deprecated properties “templateVariableContainer” and “viewHelperVariableContainer” which must now be accessed via the RenderingContext.

  • ViewHelpers’ render() and renderStatic() methods are now considered deprecated. Instead, ViewHelpers may implement the evaluate() method which takes RenderingContext argument. This will be the future best-practice implementation

  • As of 3.0 usage of render() or renderStatic() merely results in execution overhead in terms of both CPU cycles and memory.

  • The base class for ViewHelpers still exists but is now completely optional. It now only provides utility methods and support for old ViewHelper practices like using render(). A ViewHelper can from now on extend AbstractComponent or no base class at all, and then completely change every method of the API

  • InterceptorInterface has been removed. Interception is no longer possible to affect without, for example, implementing it as a ViewHelper. Escaping is now a built-in and default-enabled feature which has to be explicitly disabled through configuration

  • Expressions are no longer separate from ViewHelpers. A ViewHelper can implement a new interface to signal it also works as expression (e.g. math {foo + 1} expressions) and when Fluid parses an expression it simply creates the corresponding ViewHelper instance. This means that the ViewHelper works both as expression and as ViewHelper. Math for example works as {foo + 1} but also as {f:expression.math(a: foo, b: 1, operator: ‘+’)} for more complex use cases

  • Although not exactly a removal or deprecation: escaping quotes in nested inline syntax is no longer necessary at all. Fluid 3.0 ignores such escaping and is therefore compatible, but new templates can be written without regard to quote escaping. The sequence alone matters, i.e. your quote pairs must still match but you can use the same type of quote in all nesting levels

  • There are other deprecations not mentioned here but they all affect API that has never been considered truly public

Substituted Feature Use

Unfortunately, the deprecations and removals have been quite severe on everything except for the most important context: the template file itself. As far as possible the template writing practices have not been changed, but there are some rather important impacts in the form of substituted features which have to be used differently. These are:

  • Atoms is a new concept to replace partials and layouts. An Atom can work both as layout and as partial depending on what it contains and where it is used. Atoms are registered much like ViewHelpers to belong to a namespace, and each namespace then has multiple file system paths where lookups will be done. When an Atom is used within a template that contains nothing but sections, it works like a layout does today. When used somewhere inside a template it works like a partial. A major difference is that an Atom can be created to contain only sections, and when used, this causes the sections to be imported to the current template (and be possible to overwrite by defining new sections with the same name). Practical examples of this new concept will be provided before release. The main point is that f:layout and f:render’s partial argument are both deprecated, as are partialRootPaths and all other template path collections

  • An Atom might, for example, exist in res/atoms/myAtom.html. Registering an Atom namespace “foo” with the path res/atoms/ then means that <foo:myAtom> in Fluid renders or imports the template and sections within, or causes it to work the same way a layout works today. These paths arrays support multiple paths and can be extended the same way “partialRootPaths” and others are extended today

  • Some rarely used toggles like {escaping off} now have to be written as {@escaping off} or they will be ignored. The risk of these actually being used in real-life projects is very low, and you will know immediately if this affects you. The only exception is {namespace xyz=Foo\Bar} which has special handling (deprecated, removed in 4.0). In the future though these must be written as {@namespace xyz=Foo\Bar}

  • Namespace extraction from (X)HTML nodes now only works for <html> tags but other than this, it works precisely as before. If you used a <div xmlns:f=“…”> you will need to change this to <html> instead

The good news is that there is an incredible amount of new syntax features that have been enabled, are fully compatible with old syntax, but provide lots and lots of new ways to declare arrays, get simpler inline syntax, handle vanilla (X)HTML tags with ViewHelper classes and much more.

A demonstration repository will be created well before the 3.0 release which can be cloned and edited to study all of Fluid’s new features.

Release of Fluid 3.0 is currently not scheduled. It is not expected to be used in v10 LTS and will most likely not become a dependency of TYPO3 until v11 development, which follows almost immediately after v10 LTS is released.

I hope you are now well informed and updated of all the positive developments for Fluid 3.0. Watch this space for more articles for Fluid 3.0 users.

You can also check out the recap of the workshop from the documentation team for more information.

Proofreading: Amy Hunt