oheil
oheil

Reputation: 107

TYPO3 11 content element Plain HTML with <style>

TYPO3 11.5.4

I want to add a Plain HTML content element to a page, e.g.:

<style type="text/css">
  h1#testheader { font-weight: bold; }
</style>
<h1 id="testheader">
  Header
</h1>

(just as a simplified example)

But rendered output is:

<style type="text/css"> h1#testheader { font-weight: bold; } </style>
Header

I thought that style is allowed because I set:

lib.parseFunc.allowTags = ...,style,...
lib.parseFunc_RTE.allowTags = ...,style,...

but it doesn't work. Setting

lib.parseFunc.htmlSanitize = 0

helps but is there something better to allow <style> in Plain HTML content elements?

EDIT: Looking into the DB entry the html tags are not encoded, so no "<" or ">" instead of "<" and ">", so it's not an issue of the RTE.

Upvotes: 1

Views: 812

Answers (1)

oheil
oheil

Reputation: 107

After some more research (hours of hours again invested) I come to the conclusion that the only way is to extend the HTMLSanitizer.

The following sources have been used for this solution:

https://punkt.de/de/blog/2021/htmlsanitizer-in-typo3.html https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/9.5.x/Important-94484-IntroduceHTMLSanitizer.html https://gist.github.com/ohader/2239dab247e18d23e677fd1b816f4fd5

The complete solution to allow <style>,<script> and <iframe> is shown below.

Still I am not able to allow <font> with this approach!

It's implemented in a local site package (gpcf_theme) and composer is used.

Add <style>,<script> and <iframe> to

lib.parseFunc.allowTags = ... style, ..., iframe, script, ...

in the TypoScript part of the site package.

style seems to be standard and is already part of this list.

The path to the local site package is:

local_packages/gpcf_theme

with a symbolic link to it from:

public/typo3conf/ext/gpcf_theme -> ../../../local_packages/gpcf_theme

These are the important file changes:

local_packages/gpcf_theme/composer.json:

{
        "name": "oheil/gpcf_theme",
        ...
        "autoload": {
                "psr-4": {
                        "Oheil\\GpcfTheme\\": "Classes/"
                }
        },
        ...
}

local_packages/gpcf_theme/ext_localconf.php:

<?php
defined('TYPO3_MODE') || die();

...
$GLOBALS['TYPO3_CONF_VARS']['SYS']['htmlSanitizer']['default'] = \Oheil\GpcfTheme\MyDefaultBuilder::class;
...

local_packages/gpcf_theme/Classes/MyDefaultBuilder.php

<?php

namespace Oheil\GpcfTheme;

use TYPO3\CMS\Core\Html\DefaultSanitizerBuilder;
use TYPO3\HtmlSanitizer\Behavior;
use TYPO3\HtmlSanitizer\Behavior\Attr;
use TYPO3\HtmlSanitizer\Behavior\Tag;

class MyDefaultBuilder extends \TYPO3\CMS\Core\Html\DefaultSanitizerBuilder
{
    protected function createBehavior(): \TYPO3\HtmlSanitizer\Behavior
    {
        // https://docs.typo3.org/c/typo3/cms-core/main/en-us/Changelog/9.5.x/Important-94484-IntroduceHTMLSanitizer.html

        return parent::createBehavior()
                ->withName('common')
                ->withTags(
                        (new Tag(
                                'style',
                                Tag::ALLOW_CHILDREN + Behavior::ENCODE_INVALID_TAG
                        ))->addAttrs(
                                (new Attr('type')),
                                ...$this->globalAttrs
                        ),
                        (new Tag(
                                'iframe',
                                Tag::ALLOW_CHILDREN
                        ))->addAttrs(
                                ...array_merge(
                                        $this->globalAttrs,
                                        [$this->srcAttr],
                                        $this->createAttrs('scrolling', 'marginwidth', 'marginheight', 'frameborder', 'vspace', 'hspace', 'height', 'width')
                                )
                        ),
                        (new Tag(
                                'script',
                                Tag::ALLOW_CHILDREN
                        ))->addAttrs(
                                ...array_merge(
                                        $this->globalAttrs,
                                        [$this->srcAttr]
                                )
                        ),
                        // more tags...
        );
    }
}

After these changes of course you need to clear the TYPO3 cache and (not sure here) you need to do:

composer remove "oheil/gpcf_theme"
composer require "oheil/gpcf_theme"

The above is working now, but I am still happy for any expert to give some more insights in what is wrong or can be done better, perhaps easier?

And why does this not work for <font> ? Example:

<font class="font713099">Some Text</font>

Upvotes: 2

Related Questions