如何通过 TypoScript 获取 HMENU 项目的 "leveltitle"?
How to get "leveltitle" for HMENU items via TypoScript?
我有一个菜单(带 special = updated
的 HMENU),它为我提供了来自 3 个类别的最新子页面和 sub-sub 页面。
后端的页面结构如下所示:
除了标题,我想输出相应类别的名称(parent 一级页面)。
这是我的 TypoScript 尝试:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category attempt-1">|</div>
special = rootline
special.range = 1|1
special.value.field = uid # does not work
1 = TMENU
1.NO.allWrap = |
}
30 = TEXT
30{
wrap = <div class="category attempt-2">|</div>
data = leveltitle : 1 # does not work as expected
}
}
}
}
}
不幸的是,它不起作用,因为……
special = rootline
不支持special.value
.
data = leveltitle : 1
使用当前页面的 ID,而不是 TMENU 项目 ID。
有人有其他方法可以使用 TypoScript 获取相应类别的标题吗?
编辑:背景信息/需要做什么
我打算用这个菜单替换现有项目的新闻模块 ext:news。现在使用页面而不是新闻记录,并且此菜单创建列表视图。当然会添加一个TypoScript页面浏览器。
我不会重建完整的菜单项生成 (NO.doNotLinkIt = 1
)。
只需使用NO.after.cObject = COA
.
leveltitle : 1
如果你想要当前页面的标题是正确的。
如果显示根菜单也是一样的:它是为当前页面生成的。
如果你想要其他页面的levelfield,你需要自己构建它。
在打字错误中,您可能会使用用户函数。 (有一个核心函数用于获取给定页面 id 的根线)
如果您使用 FLUID 生成菜单,您可能会使用 viewhelper。 (您可能会从 ext:vhs
中的 this option of viewhelper menu.directory
or this option of VH page.breadCrumb
中得到启发。)
编辑:
您可以将需要的信息直接存储在pages
记录中。
向记录添加新字段(或使用任何未使用的字段)。
然后确保每个类别页面包含一些页面 TS_config:
TCADefaults.pages.<yourfield> = CategoryName
使用此配置,下面的每个新页面都会自动设置此值。
当然,您需要手动或通过一些手动查询为所有现有页面设置这些值。
如果要阻止编辑器更改此值,您需要使用 top-page 上的此 TSConfig 从编辑表单中删除该字段:
TCEForm.pages.<yourfield>.hide= 1
我找到了一个纯 TypoScript 解决方案,可能不是很优雅,但它有效:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category">|</div>
special = list
special.value.field = pid
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = HMENU
cObject{
special = list
special.value.field = pid
1 = TMENU
1.NO.doNotLinkIt = 1
}
}
}
}
}
}
}
}
}
如果菜单要越过更多层次,覆盖当然必须嵌套得更深。
编辑 – 改进:
RECORDS 而不是 HMENU: Bernd Wilke 在评论中建议使用 CONTENT 而不是 HMENU 来生成类别标题。当系统文件夹(作为类别的子页面)用于构建项目时,这在我的测试中引起了问题。这可能与 bug/feature #20933(启用在 CONTENT 中使用 SysFolders)有关。但记录可能具有可比性。我试过了,能够稍微缩短渲染时间(参见下面的 table)。
lib.myMenu.1.NO.stdWrap.cObject.20 = RECORDS
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = RECORDS
cObject{
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages.field = seo_title // title
}
}
}
}
CONTENT 而不是 HMENU: 如果不需要 sysfolders(从 TYPO3 10.4 起 sysfolders 也应该工作)
lib.myMenu.1.NO.stdWrap.cObject.20 = CONTENT
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = CONTENT
cObject{
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj.field = seo_title // title
}
}
}
}
userFunc 而不是 HMENU: Bernd Wilke 在他的回答中建议使用用户函数。即使这不是纯粹的 TypoScript 解决方案,我也很想测试它以便能够比较性能。不幸的是,方法 getRootLine() 有 been marked as deprecated。因为我不是扩展开发人员,所以我还不清楚如何通过 userFunc 读取类别以及这是否真的更有效。如果我仍然遇到关于这个的解决方案,它将添加在这里。
Rendertime: 我有 test-implemented 实时站点中的菜单(在现有模板中)并比较了有和没有类别输出的网站渲染时间查看嵌套菜单对性能的影响有多大。这些值是 10 次测量的平均值。我也限制了输出20个项目,这应该是以后每页更实际的价值:
mode
20 items
100 items
without category
99 ms
218 ms
categories via HMENU
133 ms
353 ms
categories via RECORDS
132 ms
331 ms
categories via CONTENT
121 ms
255 ms
categories via userFunc
TBD
TBD
您不应使用单独的 HMENU 或 userFunc,而应在 parent 级别的菜单项中使用简单的 LOAD_REGISTER。这会生成寄存器条目,可以在循环遍历 HMENU 结构的不同级别时添加、更改或恢复这些条目。
因此您不需要 PHP 函数的自定义代码,并且您不会受到嵌套 HMENU 的性能损失。
基本上它显示在官方文档中,但带有 CSS class 而不是标题。但是当然你可以用同样的方法将 parent 中的其他信息传递给它的 children。
示例如下:
10 = COA
10 {
### left menu table column
10 = LOAD_REGISTER
10 {
ulClass = col-left
}
### right menu table column
20 = LOAD_REGISTER
20 {
ulClass = col-right
}
30 = HMENU
30 {
special = list
special.value = 1
1 = TMENU
# ...
3 = TMENU
3 {
stdWrap {
preCObject = COA
preCObject {
10 = RESTORE_REGISTER
}
dataWrap = <ul class="{register:ulClass}">|</ul>
}
wrap =
SPC = 1
SPC {
allStdWrap {
replacement {
10 {
search = ---
replace =
}
}
dataWrap = </ul>|<ul class="{register:ulClass}">
}
}
}
}
}
这里是完整文档页面的 link:
https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/UsingSetting/Register.html
我有一个菜单(带 special = updated
的 HMENU),它为我提供了来自 3 个类别的最新子页面和 sub-sub 页面。
后端的页面结构如下所示:
除了标题,我想输出相应类别的名称(parent 一级页面)。
这是我的 TypoScript 尝试:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category attempt-1">|</div>
special = rootline
special.range = 1|1
special.value.field = uid # does not work
1 = TMENU
1.NO.allWrap = |
}
30 = TEXT
30{
wrap = <div class="category attempt-2">|</div>
data = leveltitle : 1 # does not work as expected
}
}
}
}
}
不幸的是,它不起作用,因为……
special = rootline
不支持special.value
.data = leveltitle : 1
使用当前页面的 ID,而不是 TMENU 项目 ID。
有人有其他方法可以使用 TypoScript 获取相应类别的标题吗?
编辑:背景信息/需要做什么
我打算用这个菜单替换现有项目的新闻模块 ext:news。现在使用页面而不是新闻记录,并且此菜单创建列表视图。当然会添加一个TypoScript页面浏览器。
我不会重建完整的菜单项生成 (NO.doNotLinkIt = 1
)。
只需使用NO.after.cObject = COA
.
leveltitle : 1
如果你想要当前页面的标题是正确的。
如果显示根菜单也是一样的:它是为当前页面生成的。
如果你想要其他页面的levelfield,你需要自己构建它。
在打字错误中,您可能会使用用户函数。 (有一个核心函数用于获取给定页面 id 的根线)
如果您使用 FLUID 生成菜单,您可能会使用 viewhelper。 (您可能会从
ext:vhs
中的 this option of viewhelpermenu.directory
or this option of VHpage.breadCrumb
中得到启发。)
编辑:
您可以将需要的信息直接存储在pages
记录中。
向记录添加新字段(或使用任何未使用的字段)。
然后确保每个类别页面包含一些页面 TS_config:
TCADefaults.pages.<yourfield> = CategoryName
使用此配置,下面的每个新页面都会自动设置此值。
当然,您需要手动或通过一些手动查询为所有现有页面设置这些值。
如果要阻止编辑器更改此值,您需要使用 top-page 上的此 TSConfig 从编辑表单中删除该字段:
TCEForm.pages.<yourfield>.hide= 1
我找到了一个纯 TypoScript 解决方案,可能不是很优雅,但它有效:
lib.myMenu = HMENU
lib.myMenu {
special = updated
special{
value.field = 10,11,12
beginAtLevel = 1
limit = 99
}
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.cObject = COA
stdWrap.cObject {
10 = TEXT
10{
wrap = <h3>|</h3>
field = seo_title // title
typolink.parameter.field = uid
}
20 = HMENU
20{
wrap = <div class="category">|</div>
special = list
special.value.field = pid
1 = TMENU
1{
NO{
doNotLinkIt = 1
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = HMENU
cObject{
special = list
special.value.field = pid
1 = TMENU
1.NO.doNotLinkIt = 1
}
}
}
}
}
}
}
}
}
如果菜单要越过更多层次,覆盖当然必须嵌套得更深。
编辑 – 改进:
RECORDS 而不是 HMENU: Bernd Wilke 在评论中建议使用 CONTENT 而不是 HMENU 来生成类别标题。当系统文件夹(作为类别的子页面)用于构建项目时,这在我的测试中引起了问题。这可能与 bug/feature #20933(启用在 CONTENT 中使用 SysFolders)有关。但记录可能具有可比性。我试过了,能够稍微缩短渲染时间(参见下面的 table)。
lib.myMenu.1.NO.stdWrap.cObject.20 = RECORDS
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = RECORDS
cObject{
source.field = pid
tables = pages
conf.pages = TEXT
conf.pages.field = seo_title // title
}
}
}
}
CONTENT 而不是 HMENU: 如果不需要 sysfolders(从 TYPO3 10.4 起 sysfolders 也应该工作)
lib.myMenu.1.NO.stdWrap.cObject.20 = CONTENT
lib.myMenu.1.NO.stdWrap.cObject.20{
stdWrap.wrap = <div class="category">|</div>
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj {
field = seo_title // title
stdWrap.override{
# Overwrite it if we are not yet at the category level
if{
# The ID of the page parent to the categories ("Website") is 1618
equals = 1618
value.field = pid
negate = 1
}
cObject = CONTENT
cObject{
table = pages
select {
uidInList.field = pid
pidInList = 0
selectFields = uid, pid, seo_title, title
}
renderObj = TEXT
renderObj.field = seo_title // title
}
}
}
}
userFunc 而不是 HMENU: Bernd Wilke 在他的回答中建议使用用户函数。即使这不是纯粹的 TypoScript 解决方案,我也很想测试它以便能够比较性能。不幸的是,方法 getRootLine() 有 been marked as deprecated。因为我不是扩展开发人员,所以我还不清楚如何通过 userFunc 读取类别以及这是否真的更有效。如果我仍然遇到关于这个的解决方案,它将添加在这里。
Rendertime: 我有 test-implemented 实时站点中的菜单(在现有模板中)并比较了有和没有类别输出的网站渲染时间查看嵌套菜单对性能的影响有多大。这些值是 10 次测量的平均值。我也限制了输出20个项目,这应该是以后每页更实际的价值:
mode | 20 items | 100 items |
---|---|---|
without category | 99 ms | 218 ms |
categories via HMENU | 133 ms | 353 ms |
categories via RECORDS | 132 ms | 331 ms |
categories via CONTENT | 121 ms | 255 ms |
categories via userFunc | TBD | TBD |
您不应使用单独的 HMENU 或 userFunc,而应在 parent 级别的菜单项中使用简单的 LOAD_REGISTER。这会生成寄存器条目,可以在循环遍历 HMENU 结构的不同级别时添加、更改或恢复这些条目。
因此您不需要 PHP 函数的自定义代码,并且您不会受到嵌套 HMENU 的性能损失。
基本上它显示在官方文档中,但带有 CSS class 而不是标题。但是当然你可以用同样的方法将 parent 中的其他信息传递给它的 children。
示例如下:
10 = COA
10 {
### left menu table column
10 = LOAD_REGISTER
10 {
ulClass = col-left
}
### right menu table column
20 = LOAD_REGISTER
20 {
ulClass = col-right
}
30 = HMENU
30 {
special = list
special.value = 1
1 = TMENU
# ...
3 = TMENU
3 {
stdWrap {
preCObject = COA
preCObject {
10 = RESTORE_REGISTER
}
dataWrap = <ul class="{register:ulClass}">|</ul>
}
wrap =
SPC = 1
SPC {
allStdWrap {
replacement {
10 {
search = ---
replace =
}
}
dataWrap = </ul>|<ul class="{register:ulClass}">
}
}
}
}
}
这里是完整文档页面的 link: https://docs.typo3.org/m/typo3/reference-typoscript/master/en-us/UsingSetting/Register.html