b13 / menus
为TYPO3前端提供简单快捷的菜单
Requires
- php: ^7.4 || ~8.0
- typo3/cms-core: ^10 || ^11 || ^12.4
- typo3/cms-frontend: ^10 || ^11 || ^12.4
Requires (Dev)
- phpstan/phpstan: ^1.8.11
- phpunit/phpunit: ^9.5
- typo3/cms-fluid-styled-content: ^11.5
- typo3/cms-install: ^11.5
- typo3/coding-standards: ^0.5
- typo3/tailor: ^1.0
- typo3/testing-framework: 7.0.2
This package is auto-updated.
Last update: 2024-09-02 10:14:28 UTC
README
菜单 - 一个用于创建快速菜单的TYPO3扩展 - 以快速的方式
简介
TYPO3 CMS因其能够处理大量内容的大型网站而闻名。TYPO3 核心提供了几种非常灵活的方式构建导航/菜单。然而,生成菜单一直是我们大多数大规模项目中的繁琐问题。在TYPO3 v9中,生成菜单的性能在URL生成方面有所提高,但链接和菜单生成中仍存在一些概念性问题。
-
所有逻辑都依赖于HMENU
每个菜单都是使用HMENU生成的,即使是Fluid的MenuDataProcessor也使用它。是的,它很强大,但也提供了我们大多数情况下不需要的大量选项。
-
HMENU为每个页面保存状态
HMENU提供了定义大量状态(“活动”、“当前”、“有子项”)的可能性。这些信息对于每个页面都是不同的——显然——然后被缓存在
cache_hash
的单独缓存条目中,即使我们不使用状态,缓存条目也相当大。我们使用
expAll
(扩展所有其他页面的所有子页面),这使得对页面的请求变得非常大。 -
HMENU对“特殊”菜单有晦涩的语法
如今,为页脚导航、巨菜单、像网站地图一样的侧边栏菜单等构建菜单相当常见。对于语言菜单使用“special.”,对于“目录”或简单的页面列表,似乎相当复杂。
这个扩展试图通过以下方式克服这些陷阱
- 一次性构建菜单,然后缓存结果,之后应用活动状态(减少缓存数据量)。这对于基于树的菜单尤为重要,
- 引入新的cObjects和数据处理器以针对特定用例,使它们对非TYPO3-Gurus更易于理解。
安装与需求
使用composer req b13/menus
或通过从TYPO3扩展仓库使用扩展键menus
通过TYPO3扩展管理器安装。
您需要TYPO3 v9以及站点处理才能使用此扩展。如果您的项目支持挂载点,则此功能尚未实现。此外,访问受限制页面的页面(尽管没有访问权限)尚未考虑。
功能
此扩展为基于Fluid的页面模板提供TypoScript cObjects和TypoScript DataProcessors。
所有菜单的常用选项
- excludePages - 要从页面中排除的页面ID列表(如果使用树菜单或面包屑导航,则包括其子页面)
- excludeDoktypes - 不渲染的文档类型列表。默认排除BE_USER_SECTION。查询SYS_FOLDER(用于子页面等),但从不渲染。
- includeNotInMenu - 包含设置为1的nav_hide的页面,而不是忽略它们
项目常用选项
在TypoScript中,此选项可用作field:isSpacer
,在Fluid中,此选项可通过{page.isSpacer}
访问
- {page.isCurrentPage} (bool)
- {page.isInRootLine} (bool)
- {page.isSpacer} (bool)
- {page.hasSubpages} (bool) - TreeMenu only
- {page.subpages} (array) - TreeMenu only
树菜单
用于巨菜单、为移动设备创建单独的菜单(如网站地图)等。
基于TypoScript的纯解决方案
page.10 = TREEMENU
# a list of page IDs, rootpageID is used if none given
page.10.entryPoints = 23,13
# the number of levels to fetch from the database (1 if empty)
page.10.depth = 3
page.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.renderObj.level0 = TEXT
page.10.renderObj.level0.typolink.parameter.data = field:uid
page.10.renderObj.level0.typolink.ATagParams = class="active"
page.10.renderObj.level0.typolink.ATagParams.if.isTrue.field = isInRootLine
page.10.renderObj.level0.dataWrap = <li class="firstLevel">|<ul>{field:subpageContent}</ul></li>
基于Fluid的解决方案
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\TreeMenu
page.10.dataProcessing.10.entryPoints = 23,13
page.10.dataProcessing.10.depth = 3
page.10.dataProcessing.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
page.10.dataProcessing.10.as = mobilemenu
在Fluid中的使用
<nav>
<f:for each="{mobilemenu}" as="page">
<f:link.page pageUid="{page.uid}">{page.nav_title}</f:link.page>
<f:if condition="{page.hasSubpages} && {page.isInRootLine}">
<ul>
<f:for each="{page.subpages}" as="subpage">
<li><f:link.page pageUid="{subpage.uid}">{subpage.nav_title}</f:link.page>
</f:for>
</ul>
</f:if>
</f:for>
</nav>
注意:如果数据库记录nav_title为空,则nav_title是标题。
语言菜单
通过几行代码即可实现语言切换器的构建
纯TypoScript解决方案
page.10 = LANGUAGEMENU
page.10.excludeLanguages = de,en
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
# add all siteLanguages to menu even if page is not available in language (default 0)
page.10.addAllSiteLanguages = 1
page.10.wrap = <ul> | </ul>
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.typolink.additionalParams.data = field:language|languageId
page.10.renderObj.typolink.additionalParams.intval = 1
page.10.renderObj.typolink.additionalParams.wrap = &L=|
page.10.renderObj.data = field:language|title // field:language|twoLetterIsoCode
page.10.renderObj.wrap = <li class="language-item"> | </li>
stdWrap data
是当前页面的信息以及从所选网站语言合并的信息。
基于Fluid的解决方案
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\LanguageMenu
page.10.dataProcessing.10.excludeLanguages = de,en
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
# add all siteLanguages to menu even if page is not available in language (default 0)
page.10.dataProcessing.10.addAllSiteLanguages = 1
page.10.dataProcessing.10.as = languageswitcher
在Fluid中的使用
<nav>
<f:for each="{languageswitcher}" as="item">
<f:link.page pageUid="{item.uid}" language="{item.language.languageId}">{item.language.title}</f:link.page>
</f:for>
</nav>
注意:语言菜单在language
属性中将每个条目的siteLanguage作为数组持有
列表菜单
如果您只想获取文件夹中所有项目的列表,或者用于页脚的链接列表,请使用列表菜单。
基于TypoScript的纯解决方案
page.10 = LISTMENU
# a page ID, rootpageID is used if none given, stdWrap possible
page.10.pages = 13,14,15
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.wrap = <ul> | </ul>
page.10.renderObj = TEXT
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.wrap = <li> | </li>
基于Fluid的解决方案
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\ListMenu
page.10.dataProcessing.10.pages = 13,14,15
page.10.dataProcessing.10.as = footerlinks
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
在Fluid中的使用
<nav>
<f:for each="{footerlinks}" as="page">
<f:link.page pageUid="{page.uid}">{page.nav_title}</f:link.page>
</f:for>
</nav>
面包屑菜单(又称根线菜单)
page.10 = BREADCRUMBS
page.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.includeNotInMenu = 0
page.10.wrap = <ul> | </ul>
page.10.renderObj = TEXT
page.10.renderObj.typolink.parameter.data = field:uid
page.10.renderObj.wrap = <li> | </li>
基于Fluid的解决方案
page.10 = FLUIDTEMPLATE
page.10.dataProcessing.10 = B13\Menus\DataProcessing\BreadcrumbsMenu
page.10.dataProcessing.10.excludePages = 4,51
# 0: default, 1 to include nav_hide = 1 pages
page.10.dataProcessing.10.includeNotInMenu = 0
page.10.dataProcessing.10.as = breadcrumbs
在Fluid中的使用
<nav>
<f:for each="{breadcrumbs}" as="page">
<f:link.page pageUid="{page.uid}">{page.nav_title}</f:link.page>
<f:if condition="{page.isCurrentPage} == false"> </f:if>
</f:for>
</nav>
菜单的动态配置值(stdWrap)
如果您想获取页面的直接同级菜单,无论选择哪个页面,都可以使用内置在每个属性中的stdWrap函数
9999 = B13\Menus\DataProcessing\TreeMenu
9999 {
entryPoints.data = page:pid
as = listOfJobPages
}
通过使用entryPoints
属性的.data
属性,我们可以访问当前构建页面的每个属性。因此,我们可以渲染页面的同级。
技术细节
缓存
在"cache_hash"中,记录的检索被缓存在带有适当缓存标签的缓存条目中,渲染也被缓存在每个页面的单独缓存条目中(常规),其中应用了活动状态。
常见问题解答(FAQ)
此扩展避免处理选项addQueryParams
、ADD_GET_PARAM
或target
属性,以便尽可能地将页面作为“本地”处理,就像任何其他链接一样。
许可证
此扩展根据GPL v2+许可,与TYPO3核心相同。有关详细信息,请参阅此存储库中的LICENSE文件。
开放性问题
如果您发现问题,请随时在GitHub上创建问题或拉取请求。
待办事项
- 添加
includeSpacer
选项 - 将stdWrap功能从缓存参数中提取出来
鸣谢
此扩展由Benni Mack于2019年创建,用于b13 GmbH。
查找更多我们开发的TYPO3扩展,这些扩展有助于我们在客户项目中实现价值。作为我们的工作方式的一部分,我们专注于测试和最佳实践,以确保我们所有代码的长期性能、可靠性和结果。