Neos 8.0
This release of Neos comes with some great new features, bugfixes and a lot of modernisation of the existing code base.
As usual, we worked hard to keep this release as backwards compatible as possible but, since it’s a major release, some of the changes might require manual adjustments. So please make sure to carefully read the upgrade instructions below.
Neos 8.0 also increases the minimal required PHP version to 8.0.
New Features
!!! FEATURE: Rewrite Fusion Parser
The fusion parser has been rewritten from a single file to an architecture with separate parser and lexer. The architecture is more precise and accessible and will allow to add new features and optimization to fusion in future. The fusion parser tests are generally unchanged, only the removed fusion namespace support required some adjustments.
The existing parser class and interface are unchanged but the inner working is: - The Fusion Parser hands the parsing of fusion files to the ObjectTreeParser which returns not an Array but actual Objects representing the parsed fusion - The Parser then uses the MergedArrayTreeVisitor to traverse the ObjectTree and convert convert it to the Array structure the Fusion Runtime expects. Closures for handling includes and dsl are allow the visitor to resolve those on the go.
About breakiness: - The fusion namespace feature is removed so the new parser only supports fully qualified prototype names - The new parser is a bit stricter as the old parser. However only clearly broken fusion-syntax is rejected. Since the parser adds clear error messages that help to fix such issues.
About Performance: - In Production the Fusion ObjectTreeArray is cached so as this is unchanged the Performance in Production is unchanged. - In Development mode the architecture adds a little to the parsing time for now. However the architecture will eventually allow us to cache the parsed fusion for each fusion file and only parse changed fusion files. This is not part of this pr but a follow up.
Note: The architecture with the old Parser staying in place as a wrapper is an immediate step as is the generation of the old ArrayAst via MergedArrayTreeVisitor. In the end also the runtime should use an object tree directly but this step allowed to adjust the parser separately with high confidence because the testsuite is unchanged. That us also the reason the new ObjectTreeParser is not marked as beeing public api yet.
Related issue: #3593
!!! FEATURE: Remove legacy cache tag support
In Neos 4.1 new Eel helpers were introduced to generate content cache tags in Fusion. Those make sure that the cache tags provided by the integrator are valid. Until Neos 4.0 they needed to be written manually as string which was error prone.
But to support old cache tags that were lacking the workspace context the ContentCacheFlusher
still cleared them.
This change removes that support. So this is breaking and projects need to be adjusted when upgrading and still using those old cache tags.
The advantage of removing them is that the number of cache tags to be flushed during publishing is lower. TODO: Add number.
This change requires `#3631 <https://github.com/neos/neos-development-collection/issues/3631>`_to be merged first.
Removed the legacy cache tag generation.
The change also include a new code migration version 20220318111600
to replace the most commonly used legacy cache tags with matching eel helper calls:
`
node = ${'Node_' + node.identifier}
descendants = ${'DescendantOf_' + node.identifier}
nodeType = 'NodeType_My.Vendor:Content.Foo'
`
!!! FEATURE: Neos.Media: Extend SupportsTaggingInterface by countByTag
Currently classes that implement the SupportsTaggingInterface can only count untagged Assets. When using the interface with external Assets, this leads to the MediaBrowser displaying the count of Neos Media Assets for the external Source, not the count of the Assets matching that Tag in the external source. I extended the SupportsTaggingInterface so that Classes using this interface can change the count of the Tags that are displayed in the Media Browser, just like they can change the count of untagged Assets.
I added the countByTag method to the SupportsTaggingInterface and implemented it in the Neos MediaBrowser where the count happens. Since I am new to Neos I was not sure if countByTags should also pass the active AssetCollection, but I decided against it since the findByTag function also does not pass the active AssetCollection and the count should match the result. This could both be changed. Also, this could throw errors with Packages implementing the Interface.
When implementing the SupportsTaggingInterface the method countByTag must be implemented and will change the count of Assets for every tag displayed in the left sidebar.
FEATURE: Add ParsePartials cache to the fusion parser
The New Fusion Parser now uses a Neos_Fusion_ParsePartials
cache to store the generated FileAst _*_ for each Fusion File. Those File partials are flushed via file monitor when the source Fusion file was changed.
The generated merged array Fusion tree for a Fusion DSL is also cached seperately in this cache.
With this cache layer in place, only changed files are reparsed which speeds up Fusion parsing in Development mode by factor of 2 to 8 depending on context. _**_
The ParsePartials cache is disabled in Production mode as this one already uses the ObjectTreeCache.
since we cache mostly AstNode objects its recommended to have the php extension igbinary
installed.
the cache can be turned of by disabling: Neos.Fusion.enableParsePartialsCache
_*_ there are now more representations of the Fusion code - we created a step in between where we create AstNode Objects see for more infos the PR of the New Fusion Parser: https://github.com/neos/neos-development-collection/pull/3497
_**_ in my tests, when the cached is warmed _***_, performance boost might not be notable on small projects.
_***_ of course is the cache warmed - as always for the statistics ;)
Related issue: #3661
FEATURE: Optimise cache tag generation before flushing content cache after publishing
The generation of cache tags is quite slow for a large number of published changes as many operations are done for each involved node and workspace. I improved the performance by skipping repeated operations on the same node with the same context and by caching the result of nodetype related calculations.
Reuse calculated list of implemented nodetypes for each node changed by introducing a variable to store each calculation
Stop traversal through a nodes parents if one of the parents was already traversed before to generate
DescendantOf
cache tags.Tests still run fine
FEATURE: Implement user impersonation
Extending the Neos with endpoints to impersonate a logged-in user and also restoring the user. For that, the change will add a new controller ImpersonateController for the backend.
Backend Administrators will get the permission to impersonate users, and everybody is able to restore the origin user if the user is authenticated by the impersonation. The change extends the user management module with a button for each user and the user menu in the to bar to be able to restore the user.
The user menu in the content module needs to be adjusted in the neos-ui.
https://user-images.githubusercontent.com/1014126/159288830-23440aea-399b-444a-a0f4-c0f01408977e.mp4
Related issue: #3647
FEATURE: Add external rel attribute to link in ConvertUrisImplementation
closes #3543
I added the posibility of adding ‘rel=”external”’ to external links, when using the ConvertUrisImplementation
Just like the already existing attribute setNoOpener, I added the option setExternal.
I was wondering about making this more open by allowing a string/array to be set here, since rel-attributes can contain a lot of different attributes. But then again, this could be misused.
When using the ConvertUrisImplementation in fusion, the option setExternal can be used to add rel=”external” to a link.
- `
- @class = ‘Neos\Neos\Fusion\ConvertUrisImplementation’
value = ${value} node = ${node} externalLinkTarget = ‘_blank’ resourceLinkTarget = ‘_blank’ absolute = false forceConversion = false setNoOpener = true setExternal = true
Upgrade Instructions
See https://www.neos.io/download-and-extend/upgrade-instructions-7-3-8-0.html
Note
Additionally all changes in Flow 8.0 apply, see the release notes to further information. See https://flowframework.readthedocs.org/en/8.0/TheDefinitiveGuide/PartV/ReleaseNotes/800.html
Potentially breaking changes
Neos 8.0 comes with some breaking changes and removes several deprecated functionalities, be sure to read the following changes and adjust your code respectively. For a full list of changes please refer to the change log.
!!! FEATURE: Rewrite Fusion Parser
The fusion parser has been rewritten from a single file to an architecture with separate parser and lexer. The architecture is more precise and accessible and will allow to add new features and optimization to fusion in future. The fusion parser tests are generally unchanged, only the removed fusion namespace support required some adjustments.
The existing parser class and interface are unchanged but the inner working is: - The Fusion Parser hands the parsing of fusion files to the ObjectTreeParser which returns not an Array but actual Objects representing the parsed fusion - The Parser then uses the MergedArrayTreeVisitor to traverse the ObjectTree and convert convert it to the Array structure the Fusion Runtime expects. Closures for handling includes and dsl are allow the visitor to resolve those on the go.
About breakiness: - The fusion namespace feature is removed so the new parser only supports fully qualified prototype names - The new parser is a bit stricter as the old parser. However only clearly broken fusion-syntax is rejected. Since the parser adds clear error messages that help to fix such issues.
About Performance: - In Production the Fusion ObjectTreeArray is cached so as this is unchanged the Performance in Production is unchanged. - In Development mode the architecture adds a little to the parsing time for now. However the architecture will eventually allow us to cache the parsed fusion for each fusion file and only parse changed fusion files. This is not part of this pr but a follow up.
Note: The architecture with the old Parser staying in place as a wrapper is an immediate step as is the generation of the old ArrayAst via MergedArrayTreeVisitor. In the end also the runtime should use an object tree directly but this step allowed to adjust the parser separately with high confidence because the testsuite is unchanged. That us also the reason the new ObjectTreeParser is not marked as beeing public api yet.
Related issue: #3593
!!! FEATURE: Remove legacy cache tag support
In Neos 4.1 new Eel helpers were introduced to generate content cache tags in Fusion. Those make sure that the cache tags provided by the integrator are valid. Until Neos 4.0 they needed to be written manually as string which was error prone.
But to support old cache tags that were lacking the workspace context the ContentCacheFlusher
still cleared them.
This change removes that support. So this is breaking and projects need to be adjusted when upgrading and still using those old cache tags.
The advantage of removing them is that the number of cache tags to be flushed during publishing is lower. TODO: Add number.
This change requires `#3631 <https://github.com/neos/neos-development-collection/issues/3631>`_to be merged first.
Removed the legacy cache tag generation.
The change also include a new code migration version 20220318111600
to replace the most commonly used legacy cache tags with matching eel helper calls:
`
node = ${'Node_' + node.identifier}
descendants = ${'DescendantOf_' + node.identifier}
nodeType = 'NodeType_My.Vendor:Content.Foo'
`
!!! FEATURE: Neos.Media: Extend SupportsTaggingInterface by countByTag
Currently classes that implement the SupportsTaggingInterface can only count untagged Assets. When using the interface with external Assets, this leads to the MediaBrowser displaying the count of Neos Media Assets for the external Source, not the count of the Assets matching that Tag in the external source. I extended the SupportsTaggingInterface so that Classes using this interface can change the count of the Tags that are displayed in the Media Browser, just like they can change the count of untagged Assets.
I added the countByTag method to the SupportsTaggingInterface and implemented it in the Neos MediaBrowser where the count happens. Since I am new to Neos I was not sure if countByTags should also pass the active AssetCollection, but I decided against it since the findByTag function also does not pass the active AssetCollection and the count should match the result. This could both be changed. Also, this could throw errors with Packages implementing the Interface.
When implementing the SupportsTaggingInterface the method countByTag must be implemented and will change the count of Assets for every tag displayed in the left sidebar.