FluidTYPO3 / vhs

TYPO3 extension VHS: Fluid ViewHelpers
https://fluidtypo3.org
Other
189 stars 228 forks source link

Typo3 v11: Asset handling #1736

Closed MediKathi closed 2 years ago

MediKathi commented 3 years ago

Some of the hooks are gone in Typo3 v11 now.

For example: $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['contentPostProc-output'] which ist used by the assetservice

Therefore the Asset Viewhelpers are not longer working.

Edit: I was able to get this working in a Kinda lazy way, I reimplemented the old hook:

I had to create a file typo3conf/ext/myExt/Configuration/RequestMiddlewares.php

<?php
return [
    'frontend' => [
        'myVendor/myExt/assets' => [
            'target' => \myVendor\myExt\Middleware\Assets::class,
            'after' => [
                'typo3/cms-frontend/output-compression',
            ],
        ],
    ],
];

also setting up some stuff in the typo3conf/ext/myExt/Configuration/Services.yaml

services:
  _defaults:
    autowire: true
    autoconfigure: true
    public: false

  myVendor\myExt\Middleware\Assets:
    public: true
    arguments:
      $responseFactory: '@Psr\Http\Message\ResponseFactoryInterface'
      $requestFactory: '@Psr\Http\Message\RequestFactoryInterface'

And Filnaly remimplemented the Hook typo3conf/ext/myExt/Classes/Middleware/Assets.php:

<?php

namespace Dm\DmLayout\Middleware;

use Psr\Http\Client\ClientInterface;
use Psr\Http\Message\RequestFactoryInterface;
use Psr\Http\Message\ResponseFactoryInterface;
use Psr\Http\Message\ResponseInterface;
use Psr\Http\Message\ServerRequestInterface;
use Psr\Http\Server\MiddlewareInterface;
use Psr\Http\Server\RequestHandlerInterface;

use TYPO3\CMS\Core\Http\Response;
use TYPO3\CMS\Core\Utility\GeneralUtility;

class Assets implements MiddlewareInterface
{
    /** @var ResponseFactory */
    private $responseFactory;

    /** @var RequestFactory */
    private $requestFactory;

    public function __construct(
        ResponseFactoryInterface $responseFactory,
        RequestFactoryInterface $requestFactory
    ) {
        $this->responseFactory = $responseFactory;
        $this->requestFactory = $requestFactory;
    }

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        $controller = $GLOBALS['TSFE'];
        $response = new Response();
        $controller->content = $handler->handle($request)->getBody()->__toString();
        $response = $controller->applyHttpHeadersToResponse($response);   
        $_params = ['pObj' => &$controller];
        foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['myAssetsHook'] ?? [] as $_funcRef) {
            GeneralUtility::callUserFunction($_funcRef, $_params, $controller);
        }
        $response->getBody()->write($controller->content);
        return $response;
    }
}

The new hook can then be used in the ext_localconf.php:

$GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['tslib/class.tslib_fe.php']['myAssetsHook'][] = 'FluidTYPO3\\Vhs\\Service\\AssetService->buildAllUncached';
tobsnti commented 2 years ago

Have you considered to migrate your asset includes to the new AssetCollector?

Introduction: https://docs.typo3.org/c/typo3/cms-core/master/en-us/Changelog/10.3/Feature-90522-IntroduceAssetCollector.html
Viewhelpder docs: https://docs.typo3.org/other/typo3/view-helper-reference/10.4/en-us/typo3/fluid/latest/Asset/Css.html

MediKathi commented 2 years ago

The Asset-Collector seams to be a nice Feature, but accutally we (in the company I work for) are using a slight modified version of the vhs Asset-Service since Typo3 v7. We Keep the Code of the Fork upn to date. We Added a possibility to Compile SASS directly within the Assest-Service with one call to the Compiler, after the files are combined. Because the Asset-Service is called via the Hook, we are easily and update-safe able to replace the Original with our internal fork.

NamelessCoder commented 2 years ago

For posterity: this only happens if config.no_cache = 1 or other implementations disable page cache completely. Solved now by switching to request middlewares on TYPO3 versions that support this. @MediKathi beware, I had to change an (internal) method signature AssetService::buildAll (and others internally) so if you plan on keeping your AssetService override you might need to adjust that.

mkarulin commented 2 years ago

@NamelessCoder, Has this been tested in TYPO3 9.5 and 10.4? When page is not cached, the assets are loaded, but after caching, they are gone. Proble started with in 6.1.0

EDIT: I tested with TYPO3 11.5, and it's not working there either.

NamelessCoder commented 2 years ago

@mkarulin It was tested on all four supported TYPO3 versions, but it's possible (likely) that some specific context state was affecting my results while testing. For example, I was always logged in to the BE.

Can you open a new issue for this, then I will look into it?