Navigation Menu

Skip to content

Instantly share code, notes, and snippets.

@NamelessCoder
Created January 10, 2019 11:56
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save NamelessCoder/1f9a91cc237ad816c9147d97abfb4487 to your computer and use it in GitHub Desktop.
Save NamelessCoder/1f9a91cc237ad816c9147d97abfb4487 to your computer and use it in GitHub Desktop.

Idea: Content Types API for TYPO3

This brief aims to outline an idea I had for TYPO3: an API for registering various content types that can then be used by editors. Currently we have a multitude of different ways such content types can be achieved, even with sub-types for plugins and sub-sub-types in the form of Extbase-based plugins.

It would make sense to have a common API for all this.

First part of solution: autoloaded configuration file returning objects

We should declare a convention for a new file, Configuration/ContentTypes.php which can be placed in extensions and will return an array (or collection object?) of content types provided by said extension.

Example:

<?php
defined('TYPO3_MODE') or die('Access denied');

return [
    new StandardContentType('mytype', ...),
    new ExtbasePlugin('myplugin', ...),
];

The idea being that we create (by default immutable) objects that define all the settings a certain type of content requires to drive it - e.g. ExtbasePlugin would require additional "allowed actions" and "uncached actions" parameters in addition to those required by any content type.

The returned objects can then be iterated and persisted. As a first-level compatible solution this iteration and registration could be done simply by extracting the required parameters and calling whichever API we currently have, to make the actual registration of title, icon, fields to show, allowed actions and whatnot.

I would then personally also add a capability for content types that will not be written to caches in any way, e.g. by a second configuration file UncachedContentTypes.php - for "content types from runtime-configured extensions", but in a way that also standard extensions can utilise it.

The ContentType objects' versatility

If we switch to this API that returns a set of objects with a strict interface, it becomes possible to make abstractions on top of this to read content types from basically any type of source. Using Flux as an example, Flux would simply create one or more new types of ContentTypeDefinition interface implementations that extract the required metadata from sources like it does currently.

It also means that we can fully validate things like Extbase plugin registrations even before they are registered and as a full unit before any part of the configuration is written to caches.

At the time of writing this, we might have:

  • StandardContentType which receives the attributes you normally have to register as select option for CType etc. and allows you some way to define TCA's showitem. This would be the preferred thing to use by third parties.
  • StandardPlugin which is a basic list_type implementation that registers through our legacy plugin API.
  • ExtbasePlugin which extends the standard plugin and adds the controller action, vendor identity etc.

Then in addition we may want to provide new types:

  • FluidTemplateContent which is like StandardContentType but results in a FLUIDTEMPLATE TS object and has options for things like template file reference and default variables. Possibly later extended with a PHP-based API to register but not execute DataProcessors (in the longer term solidifying the current DataProcessor's API with proper declarations of all accepted options.

Possible future uses of this strategy

This strategy can equally well be applied to things like:

  • Extension configuration currently stored in ext_conf_template.txt can be given a true PHP API and loaded from such a configuration file.
  • Equally, ext_typoscript_setup.txt could be handled via such a configuration file and instead of returning a TS string, might instead return an array which is then possible to modify based on things like extension settings.
  • Extension updates. It would be almost a no-brainer to drop the ext_update.php pattern in favor of letting extensions return collections of proper PHP object instances each reflecting a certain update (and then let's extend that API to make it more useful than the very manual ext update procedures we have now).
  • Page types (doktype) as PHP API for creating PAGE-level TS setup, with integration for typeNum so it becomes much easier to define things like JSON-exchanging endpoints. Perhaps even load such separately as an Endpoints.php file?
  • Services. Instead of registering authentication etc. services in our ext_localconf.php files, we could return proper PHP instances from a Services.php file.
  • If/when we some lucky day finally get a strict API for all configuration in TYPO3 - extensions to such configuration.
  • In the end, basically anything we currently have to do in ext_localconf.php files.

For your consideration.

@NamelessCoder
Copy link
Author

Small addition: thinking more about the Fluid integration aspects, which also makes sense if we apply it to pages, we could instead create a solution that:

  • Adds a FluidRenderingDefinitionInterface which can return things like template file reference, default paths, default extension
    context, special namespaces, etc. so we encapsulate all Fluid-specific instructions there.
  • Adds a FluidRenderedInterface which can be adopted by ContentTypeDefinitionInterface implements.
  • This interface declares a single method, getRenderingDefinition(): FluidRenderingDefinitionInterface

End result being that any arbitrary type definition can signal that it is rendered by Fluid and can return the metadata that would be
used to render that Fluid (be that as TS FLUIDTEMPLATE object or in custom ways, thinking again of Flux). This would make it very
easy to configure new types of content that render basic Fluid templates without ever having to deal with the TS or TCA aspects.

Lastly: there's also the consideration that having a strict PHP API means we can automatically document every type and every option ;)

@bmack
Copy link

bmack commented Jan 11, 2019

Hey Claus,

very nice read!

Let's split this concept up in various parts.

Part 1: Registration

I am strongly for getting rid of these "let's put everything in ext_localconf.php" concepts we have. The approach of creating custom registration files is like a Service Provider concept, which we could do with PSR-11.

Part 2: Minimizing Efforts in TypoScript

Let's do this. Getting rid of these doktype, typeNum complexity would be useful as well.
We always need to consider that we only want to have something for a specific site and not for the whole TYPO3 instance.

Part 3: ContentType Objects

This is something I'd really love to see: Compressing the definition of the Content Type, the necessary fields / field definitions (currently TCA), the rendering for BE Fields (For FormEngine), the CType selection restriction (pageTS for new content element wizard etc), and the TemplatePath registration / resolving logic (should be discussed separately) and the current TypoScript instructions. I'm curious to see how this could look like in detail (the PHP objects), but this goes into a better "Domain Modelling" direction. I don't even know if we should make a distinction here for Plugins vs. Content Types actually, getting rid of the word "Plugin" completely.

So much for my first thoughts...

THANKS.
Benni.

@NamelessCoder
Copy link
Author

Thanks Benni - sounds like we are thinking about the same direction. I think P1 and P2 are the simpler ones that wouldn't require a complex set of models to operate, and using PSR-11 sounds appropriate.

Regarding P2 and site-specificity for certain content or page types (if we move away from TS there's no page UID context) I do have a suggestion. We have one site configuration per site and we could make it so each site configuration can be associated with ONE extension which can then contain various content types. Even inheritance would be possible: you, as creator of such a "site provider extension" would simply include-and-merge arrays of content types from extensions that the site provider depends on. We could also fit an API on top of reading content types so you can get a list of content types associated with extension key for easier merging. Kind of like how a Fluid ViewHelper overlay would cause additional VH to be available without changing the base set(s), but allowing them to be overridden with overlays.

Regarding P3 I agree, we could take this opportunity to completely clean up content types vs. plugins but that's a far bigger issue since it'd involve removal of the concept of list_type and everything associated with it, which would be hugely breaking.

I would definitely get rid of the "plugin" wording but I don't think we can do that just yet, or that we should do it as part of this API condensation. Might be best to provide an implementation that's immediately deprecated and follow that with a very soft deprecation of everything related to list_type in favor of straight-up CType.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment