[TASK] Improve custom CE explanation in FSC
[Packages/TYPO3.CMS.git] / typo3 / sysext / fluid_styled_content / Documentation / AddingYourOwnContentElements / Index.rst
1 .. include:: ../Includes.txt
2
3
4 .. _adding-your-own-content-elements:
5
6 ================================
7 Adding your own content elements
8 ================================
9
10 .. note::
11
12    This part is written for developers!
13
14 A content element can be based on already available fields in the `tt_content` table,
15 or it might be that you need extra fields. This is done the same way as you do for
16 your own extensions, extending TCA. Depending on the data in the `tt_content` table,
17 you can send the data immediately to the Fluid template or use a data processor in
18 front to do some data manipulation. The content elements in the extension "fluid_styled_content"
19 are using both as well. A data processor is sometimes used to convert a string (like
20 the `bodytext` field in content element "table") to an array, so Fluid does not
21 have to deal with this manipulation or transformation.
22
23
24 .. _AddingCE-use-an-extension:
25
26 Use an extension
27 ================
28
29 Advisable is to make your own extension. In our example we've used the extension key
30 `your_extension_key`. If you have plans to publish your extension, do not forget to
31 lookup for the availability of your desired key and register it at the
32 `"extension keys" page <http://typo3.org/extensions/extension-keys/>`_. login in
33 `typo3.org <http://typo3.org//>`_ is required.
34
35 Since this part is written for developers, we will not explain in full detail how an
36 extension works.
37
38 .. _AddingCE-PageTSconfig:
39
40 PageTSconfig
41 ------------
42 First we need to add our new content element to the "New Content Element Wizard" and
43 define its CType. We call it "yourextensionkey_newcontentelement".
44
45 .. code-block:: typoscript
46
47    mod.wizards.newContentElement.wizardItems.common {
48       elements {
49          yourextensionkey_newcontentelement {
50             iconIdentifier = your-icon-identifier
51             title = LLL:EXT:your_extension_key/Resources/Private/Language/Tca.xlf:yourextensionkey_newcontentelement.wizard.title
52             description = LLL:EXT:your_extension_key/Resources/Private/Language/Tca.xlf:yourextensionkey_newcontentelement.wizard.description
53             tt_content_defValues {
54                CType = yourextensionkey_newcontentelement
55             }
56          }
57       }
58       show := addToList(yourextensionkey_newcontentelement)
59    }
60
61
62 .. _AddingCE-TCA-Overrides-tt_content:
63
64 Configuration/TCA/Overrides/tt_content.php
65 ------------------------------------------
66
67 Then we need to add the content element to the "Type" dropdown, where you can select
68 the type of content element:
69
70 .. code-block:: php
71
72    // Adds the content element to the "Type" dropdown
73    \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addPlugin(
74       array(
75          'LLL:EXT:your_extension_key/Resources/Private/Language/Tca.xlf:yourextensionkey_newcontentelement',
76          'yourextensionkey_newcontentelement',
77          'EXT:your_extension_key/Resources/Public/Icons/ContentElements/yourextensionkey_newcontentelement.gif'
78       ),
79       'CType',
80       'your_extension_key'
81    );
82
83 Then we configure the backend fields for our new content element:
84
85 .. code-block:: php
86
87    // Configure the default backend fields for the content element
88    $GLOBALS['TCA']['tt_content']['types']['yourextensionkey_newcontentelement'] = array(
89       'showitem' => '
90          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:general,
91             --palette--;;general,
92             --palette--;;headers,
93             bodytext;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:bodytext_formlabel,
94          --div--;LLL:EXT:frontend/Resources/Private/Language/locallang_ttc.xlf:tabs.appearance,
95             --palette--;;frames,
96             --palette--;;appearanceLinks,
97          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:language,
98             --palette--;;language,
99          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:access,
100             --palette--;;hidden,
101             --palette--;;access,
102          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:categories,
103             categories,
104          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:notes,
105             rowDescription,
106          --div--;LLL:EXT:core/Resources/Private/Language/Form/locallang_tabs.xlf:extended,
107       ',
108       'columnsOverrides' => [
109          'bodytext' => [
110             'config' => [
111                'enableRichtext' => true,
112                'richtextConfiguration' => 'default'
113             ]
114          ]
115       ]
116    );
117
118 .. _AddingCE-TCA-Overrides-sys_template:
119
120 Configuration/TCA/Overrides/sys_template.php
121 --------------------------------------------
122
123 Since we need to use TypoScript as well, we add an entry in the static template list
124 found in sys_templates for static TS:
125
126 .. code-block:: php
127
128    // Add an entry in the static template list found in sys_templates for static TS
129    \TYPO3\CMS\Core\Utility\ExtensionManagementUtility::addStaticFile(
130       'your_extension_key',
131       'Configuration/TypoScript',
132       'Your description'
133    );
134
135
136 .. _AddingCE-setup-txt:
137
138 setup.txt
139 ---------
140
141 As defined in `Configuration/TCA/Overrides/tt_content.php`, this file is in the directory
142 `Configuration/TypoScript` of our own extension.
143
144 To ensure your custom content element templates can be found you need to extend the global
145 :typoscript:`templateRootPaths` with a path within your extension:
146
147 .. code-block:: typoscript
148
149    lib.contentElement {
150       templateRootPaths {
151          200 = EXT:your_extension_key/Resources/Private/Templates/
152       }
153    }
154
155 You can use an arbitrary index (`200` here), just make sure it is unique. If you use partials
156 and layouts, you need to do the same for :typoscript:`partialRootPaths` and :typoscript:`layoutRootPaths`.
157
158 Now you can register the rendering of your custom content element using a Fluid template:
159
160   .. code-block:: typoscript
161
162      tt_content {
163         yourextensionkey_newcontentelement =< lib.contentElement
164         yourextensionkey_newcontentelement {
165            templateName = NewContentElement
166         }
167      }
168
169 In this example a :typoscript:`FLUIDTEMPLATE` content object is created using a copy from
170 :typoscript:`lib.contentElement` with a template identified by the :typoscript:`templateName`
171 `NewContentElement`. This will load a `NewContentElement.html` template file from the
172 :typoscript:`templateRootPaths`.
173
174 .. note::
175
176    The :typoscript:`lib.contentElement` path is defined in
177    :file:`EXT:fluid_styled_content/Configuration/TypoScript/Helper/ContentElement.typoscript`.
178
179 You can use data processors for some data manipulation or other stuff you would like to do
180 before sending everything to the view. This is done in the :typoscript:`dataProcessing` section
181 where you can add an arbitrary number of data processors, each with a fully qualified class name
182 (FQCN) and optional parameters to be used in the data processor:
183
184 .. code-block:: typoscript
185
186    tt_content {
187       yourextensionkey_newcontentelement =< lib.contentElement
188       yourextensionkey_newcontentelement {
189          templateName = NewContentElement
190          dataProcessing {
191             1 = Vendor\YourExtensionKey\DataProcessing\NewContentElementProcessor
192             1 {
193                useHere = theConfigurationOfTheDataProcessor
194             }
195          }
196       }
197    }
198
199
200 .. _AddingCE-Data-Processor:
201
202 Data Processor
203 --------------
204
205 In our :ref:`AddingCE-setup-txt` example above, we put the data processor in the directory
206 :file:`Classes/DataProcessing`. The file :file:`NewContentElementProcessor.php` could
207 look like:
208
209 .. code-block:: php
210
211    <?php
212    namespace Vendor\YourExtensionKey\DataProcessing;
213
214    /*
215     * This file is part of the TYPO3 CMS project.
216     *
217     * It is free software; you can redistribute it and/or modify it under
218     * the terms of the GNU General Public License, either version 2
219     * of the License, or any later version.
220     *
221     * For the full copyright and license information, please read the
222     * LICENSE.txt file that was distributed with this source code.
223     *
224     * The TYPO3 project - inspiring people to share!
225     */
226
227    use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
228    use TYPO3\CMS\Frontend\ContentObject\DataProcessorInterface;
229
230    /**
231     * Class for data processing for the content element "My new content element"
232     */
233    class NewContentElementProcessor implements DataProcessorInterface
234    {
235
236       /**
237        * Process data for the content element "My new content element"
238        *
239        * @param ContentObjectRenderer $cObj The data of the content element or page
240        * @param array $contentObjectConfiguration The configuration of Content Object
241        * @param array $processorConfiguration The configuration of this processor
242        * @param array $processedData Key/value store of processed data (e.g. to be passed to a Fluid View)
243        * @return array the processed data as key/value store
244        */
245       public function process(
246          ContentObjectRenderer $cObj,
247          array $contentObjectConfiguration,
248          array $processorConfiguration,
249          array $processedData
250       )
251       {
252          $processedData['foo'] = 'This variable will be passed to Fluid';
253
254          return $processedData;
255       }
256    }
257
258
259 .. _AddingCE-ext-localconf-php:
260
261 ext\_localconf.php
262 ------------------
263
264 If you want to generate a special preview in the backend "Web > Page" module, you can use
265 a hook for this:
266
267 .. code-block:: php
268
269    // Register for hook to show preview of tt_content element of CType="yourextensionkey_newcontentelement" in page module
270    $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['cms/layout/class.tx_cms_layout.php']['tt_content_drawItem']['yourextensionkey_newcontentelement'] =
271       \Vendor\YourExtensionKey\Hooks\PageLayoutView\NewContentElementPreviewRenderer::class;
272
273
274 .. _AddingCE-Content-Element-Preview-Renderer:
275
276 Content Element Preview Renderer
277 --------------------------------
278
279 The preview renderer :file:`NewContentElementPreviewRenderer.php`, for the backend, has
280 been put in the directory :file:`Classes/Hooks/PageLayoutView` and could look like this:
281
282 .. code-block:: php
283
284    <?php
285    namespace Vendor\YourExtensionKey\Hooks\PageLayoutView;
286
287    /*
288     * This file is part of the TYPO3 CMS project.
289     *
290     * It is free software; you can redistribute it and/or modify it under
291     * the terms of the GNU General Public License, either version 2
292     * of the License, or any later version.
293     *
294     * For the full copyright and license information, please read the
295     * LICENSE.txt file that was distributed with this source code.
296     *
297     * The TYPO3 project - inspiring people to share!
298     */
299
300    use \TYPO3\CMS\Backend\View\PageLayoutViewDrawItemHookInterface;
301    use \TYPO3\CMS\Backend\View\PageLayoutView;
302
303    /**
304     * Contains a preview rendering for the page module of CType="yourextensionkey_newcontentelement"
305     */
306    class NewContentElementPreviewRenderer implements PageLayoutViewDrawItemHookInterface
307    {
308
309       /**
310        * Preprocesses the preview rendering of a content element of type "My new content element"
311        *
312        * @param \TYPO3\CMS\Backend\View\PageLayoutView $parentObject Calling parent object
313        * @param bool $drawItem Whether to draw the item using the default functionality
314        * @param string $headerContent Header content
315        * @param string $itemContent Item content
316        * @param array $row Record row of tt_content
317        *
318        * @return void
319        */
320       public function preProcess(
321          PageLayoutView &$parentObject,
322          &$drawItem,
323          &$headerContent,
324          &$itemContent,
325          array &$row
326       )
327       {
328          if ($row['CType'] === 'yourextensionkey_newcontentelement') {
329             $itemContent .= '<p>We can change our preview here!</p>';
330
331             $drawItem = false;
332          }
333       }
334    }
335
336
337 .. _AddingCE-fluid-templates:
338
339 Fluid templates
340 ---------------
341
342 For the final rendering you need a Fluid template. This template will be located at the
343 directory and file name which you have entered in :ref:`AddingCE-setup-txt` using the parameter
344 `templateName`.
345
346 Just to show the variable foo, like we defined at :ref:`AddingCE-data-processor`,
347 we can use the following markup:
348
349 .. code-block:: html
350
351    <h1>{foo}</h1>
352