TYPO3 v12.4中HMENU的entryLevel动态切换问题求助
从TYPO3 7.6升级到12.4版本,仅将treeLevel替换为tree.level后,原有实现动态切换HMENU的entryLevel的TypoScript代码失效。菜单预期逻辑为:显示当前层级的页面,若当前层级无页面项,则显示上一层级的页面项。
以下是原代码:
lib._submenu = HMENU lib._submenu { 1 = TMENU 1 { expAll = 1 NO.wrapItemAndSub = <li>|</li> IFSUB = 1 IFSUB.wrapItemAndSub = <li class="hasSub">|</li> ACT < .NO ACT = 1 ACT.wrapItemAndSub = <li class="active">|</li> ACT.ATagParams = class="active" ACTIFSUB = 1 ACTIFSUB.wrapItemAndSub = <li class="hasSub active">|</li> ACTIFSUB.ATagParams = class="active" SPC = 1 SPC.wrapItemAndSub = <li class="trenner">|</li> SPC.doNotShowLink = 0 } stdWrap.ifEmpty.cObject = HMENU stdWrap.ifEmpty.cObject { 1 = TMENU 1 { expAll = 1 NO.wrapItemAndSub = <li>|</li> IFSUB = 1 IFSUB.wrapItemAndSub = <li class="hasSub">|</li> ACT < .NO ACT = 1 ACT.wrapItemAndSub = <li class="active">|</li> ACT.ATagParams = class="active" ACTIFSUB = 1 ACTIFSUB.wrapItemAndSub = <li class="hasSub active">|</li> ACTIFSUB.ATagParams = class="active" SPC = 1 SPC.wrapItemAndSub = <li class="trenner">|</li> SPC.doNotShowLink = 0 } } } [tree.level == 1] lib._submenu { entryLevel = 1 } [END] [tree.level == 2] lib._submenu { entryLevel = 2 stdWrap.ifEmpty.cObject = HMENU stdWrap.ifEmpty.cObject { entryLevel = 1 } } [END] [tree.level == 3] lib._submenu { entryLevel = 3 stdWrap.ifEmpty.cObject = HMENU stdWrap.ifEmpty.cObject { entryLevel = 2 } } [END] [tree.level == 4] lib._submenu { entryLevel = 4 stdWrap.ifEmpty.cObject = HMENU stdWrap.ifEmpty.cObject { entryLevel = 3 } } [END]
问题根源
- 配置覆盖问题:在条件语句中重新定义
stdWrap.ifEmpty.cObject = HMENU时,会完全覆盖原有的TMENU配置,导致仅设置了entryLevel但丢失了菜单的样式、激活状态等核心行为。 - 冗余配置维护风险:原代码中重复定义TMENU配置,不仅增加代码量,还容易在修改时出现不一致。
- TYPO3版本差异:12.x中HMENU的对象继承和属性处理逻辑与7.6有差异,直接覆盖对象会破坏原有配置链。
修复方案
步骤1:抽离通用TMENU配置
将重复的TMENU配置抽离为独立对象,通过继承复用,避免重复定义和配置丢失:
# 通用TMENU配置,统一菜单样式与行为 lib._submenuTmenu = TMENU lib._submenuTmenu { expAll = 1 NO.wrapItemAndSub = <li>|</li> IFSUB = 1 IFSUB.wrapItemAndSub = <li class="hasSub">|</li> ACT < .NO ACT = 1 ACT.wrapItemAndSub = <li class="active">|</li> ACT.ATagParams = class="active" ACTIFSUB = 1 ACTIFSUB.wrapItemAndSub = <li class="hasSub active">|</li> ACTIFSUB.ATagParams = class="active" SPC = 1 SPC.wrapItemAndSub = <li class="trenner">|</li> SPC.doNotShowLink = 0 }
步骤2:重构主菜单定义
主菜单和备用菜单都继承通用TMENU配置,仅保留核心结构:
lib._submenu = HMENU lib._submenu { 1 < lib._submenuTmenu # 备用菜单继承通用配置,避免重复定义 stdWrap.ifEmpty.cObject = HMENU stdWrap.ifEmpty.cObject { 1 < lib._submenuTmenu } }
步骤3:简化条件配置
条件中仅修改entryLevel属性,不再重新定义HMENU对象,确保原有配置不被覆盖:
[tree.level == 1] lib._submenu.entryLevel = 1 [END] [tree.level == 2] lib._submenu.entryLevel = 2 lib._submenu.stdWrap.ifEmpty.cObject.entryLevel = 1 [END] [tree.level == 3] lib._submenu.entryLevel = 3 lib._submenu.stdWrap.ifEmpty.cObject.entryLevel = 2 [END] [tree.level == 4] lib._submenu.entryLevel = 4 lib._submenu.stdWrap.ifEmpty.cObject.entryLevel = 3 [END]
可选优化:动态计算entryLevel
如果站点层级规则固定,可以用动态数值计算替代条件语句,进一步简化代码:
# 直接设置当前层级为entryLevel lib._submenu.entryLevel = {tree.level} # 备用菜单设置为上一层级 lib._submenu.stdWrap.ifEmpty.cObject.entryLevel = {tree.level - 1} # 确保数值有效,避免层级为0时出错 lib._submenu.stdWrap.ifEmpty.cObject.entryLevel.stdWrap.ifEmpty = 1
内容的提问来源于stack exchange,提问作者Christian
相关产品推荐
相关产品推荐

