Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Load additional stylesheets in TYPO3 backend #33

Open
zenoussi opened this issue Dec 8, 2023 · 3 comments
Open

Load additional stylesheets in TYPO3 backend #33

zenoussi opened this issue Dec 8, 2023 · 3 comments

Comments

@zenoussi
Copy link

zenoussi commented Dec 8, 2023

It is possible to load additional CSS files for the TYPO3 backend interface via regular $TYPO3_CONF_VARS settings in a settings.php file of a project (previously known as LocalConfiguration.php) file or in an extension's ext_localconf.php.

$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'][my_extension] = 'EXT:myextension/Resources/Public/Css/myfile.css';
$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'][my_extension] = 'EXT:myextension/Resources/Public/Css/';

How can the requirements be solved?

Thanks a lot

@s2b
Copy link
Owner

s2b commented Dec 8, 2023

Hi! This was a topic in the Slack channel recently. There isn't an elegant solution in the extension yet, but it seems to be possible:

https://typo3.slack.com/archives/C05JYUT3CDP/p1700160676583849

@zenoussi
Copy link
Author

zenoussi commented Dec 8, 2023

Thank you very much, but as an integrator you don't understand what was done here to arrive at this result - a pity.
Perhaps the functionality can be extended or the workaround can be explained in advance in the documentation?

Greetings

@ri-klein
Copy link

Hello, I recently came across basically the same problem as well. I first attempted to just use the ViteService in ext_localconf, but apparently it cannot be instantiated inside ext_localconf, as the core does not allow injecting the CacheManager at that time in the bootstrapping process. Instead, I came up with something similar to the approach already discussed in Slack:

Since we already have the VitePlaceholderProcessor for resolving %vite(...)%-placeholders in yaml files, my idea was to just use those placeholders in the $GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'] array as well. A Middleware then lets the VitePlaceholderProcessor do the 'heavy lifting' in resolving the entry points, before the PageRenderer evaluates the stylesheet array.

My code basically looks like this:

// ext_localconf.php

$GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets']['some_identifier'] = "%vite('ENTRY_POINT_IDENTIFIER')%";
// Classes/Middleware/ProcessVitePlaceholdersInConfVars.php

class ProcessVitePlaceholdersInConfVars implements MiddlewareInterface
{
    protected ?VitePlaceholderProcessor $placeholderProcessor = null;

    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
    {
        foreach($GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'] as $key => $placeholder) {
            if (preg_match('/^%vite\((?<value>.*?)\)%$/', $placeholder, $matches) !== 1) {
                continue;
            }

            $placeholderProcessor = $this->getPlaceHolderProcessor();
            // The placeholder processor only needs the substring within '%vite(...)%', not the entire placeholder. We
            // still keep the placeholder syntax, so we can distinguish vite entrypoints from 'legitimate' CSS files in
            // the TYPO3_CONF_VARS array.
            $resolvedPath = $placeholderProcessor->process($matches['value'], []);
            // Strip leading slash, or else the path will not be interpreted as relative to webroot
            $GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'][$key] = ltrim($resolvedPath, '/');
        }

        return $handler->handle($request);
    }

    // Use lazy instantiation here, since this middleware runs at every BE request.
    // So we should only instantiate the placeholder processor when we really need it.
    protected function getPlaceHolderProcessor(): VitePlaceholderProcessor
    {
        if ($this->placeholderProcessor === null) {
            $this->placeholderProcessor = GeneralUtility::makeInstance(VitePlaceholderProcessor::class);
        }

        return $this->placeholderProcessor;
    }
}
// Configuration/RequestMiddlewares.php

return [
    'backend' => [
        'vendor/name/process-vite-placeholders-in-conf-vars' => [
            'target' => \Vendor\Name\Middleware\ProcessVitePlaceholdersInConfVars::class,
            'before' => [
                'typo3/cms-core/response-propagation',
            ],
        ],
    ],
];

Some things to note:

  • The middleware MUST run before typo3/cms-core/response-propagation, as that one seems to initiate the page rendering process, where $GLOBALS['TYPO3_CONF_VARS']['BE']['stylesheets'] gets evaluated
  • The vite entrypoint must be a CSS or SCSS file, otherwise a .js file will be returned (which obviously won't work)

Maybe this will help someone.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants