Custom content post procession for TYPO3

Compress or pretty print HTML output by your own

There are many HTML compression extensions for TYPO3 in the TER. Many of them aren't maintained anymore or just have a huge overhead, you will mostly not need for anything. So why not build a content compression by your own?

It's pretty easy to implement. Basically it just require the use of two Hooks from tslib/class.tslib_fe.php. The Hooks are called contentPostProc-all and contentPostProc-output. The first one handles normal pages with cached output, the second one does the same, just for uncached pages with COA or USER_INT objects. This Hooks will be bind to a class and function of your choice in ext_localconf.php of your extension.

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'][] =
    \Vendor\PostProcess\Hooks\ContentPostProcessor::class . '->cleanUncachedContent';
$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-all'][] =
    \Vendor\PostProcess\Hooks\ContentPostProcessor::class . '->cleanCachedContent';

As seen above, the class is named ContentPostProcessor and the functions cleanUncachedContent and cleanCachedContent are used. This needs to be created in the correct folder of your module exactly like this.

namespace Vendor\PostProcess\Hooks;

class ContentPostProcessor
{
    /**
     * clean cache content from FrontendRenderer, hook is called after Caching
     * for modification of pages with COA_/USER_INT objects
     * @param array $parameters
     * @return void
     */
    public function cleanUncachedContent(&$parameters)
    {
        // implement your handling
    }

    /**
     * clean cache content from FrontendRenderer, hook is called before Caching
     * for modification of pages on their way in the cache
     * @param array $parameters
     * @return void
     */
    public function cleanCachedContent(&$parameters)
    {
        // implement your handling
    }
}

That basically just does the trick. Now it's possible to compress, pretty print, extend or edit the HTML output in any way you want. Only thing to keep in mind is the time consumption. The Hook for uncached content will be run right in front of the page delivery. The time used there will be added to the normal page load itself. Keep it as small as possible.

For better understanding how this hooks work, I've added a more complex example below. This hooks will remove all comments from the content and tidy the output.

namespace Vendor\PostProcess\Hooks;

use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

class ContentPostProcessor
{
    /**
     * clean cache content from FrontendRenderer, hook is called after Caching
     * for modification of pages with COA_/USER_INT objects
     * @param array $parameters
     * @return void
     */
    public function cleanUncachedContent(&$parameters)
    {
        if (!$this->isDefaultTypeNum()) {
            return;
        }
    
        $tsfe = &$parameters['pObj'];

        if ($tsfe instanceof TypoScriptFrontendController && !$tsfe->isINTincScript()) {
            $tsfe->content = $this->tidyHtml($tsfe->content);
        }
    }

    /**
     * clean cache content from FrontendRenderer, hook is called before Caching
     * for modification of pages on their way in the cache
     * @param array $parameters
     * @return void
     */
    public function cleanCachedContent(&$parameters)
    {
        if (!$this->isDefaultTypeNum()) {
            return;
        }

        $tsfe = &$parameters['pObj'];

        if ($tsfe instanceof TypoScriptFrontendController && $tsfe->isINTincScript()) {
            $tsfe = &$parameters['pObj'];
            $tsfe->content = $this->tidyHtml($tsfe->content);
        }
    }

    /**
     * prettify html string
     * @param string $html
     * @return string
     */
    protected function tidyHtml($html)
    {
        // remove all comments, except those for indexed search
        $html = preg_replace('/<!--(.(?<!TYPO3SEARCH_))*-->/isU', '', $html);

        libxml_use_internal_errors(true);
        $dom = new \DOMDocument();
        $dom->preserveWhiteSpace = false;
        $dom->loadHTML($html);
        $dom->formatOutput = true;
        libxml_use_internal_errors(false);

        return $dom->saveHTML();
    }

    /**
     * check if current rendering is in default page type
     * @return bool
     */
    protected function isDefaultTypeNum()
    {
        $type = GeneralUtility::_GET('type');
        return $type === null || $type === 0;
    }
}

If you want to compress the content instead, it's a good idea to use a third-party library, like WyriHaximus/HtmlCompress. So you don't have to implement anything on your own again. Compression can become very complex otherwise.

use WyriHaximus\HtmlCompress\Factory;

$parser = Factory::construct();
$html = $parser->compress($html);
Share:

Einen Kommentar verfassen

Ihre E-Mail-Adresse wird nicht veröffentlicht, sie dient nur der Identifikation! Für die Profilbilder wird Gravatar verwendet und reCAPTCHA, um Spam zu vermeiden.

Kommentare 0

Es sind noch keine Kommentare für diesen Beitrag vorhanden.