TYPO3中通过userFunc实现includeCSS主题切换失败求助
TYPO3 日光主题切换:includeCSS 加载主题CSS失效问题解决
问题背景
我有一个TYPO3站点需要根据日光时间自动切换深色/浅色主题,已在常量中定义sunrise和sunset参数,通过userFunc调用Vendor\Extension\Utility\ThemeClass类成功实现了body标签的主题类切换,但在page.includeCSS中用类似方式调用userFunc加载对应主题的CSS文件时无法生效,尝试多种变通方法仍未解决。
现有代码
ThemeClass 类
<?php namespace Vendor\Extension\Utility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; /** * will return theme class in various instances of the page */ class ThemeClass extends ContentObjectRenderer { /** * @var \TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer */ public $cObj; /** * Returns theme class according to daylight * * @var string $content * @var array $config * @return string **/ protected function class($content, array $config = null) { // init $sunRise = $this->cObj->stdWrapValue('sunRise', $config, null); $sunSet = $this->cObj->stdWrapValue('sunSet', $config, null); $format = 'h:i a'; $now = date_create_from_format($format, Date($format)); $open = date_create_from_format($format, $sunRise); $close = date_create_from_format($format, $sunSet); return $theme = ($now > $open && $now < $close) ? 'light' : 'dark' ; } /** * Returns body tag according to theme * * @var string $content * @var array $config * @return string **/ public function bodyTag($content, array $config = null) { $theme = $this->class($content, $config); return '<body class="'.$theme.'">'; } /** * Returns css according to theme * * @var string $content * @var array $config * @return string **/ public function themeCss($content, array $config = null) { $theme = $this->class($content, $config); return 'EXT:extension/Resources/Public/Css/_'.$theme.'.css">'; } }
已生效的body标签配置
page.bodyTag > page.bodyTagCObject = USER page.bodyTagCObject { userFunc = Vendor\Extension\Utility\ThemeClass->bodyTag sunRise = {$extension.config.daylight.sunrise} sunSet = {$extension.config.daylight.sunset} }
未生效的includeCSS配置
page.includeCSS { theme.cObject = USER theme.cObject { userFunc = Vendor\Extension\Utility\ThemeClass->themeCss sunRise = {$extension.config.daylight.sunrise} sunSet = {$extension.config.daylight.sunset} } }
问题原因与解决方案
TYPO3的page.includeCSS不支持直接给单个条目设置cObject = USER来返回文件路径,需要通过stdWrap.cObject实现动态路径替换。同时原themeCss方法返回了多余的闭合标签,会导致路径解析错误。
修改步骤
- 修正
themeCss方法:去掉多余的闭合标签,仅返回正确的EXT格式路径 - 调整includeCSS配置:使用
stdWrap.cObject调用userFunc,替代直接设置条目cObject
修改后的代码
修正后的ThemeClass::themeCss方法
/** * Returns css file path according to theme * * @var string $content * @var array $config * @return string **/ public function themeCss($content, array $config = null) { $theme = $this->class($content, $config); // 仅返回标准EXT路径格式,无多余标签 return 'EXT:extension/Resources/Public/Css/_'.$theme.'.css'; }
修正后的includeCSS配置
page.includeCSS { // 设置默认路径(可选,确保极端情况有 fallback) theme = EXT:extension/Resources/Public/Css/_light.css // 通过stdWrap调用userFunc动态替换路径 theme.stdWrap.cObject = USER theme.stdWrap.cObject { userFunc = Vendor\Extension\Utility\ThemeClass->themeCss sunRise = {$extension.config.daylight.sunrise} sunSet = {$extension.config.daylight.sunset} } // 可选:设置CSS media属性 theme.media = all }
额外优化建议
日期比较逻辑可以改用时间戳,避免因date对象时区或格式问题导致的错误:
protected function class($content, array $config = null) { $sunRise = $this->cObj->stdWrapValue('sunRise', $config, null); $sunSet = $this->cObj->stdWrapValue('sunSet', $config, null); $format = 'h:i a'; // 转换为时间戳进行比较,更可靠 $nowTimestamp = strtotime(date($format)); $sunRiseTimestamp = strtotime($sunRise); $sunSetTimestamp = strtotime($sunSet); return ($nowTimestamp > $sunRiseTimestamp && $nowTimestamp < $sunSetTimestamp) ? 'light' : 'dark'; }
内容的提问来源于stack exchange,提问作者webman
相关产品推荐
相关产品推荐

