Skip to content

Commit

Permalink
[DOCS] Improve chapter for adding content elements
Browse files Browse the repository at this point in the history
- Simplify wording
- Add one more example for Data Processor use case
- Add crosslink to icon registry and data processor
- Enable cross references in Settings.cfg
- Re-structure tutorial
- Use logical blocks instead of file blocks for less experienced
  developers.
- Use step syntax instead of plain headlines
- Include rst format class for proper rendering of numbered lists
- Use numbered headlines with shortlinks
- Unify writing style to address the reader

Resolves: #89479
Releases: master
Change-Id: Idb2de9e78f0b128efc73e32283d45e74e0c818d8
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/62049
Tested-by: Sybille Peters <sypets@gmx.de>
Tested-by: Jörg Bösche <typo3@joergboesche.de>
Tested-by: TYPO3com <noreply@typo3.com>
Tested-by: Daniel Goerz <daniel.goerz@posteo.de>
Reviewed-by: Sybille Peters <sypets@gmx.de>
Reviewed-by: Jörg Bösche <typo3@joergboesche.de>
Reviewed-by: Daniel Goerz <daniel.goerz@posteo.de>
  • Loading branch information
typecat authored and ervaude committed Oct 24, 2019
1 parent 362affb commit 738518a
Show file tree
Hide file tree
Showing 2 changed files with 133 additions and 127 deletions.
Expand Up @@ -11,36 +11,41 @@ Adding your own content elements

This part is written for developers!

A content element can be based on already available fields in the `tt_content` table,
or it might be that you need extra fields. This is done the same way as you do for
your own extensions, extending TCA. Depending on the data in the `tt_content` table,
you can send the data immediately to the Fluid template or use a data processor in
A content element can be based on already available fields in the `tt_content` table
and/or extra fields you can add to the `tt_content` table. This is done the same way as you do for
your own extensions by extending TCA. Depending on the data in the `tt_content` table,
you can send the data immediately to the Fluid template or use a
:ref:`data processor <t3tsref:cobj-fluidtemplate-properties-dataprocessing>` in
front to do some data manipulation. The content elements in the extension "fluid_styled_content"
are using both as well. A data processor is sometimes used to convert a string (like
the `bodytext` field in content element "table") to an array, so Fluid does not
have to deal with this manipulation or transformation.
the `bodytext` field in content element "table") to an array or fetch a related record
(e.g. a FAL file), so Fluid does not have to deal with this manipulation or transformation.


.. _AddingCE-use-an-extension:

Use an extension
================

Advisable is to make your own extension. In our example we've used the extension key
We recommend to create your own extension for adding content objects.
The following example uses the extension key
`your_extension_key`. If you have plans to publish your extension, do not forget to
lookup for the availability of your desired key and register it at the
`"extension keys" page <http://typo3.org/extensions/extension-keys/>`_. login in
`typo3.org <http://typo3.org//>`_ is required.
check for the availability of your desired key and register it at the
`"extension keys" page <http://typo3.org/extensions/extension-keys/>`_ (login for
`typo3.org <http://typo3.org//>`_ is required).

Since this part is written for developers, we will not explain in full detail how an
Since this part is written for developers, it will not explain in full detail how an
extension works.

.. _AddingCE-PageTSconfig:
.. _RegisterCE:
.. _AddingCE-TCA-Overrides-tt_content:

1. Register the content element
===============================

PageTSconfig
------------
First we need to add our new content element to the "New Content Element Wizard" and
define its CType. We call it "yourextensionkey_newcontentelement".
First add your new content element to the "New Content Element Wizard" and define its CType in `PageTSconfig`.
The example content element is called "yourextensionkey_newcontentelement":

.. code-block:: typoscript
Expand All @@ -58,14 +63,10 @@ define its CType. We call it "yourextensionkey_newcontentelement".
show := addToList(yourextensionkey_newcontentelement)
}
You need to :ref:`register the icon identifier <t3coreapi:icon-registration>` with the icon API in your :file:`ext_localconf.php`.

.. _AddingCE-TCA-Overrides-tt_content:

Configuration/TCA/Overrides/tt_content.php
------------------------------------------

Then we need to add the content element to the "Type" dropdown, where you can select
the type of content element:
Then you need to add the content element to the "Type" dropdown, where you can select
the type of content element in the file :file:`Configuration/TCA/Overrides/tt_content.php`:

.. code-block:: php
Expand All @@ -80,7 +81,13 @@ the type of content element:
'your_extension_key'
);
Then we configure the backend fields for our new content element:
.. _ConfigureCE-Fields:

2. Configure fields
===================

Then you need to configure the backend fields for your new content element in the file
:file:`Configuration/TCA/Overrides/tt_content.php`:

.. code-block:: php
Expand Down Expand Up @@ -115,13 +122,13 @@ Then we configure the backend fields for our new content element:
]
);
.. _AddingCE-TCA-Overrides-sys_template:
.. _ConfigureCE-Frontend:

Configuration/TCA/Overrides/sys_template.php
--------------------------------------------
3. Configure the frontend template
==================================

Since we need to use TypoScript as well, we add an entry in the static template list
found in sys_templates for static TS:
Since TypoScript configuration is needed as well, add an entry in the static template list
found in sys_templates for static TypoScript in :file:`Configuration/TCA/Overrides/sys_template.php`:

.. code-block:: php
Expand All @@ -132,14 +139,8 @@ found in sys_templates for static TS:
'Your description'
);
.. _AddingCE-setup-txt:

setup.txt
---------

As defined in `Configuration/TCA/Overrides/tt_content.php`, this file is in the directory
`Configuration/TypoScript` of our own extension.
As defined in :file:`Configuration/TCA/Overrides/tt_content.php`, the file :file:`setup.typoscript` is in the directory
:file:`Configuration/TypoScript` of your own extension.

To ensure your custom content element templates can be found you need to extend the global
:typoscript:`templateRootPaths` with a path within your extension:
Expand Down Expand Up @@ -176,40 +177,39 @@ In this example a :typoscript:`FLUIDTEMPLATE` content object is created using a
The :typoscript:`lib.contentElement` path is defined in
:file:`EXT:fluid_styled_content/Configuration/TypoScript/Helper/ContentElement.typoscript`.

You can use data processors for some data manipulation or other stuff you would like to do
before sending everything to the view. This is done in the :typoscript:`dataProcessing` section
where you can add an arbitrary number of data processors, each with a fully qualified class name
(FQCN) and optional parameters to be used in the data processor:

.. code-block:: typoscript
For the final rendering you need a Fluid template. This template will be located at the
directory and file name which you have entered in :file:`setup.typoscript` using the parameter
`templateName`. Now we can use the `tt_content` fields in the Fluid template by accessing them
via the `data` variable. The following example shows the text entered in the richtext enabled
field `bodytext` formatted unsing the defined richtext configuration:

tt_content {
yourextensionkey_newcontentelement =< lib.contentElement
yourextensionkey_newcontentelement {
templateName = NewContentElement
dataProcessing {
1 = Vendor\YourExtensionKey\DataProcessing\NewContentElementProcessor
1 {
useHere = theConfigurationOfTheDataProcessor
}
}
}
}
.. code-block:: html

<div>{data.bodytext -> f:format.html()}</div>

.. _AddingCE-Data-Processor:

Data Processor
--------------
.. _ConfigureCE-Preview:

In our :ref:`AddingCE-setup-txt` example above, we put the data processor in the directory
:file:`Classes/DataProcessing`. The file :file:`NewContentElementProcessor.php` could
look like:
4. Optional: configure custom backend preview
=============================================

If you want to generate a special preview in the backend "Web > Page" module, you can use
a hook for this:

.. code-block:: php
// Register for hook to show preview of tt_content element of CType="yourextensionkey_newcontentelement" in page module
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['yourextensionkey_newcontentelement'] =
\Vendor\YourExtensionKey\Hooks\PageLayoutView\NewContentElementPreviewRenderer::class;
The preview renderer :file:`NewContentElementPreviewRenderer.php`, for the backend, has
been put in the directory :file:`Classes/Hooks/PageLayoutView` and could look like this:

.. code-block:: php
<?php
namespace Vendor\YourExtensionKey\DataProcessing;
namespace Vendor\YourExtensionKey\Hooks\PageLayoutView;
/*
* This file is part of the TYPO3 CMS project.
Expand All @@ -224,65 +224,85 @@ look like:
* The TYPO3 project - inspiring people to share!
*/
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
use \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
use \TYPO3\CMS\Backend\View\PageLayoutView;
/**
* Class for data processing for the content element "My new content element"
* Contains a preview rendering for the page module of CType="yourextensionkey_newcontentelement"
*/
class NewContentElementProcessor implements DataProcessorInterface
class NewContentElementPreviewRenderer implements PageLayoutViewDrawItemHookInterface
{
/**
* Process data for the content element "My new content element"
* Preprocesses the preview rendering of a content element of type "My new content element"
*
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processorConfiguration The configuration of this processor
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionality
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
*
* @return void
*/
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
public function preProcess(
PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
)
{
$processedData['foo'] = 'This variable will be passed to Fluid';
if ($row['CType'] === 'yourextensionkey_newcontentelement') {
$itemContent .= '<p>We can change our preview here!</p>';
return $processedData;
$drawItem = false;
}
}
}
.. _ConfigureCE-Extend-tt_content:

.. _AddingCE-ext-localconf-php:
5. Optional: extend tt_content
==============================

ext\_localconf.php
------------------
.. todo:
If you want to generate a special preview in the backend "Web > Page" module, you can use
a hook for this:
This will be filled in another patch.
.. code-block:: php
.. _ConfigureCE-DataProcessors:

// Register for hook to show preview of tt_content element of CType="yourextensionkey_newcontentelement" in page module
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['yourextensionkey_newcontentelement'] =
\Vendor\YourExtensionKey\Hooks\PageLayoutView\NewContentElementPreviewRenderer::class;
6. Optional: use data processors
================================

You can use data processors for some data manipulation or other actions you would like to perform
before passing everything to the view. This is done in the :typoscript:`dataProcessing` section
where you can add an arbitrary number of data processors, each with a fully qualified class name
(FQCN) and optional parameters to be used in the data processor:

.. _AddingCE-Content-Element-Preview-Renderer:
.. code-block:: typoscript
Content Element Preview Renderer
--------------------------------
tt_content {
yourextensionkey_newcontentelement =< lib.contentElement
yourextensionkey_newcontentelement {
templateName = NewContentElement
dataProcessing {
1 = Vendor\YourExtensionKey\DataProcessing\NewContentElementProcessor
1 {
useHere = theConfigurationOfTheDataProcessor
}
}
}
}
The preview renderer :file:`NewContentElementPreviewRenderer.php`, for the backend, has
been put in the directory :file:`Classes/Hooks/PageLayoutView` and could look like this:
In the example :file:`setup.typoscript` above, the data processor is located in the directory
:file:`Classes/DataProcessing`. The file :file:`NewContentElementProcessor.php` could
look like this:

.. code-block:: php
<?php
namespace Vendor\YourExtensionKey\Hooks\PageLayoutView;
declare(strict_types = 1);
namespace Vendor\YourExtensionKey\DataProcessing;
/*
* This file is part of the TYPO3 CMS project.
Expand All @@ -297,54 +317,40 @@ been put in the directory :file:`Classes/Hooks/PageLayoutView` and could look li
* The TYPO3 project - inspiring people to share!
*/
use \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
use \TYPO3\CMS\Backend\View\PageLayoutView;
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
/**
* Contains a preview rendering for the page module of CType="yourextensionkey_newcontentelement"
* Class for data processing for the content element "My new content element"
*/
class NewContentElementPreviewRenderer implements PageLayoutViewDrawItemHookInterface
class NewContentElementProcessor implements DataProcessorInterface
{
/**
* Preprocesses the preview rendering of a content element of type "My new content element"
*
* @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
* @param bool $drawItem Whether to draw the item using the default functionality
* @param string $headerContent Header content
* @param string $itemContent Item content
* @param array $row Record row of tt_content
* Process data for the content element "My new content element"
*
* @return void
* @param ContentObjectRenderer $cObj The data of the content element or page
* @param array $contentObjectConfiguration The configuration of Content Object
* @param array $processorConfiguration The configuration of this processor
* @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
* @return array the processed data as key/value store
*/
public function preProcess(
PageLayoutView &$parentObject,
&$drawItem,
&$headerContent,
&$itemContent,
array &$row
public function process(
ContentObjectRenderer $cObj,
array $contentObjectConfiguration,
array $processorConfiguration,
array $processedData
)
{
if ($row['CType'] === 'yourextensionkey_newcontentelement') {
$itemContent .= '<p>We can change our preview here!</p>';
$processedData['foo'] = 'This variable will be passed to Fluid';
$drawItem = false;
}
return $processedData;
}
}
.. _AddingCE-fluid-templates:

Fluid templates
---------------

For the final rendering you need a Fluid template. This template will be located at the
directory and file name which you have entered in :ref:`AddingCE-setup-txt` using the parameter
`templateName`.

Just to show the variable foo, like we defined at :ref:`AddingCE-data-processor`,
we can use the following markup:
Just to show the variable foo, like defined in :ref:`ConfigureCE-Data-Processor`,
you can use the following markup:

.. code-block:: html

Expand Down
4 changes: 2 additions & 2 deletions typo3/sysext/fluid_styled_content/Documentation/Settings.cfg
Expand Up @@ -38,7 +38,7 @@ use_opensearch =
# t3api = https://typo3.org/api/typo3cms/
# t3cgl = https://docs.typo3.org/typo3cms/CodingGuidelinesReference/
# t3coreapi = https://docs.typo3.org/typo3cms/CoreApiReference/
t3coreapi = https://docs.typo3.org/m/typo3/reference-coreapi/master/en-us/
# t3editors = https://docs.typo3.org/typo3cms/EditorsTutorial/
# t3extbasebook = https://docs.typo3.org/typo3cms/ExtbaseFluidBook/
# t3fal = https://docs.typo3.org/typo3cms/FileAbstractionLayerReference/
Expand All @@ -53,5 +53,5 @@ use_opensearch =
# t3templating = https://docs.typo3.org/typo3cms/TemplatingTutorial/
# t3ts45 = https://docs.typo3.org/typo3cms/TyposcriptIn45MinutesTutorial/
# t3tsconfig = https://docs.typo3.org/typo3cms/TSconfigReference/
# t3tsref = https://docs.typo3.org/typo3cms/TyposcriptReference/
t3tsref = https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/
# t3tssyntax = https://docs.typo3.org/typo3cms/TyposcriptSyntaxReference/

0 comments on commit 738518a

Please sign in to comment.