You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TYPO3 v12.4中HMENU的entryLevel动态切换问题求助

TYPO3 7.6升级至12.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]

问题根源

  1. 配置覆盖问题:在条件语句中重新定义stdWrap.ifEmpty.cObject = HMENU时,会完全覆盖原有的TMENU配置,导致仅设置了entryLevel但丢失了菜单的样式、激活状态等核心行为。
  2. 冗余配置维护风险:原代码中重复定义TMENU配置,不仅增加代码量,还容易在修改时出现不一致。
  3. 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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 08:25:18