Skip to content
Snippets Groups Projects
Commit c22b72cd authored by Christian Kuhn's avatar Christian Kuhn
Browse files

[FEATURE] Implement and use a core ViewFactoryInterface

After a long list of preparation and side patches, this
change introduces a central ext:core ViewFactoryInterface
plus a default implementation for fluid, and rolls it out.

We established a sub section of a generic view for backend
modules with ext:backend BackendViewFactory in TYPO3 v12
already. This worked out well. The patch picks this up
with a global factory interface for all other use
cases that need to deal with views.

This ultimately allows instances to change any view rendered
by any component by configuring the instance to inject a
different ViewFactoryInterface implementation to some
controller and let it return an ext:core ViewInterface that
uses some different view implemenation like Twig or whatever
floats your boat. This is also very helpful for headless
implementations to transparently substitute casual html
rendering with for instance a json result.

The patch decouples fluid much better and obsoletes the custom
fluid view implementations ext:fluid StandaloneView, ext:fluid
TemplateView and their abstract ext:fluid AbstractTemplateView.
The previous ViewResolverInterface of extbase is obsoleted as
well.

The following architectural decisions have been taken:

* ext:core ViewFactoryInterface has the single create() method
  that takes a ViewFactoryData data object to create an ext:core
  ViewInterface based on it.
* ext:core ViewFactoryInterface should be *injected* whenever
  possible to allow instances reconfiguring the injection. Core
  has only a couple of places where this is not possible yet due
  to technical debt. An example is #104724.
* The default injection of ViewFactoryInterface is ext:core
  FluidViewFactory. This returns an instance of the already
  established FluidViewAdapter, which acts as a facade to
  fluid standalone TemplateView. FluidViewAdapter implements
  all the specialities from the now deprecated custom ext:fluid
  view classes, so switching to this implementation within core
  is not considered breaking. Most of those compatibility
  methods are declared deprecated, though. Some are kept
  non-deprecated, due to technical debt in some consumers.
* ext:core ViewFactoryData is a straight data object that is
  supposed to be set up by view consumers. It is about handing
  over the template paths entry points to the factory, requesting
  a preferred format if desired, and handing over PSR-7 request
  if possible.
* The request is actively hand over in ViewFactoryData whenever
  possible within core usages, since it may help custom
  ViewFactoryInterface implementations to take decisions based on
  it: "If that's a ext:news controller action and if request type
  is json, then create my json view, otherwise fall back to default
  fluid view using FluidViewFactory".
* The signature of ext:core ViewFactoryData is still kinda
  tailored towards fluid with the almighty template/layout/partial
  tuple, but it allows the core to go ahead in this area with TYPO3
  v14, to potentially establish a better solution regarding
  template entry points in general.
* Best use of the ViewFactoryData paths entry points tuple are the
  "extension template entry points", namely arrays of
  "EXT:myExt/Resources/Private/Templates",
  "EXT:myExt/Resources/Private/Layouts" and
  "EXT:myExt/Resources/Private/Partials".
  Only ext:form violates this once, which should be ruled out.
* Single view rendering is best called using
  render('path/within/templateRootPath'): This has been established
  with BackendViewFactory for backend modules already, and gives
  the core a good place to kick in automatic path overlay
  handling later. Only extbase and TEMPLATEVIEW violate this at the
  moment, and we will see on how to continue on this.
* In ViewFactoryData, "templatePathAndFilename" is the ugly kid
  in the block, we'll want to get rid of this when a general
  path lookup and overlay solution is established.

The patch essentially adds the ViewFactoryInterface API, adds
the default FluidViewFactory implementation, and changes all
places that instantiated custom fluid view towards the new API.

Notable specialities:

* ext:adminpanel suffers from an architectual flaw that cripples
  DI on sub modules. GU::makeInstance(ViewFactoryInterface::class)
  solves this for now, but a solution should be handled with
  #104724 to allow injection of ViewFactoryInterface.
* ext:backend LoginController follows a weird logic for extensions
  that take over login rendering to have own login fields. This
  needs a bigger overhaul that is out of scope of this patch.
  Since the existing API hard coded type hints for ext:fluid
  StandaloneView, there is currently no other way than mitigating
  this by introducing a new API method and triggering deprecations
  for extension that don't follow.
* The patch reveals architecural flaws when creating emails via the
  FluidEmail construct where 'composition over inheritance' went
  wrong. This needs a redesign, the implementation is currently
  bound to fluid and throws an exception if the view is not an
  instance of FluidViewAdapter
* Similar with FLUIDTEMPLATE content object: This implementation is
  heavily tailored towards fluid. This is ok'ish: When for instance
  a page rendering for 'headless' is called, those FLUIDTEMPLATE
  TypoScript definitions need to be changed to something else using
  TypoScript. The implementation now throws an exception if the view
  factory did not return a FluidViewAdapter view.
* New v13 PAGEVIEW content object is changed to *not* relax on
  upper/lowercase template filenames for now: While we *do* want
  fluid to handle file and path casings more relaxed, this single
  use case is not the way to go. This needs to be solved on a more
  general level that requires more refactoring, find, and lookup
  magic on a lower level. To stay consistent with current fluid
  strategy, we for now remove the "ignore casing" feature of this
  content object, but it will hopefully see a revamp in v14.
* extbase is (guess what?) problematic. The patch switches from
  ext:extbase ViewResolverInterface to ext:core ViewFactoryInterface
  and keeps using ViewResolverInterface as deprecated fallback.
  The extbase abstract ActionController "defaultViewObjectName"
  API is ugly, is a bit more restricted now, and will have to fall
  at some point. In v14, single actions should probably create a
  view explicitely when they need some, using a helper method
  provided by the abstract, or similar. The automagic view
  configuration is of course kept for now, but becomes more and
  more questionable.

Resolves: #104773
Related: #101559
Related: #104724
Related: #103504
Releases: main
Change-Id: Ic4603b55da1504a5f20b23468850a1a518684967
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/85735


Reviewed-by: default avatarBenni Mack <benni@typo3.org>
Tested-by: default avatarcore-ci <typo3@b13.com>
Tested-by: default avatarBenni Mack <benni@typo3.org>
Tested-by: default avatarSimon Praetorius <simon@praetorius.me>
Tested-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Tested-by: default avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: default avatarStefan Bürk <stefan@buerk.tech>
Reviewed-by: default avatarSimon Praetorius <simon@praetorius.me>
Reviewed-by: default avatarAnja Leichsenring <aleichsenring@ab-softlab.de>
Reviewed-by: default avatarChristian Kuhn <lolli@schwarzbu.ch>
Tested-by: default avatarGarvin Hicking <gh@faktor-e.de>
Reviewed-by: default avatarGarvin Hicking <gh@faktor-e.de>
Tested-by: default avatarChristian Kuhn <lolli@schwarzbu.ch>
parent c2d7bdff
No related merge requests found
Showing
with 308 additions and 149 deletions
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment