1.. include:: ../Includes.txt
2
3
4.. _config-concepts:
5
6======================
7Configuration Concepts
8======================
9
10
11Configuration Overview
12======================
13
14The main principles of configuring a Rich Text Editor in TYPO3
15apply to editing with any Rich Text Editor (`rte_ckeditor`, ...).
16
17Some of the functionality (for example the RTE transformations) is
18embedded in the TYPO3 core and not specific to `rte_ckeditor`.
19
20There are three main parts relevant for rich text editing with TYPO3:
21
22#. **Editor configuration:** This covers how the actual editor (in this case CKEditor)
23   should behave, what buttons should be shown, what options are available.
24#. **RTE transformations:** This defines how the information is processed when saved
25   from the Rich Text Editor to the database and when loaded from the database into
26   the Rich Text Editor
27#. **Frontend output configuration**: The information fetched from the database may need to
28   be processed for the frontend. The configuration of the
29   frontend output is configured via TypoScript.
30
31.. todo: diagram: overview with DB <-> RTE, DB -> FE etc.
32
33This section mainly covers editor configuration and RTE transformations, as for
34TypoScript the TypoScript reference handles output of HTML content and
35has everything preset (see :ref:`t3tsref:parsefunc`).
36
37
38.. tip::
39
40   Before you start, have a look at the :ref:`config-best-practices`.
41
42
43.. _config-editor:
44
45Editor Configuration
46====================
47
48Yaml
49----
50
51For TYPO3 v8 the ability to configure editor-related configuration and transformations
52via Yaml (Yet-Another-Markup-Language) was made available and is usable for both CKEditor
53and HtmlArea, although for the latter it is recommended to use the existing configuration
54when having special setups.
55
56.. todo: add link to general information about configuration with Yaml, once available
57
58Yaml Basics
59~~~~~~~~~~~
60
61* Yaml is case sensitive
62* Indenting level reflects hierarchy level and indenting must be used consistently
63  (indent with 2 spaces in `rte_ckeditor` configuration).
64* Comments begin with a `#`.
65* White space is important, use a space after `:`.
66
67This is a dictionary (associative array):
68
69.. code-block:: yaml
70
71   key1: value
72   key2: value
73
74A dictionary can be nested, for example:
75
76.. code-block:: yaml
77
78   key1:
79     key1-2: value
80
81This is a list:
82
83.. code-block:: yaml
84
85   - list item 1
86   - list item 2
87
88A dictionary can be combined with a list:
89
90.. code-block:: yaml
91
92   key:
93     key2:
94       - item 1
95       - item 2
96
97
98.. configuration-presets:
99
100Configuration Presets
101---------------------
102
103Presets are the heart of having custom configuration per record type, or
104page area. A preset consists of a name and a reference to the location
105of a Yaml file.
106
107TYPO3 ships with three RTE presets, “default”, “minimal” and “full”. The
108"default" configuration is active by default.
109
110It is possible for extensions to ship their own preset like “news”, or “site_xyz”.
111
112Registration of a preset happens within :file:`LocalConfiguration.php`,
113:file:`AdditionalConfiguration.php` or within
114:file:`ext_localconf.php` of an extension:
115
116.. code-block:: php
117
118   $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['default'] = 'EXT:rte_ckeditor/Configuration/RTE/Default.yaml';
119
120This way, it is possible to override the default preset, for example by using
121the configuration defined in a custom extension:
122
123.. code-block:: php
124
125   $GLOBALS['TYPO3_CONF_VARS']['RTE']['Presets']['default'] = 'EXT:my_extension/Configuration/RTE/Default.yaml';
126
127
128TYPO3 uses the “default” preset for all Rich-Text-Element fields. To use
129a different preset throughout an installation or a branch of the website,
130see :ref:`override-configuration-via-page-tsconfig`.
131
132Selecting a specific preset for bullet lists can be done via TCA
133configuration of a field. The following example shows the TCA configuration
134for the sys_news database table, which can be found in
135:file:`EXT:core/Configuration/TCA/sys_news.php`.
136
137.. code-block:: php
138
139   'content' => [
140      'label' => 'LLL:EXT:lang/Resources/Private/Language/locallang_general.xlf:LGL.text',
141      'config' => [
142         'type' => 'text',
143         'cols' => 48,
144         'rows' => 5,
145         'enableRichtext' => true,
146         'richtextConfiguration' => 'default',
147      ],
148
149Enabling Rich Text Parsing itself is done via :ref:`t3tca:columns-text-properties-enableRichtext`,
150and a specific configuration
151can be set via :ref:`t3tca:columns-text-properties-richtextConfiguration`, setting it to for example
152“news”.
153
154.. _override-configuration-via-page-tsconfig:
155
156Overriding Configuration via Page TSconfig
157------------------------------------------
158
159Instead of overriding all TCA fields to use a custom preset, it is possible
160to override this information via Page TSconfig.
161
162The option :typoscript:`RTE.default.preset = news` can also be set on a per-field
163and per-type basis:
164
165.. code-block:: typoscript
166
167   # per-field
168   RTE.config.tt_content.bodytext.preset = minimal
169
170   # per-type
171   RTE.config.tt_content.bodytext.types.bullets.preset = bullets
172
173* line #2: This sets the "minimal" preset for all bodytext fields of
174  content elements.
175* line #4: This sets the "bullets" preset for all bodytext fields of
176  content elements with Content Type “Bullet list” (CType=bullets).
177
178Of course, any other specific option set via Yaml can be overridden via
179Page TSconfig as well:
180
181.. code-block:: typoscript
182
183   # Allow iframe tag with all attributes and all styles in bodytext field of content elements (Requires additional processing configuration)
184   RTE.config.tt_content.bodytext.editor.config.extraAllowedContent = iframe[*]{*}
185   # Restrict format_tags to h2 in bodytext field of content elements
186   RTE.config.tt_content.bodytext.editor.config.format_tags = h2
187
188For more examples, see :ref:`t3tsconfig:pageTsRte` in "TSconfig Reference".
189
190
191.. _config-rte-transformations:
192
193RTE Transformations
194===================
195
196Transformations are directives for parsing HTML markup. They are executed by the
197TYPO3 Core every time a RTE-based field is saved to the TYPO3 database or fetched
198from the database for the Rich Text Editor to render. This way, there are always
199two ways / two transformations applied.
200
201There are several advantages for transformations, the most prominent reason is to
202not inject bad HTML code into the database which in turn would be used for output.
203Transformations from the RTE towards the database can filter out HTML tags or attributes.
204
205.. todo: diagram rte -> DB -> RTE
206   todo: add examples for transformations
207   todo: possibly move most of this part to TYPO3 explained:
208     https://docs.typo3.org/typo3cms/CoreApiReference/latest/ApiOverview/Rte/Transformations/Index.html
209
210A Brief Dive Into History
211-------------------------
212
213Back in the very old days of TYPO3, there was an RTE which only worked inside Microsoft
214Internet Explorer 4 (within the system extension “`rte`”). All other editors of TYPO3 had
215to write HTML by hand, which was very complicated with all the table-based layouts available.
216Links were not set with a :html:`<a>` tag, but with a so-called :html:`<typolink 23,13 _blank>`
217tag. Further tags were :html:`<typolist>` and :html:`<typohead>`, which were stored in the database
2181:1. Since RTEs did not understand these special tags, they had to transform these special tags into
219valid HTML tags. Additionally, TYPO3 did not store regular :html:`<p>` or :html:`<div>` tags but
220treated every line without a surrounding HTML block element as :html:`<p>` tag. The frontend rendering
221then added `<p>` tags for each line when parsing (see below).
222
223Transformations were later used to allow :html:`<em>`/:html:`<strong>` tags instead of :html:`<b>`/:html:`<i>`
224tags, while staying backwards-compatible.
225
226A lot of transformation options have been dropped for TYPO3 v8, and the default configuration
227for these transformations acts as a solid base. CKEditor itself includes features that work as
228another security layer for disallowing injecting of certain HTML tags in the database.
229
230For TYPO3 v8, the :html:`<typolink>` tag was migrated to proper :html:`<a>` tags with a special
231:html:`<a href="t3://page?id=23">` syntax when linking to pages to ensure HTML valid output.
232Additionally, all records that are edited and stored to the database now contain proper
233<p> tags, and transformations for paragraph tags are only applied when not set yet.
234
235Transformations for invalid links and images (still available in HtmlArea) are still in place.
236
237Most logic related to transformations can be found within :php:`TYPO3\CMS\Core\Html\RteHtmlParser`.
238
239
240.. _transformations-vs-acf:
241
242Transformations vs. CKEditor’s Advanced Content Filter
243------------------------------------------------------
244
245TYPO3’s HtmlParser transformations were used to transform readable semi-HTML
246code to a full-blown HTML rendering ready for the RTE and vice versa. Since
247TYPO3 v8, magically adding :html:`<p>` tags or transforming :html:`<typolink>`
248tags is not necessary anymore, which leaves transformations almost obsolete.
249
250However, they can act as an extra fallback layer of security to filter out
251disallowed tags when saving. TYPO3 v8 configuration ships with a generic
252transformation configuration, which is mainly based on legacy functionality
253shipped with TYPO3 nowadays.
254
255However, CKEditor comes with a separate strategy of allowing which HTML tags
256and attributes are allowed, and can be configured on an editor-level.
257This configuration option is called “allowedContent”, the feature itself is
258named `Advanced Content Filter <http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter>`__
259(ACF).
260
261Activating CKEditor’s table plugin allows to add :html:`<table>`, :html:`<tr>`
262tags etc. Enabling the link picker enables the usage of :html:`<a>` tags. CKEditor
263cleans content right away which was e.g. copy-pasted from MS Word and does not
264match the allowed tags.
265
266
267.. _config-frontend:
268
269Frontend Output Configuration
270=============================
271
272Mostly due to historical reasons, the frontend output added :html:`<p>` tags to each
273line which is not wrapped in HTML. Additionally the :html:`<typolink>` tag was replaced
274by :html:`<a>` tags and checked if e.g. if a link was set to a specific page within
275TYPO3 is actually accessible for this specific visitor.
276
277The latter part is still necessary, so the :html:`<a href="t3://page?id23">` HTML snippet
278is replaced by a speaking URL which the power of typolink will still take care of.
279There are, of course, more options to it, like default “target” attributes for
280external links or spam-protecting links to email addresses, which all happens within the
281typolink logic, the master for generating a link in the TYPO3 Frontend rendering process.
282
283.. todo: [DIAGRAM DB => FE]
284
285
286TypoScript
287----------
288
289As with every content that is rendered via TYPO3, this processing for the frontend
290output of Rich-Text-Editing fields is done via TypoScript, more specifically within
291the stdWrap property :ref:`t3tsref:parsefunc`. With Fluid Styled Content and CSS Styled
292Content comes :typoscript:`lib.parseFunc` and :typoscript:`lib.parseFunc_RTE` which add
293support for parsing :html:`<a>` and :html:`<link>` tags and dumping them into the typolink
294functionality. The shipped TypoScript code looks like this:
295
296.. code-block:: typoscript
297
298   lib.parseFunc.tags {
299      a = TEXT
300      a {
301         current = 1
302         typolink {
303            parameter.data = parameters:href
304            title.data = parameters:title
305            ATagParams.data = parameters:allParams
306            target.data = parameters:target
307            extTarget = {$styles.content.links.extTarget}
308            extTarget.override.data = parameters:target
309         }
310      }
311   }
312
313
314If you already use Fluid Styled Content and CSS Styled Content and
315you haven’t touched that area of TypoScript yet, you’re good to go
316by including the TypoScript template.
317
318Fluid
319-----
320
321Outputting the contents of a RTE-enabled database field within Fluid can
322be achieved by adding :html:`<f:format.html>{record.myfield}</f:format.html>`
323which in turn calls :typoscript:`stdWrap.parseFunc` with :typoscript:`lib.parseFunc_RTE`
324thus applying the same logic. Just ensure that the :typoscript:`lib.parseFunc_RTE`
325functionality is available.
326
327You can check if this TypoScript snippet is loaded by using
328:guilabel:`Web > Template` and use the TypoScript Object Browser (Setup)
329to see if :typoscript:`lib.parseFunc_RTE` is filled.
330
331.. todo: [SCREENSHOT of TSOB having lib.parseFunc_RTE open]
332
333.. important::
334   If you add your opening and closing tags on an own line, the rendered output
335   includes empty paragraphs at beginning and end.
336
337.. tip::
338   In some cases it is an advantage to use the fluid inline notation to output the contents
339   of a RTE-enabled database field: :html:`{record.myfield -> f:format.html()}`. This makes
340   it easier to process the output further (e.g. by chaining Fluid ViewHelpers).
341
342
343
344