我正在尝试为Typo3网站创建一个JSON站点地图,然后我会在其他页面中使用它。
我已经取得了一些模仿JSON的东西,但我坚持一些事情:
所以问题是:有没有更好的方法呢?有没有人有一个扩展,将创建这样的JSON响应?有人可以弄明白,如何将子条目移动到cObject中,这样我就可以使用wrap函数来显示缺失的"},"?
TypoScript模板:
config.disableAllHeaderCode = 1
config.doctype = none
# set json header
config.additionalHeaders = Content-type:application/json
# keep typo3 from "tidying up" -> perfectly valid json
config.xhtml_cleaning = 0
# Delete and reset the page object
page = PAGE
# Page context
page.10 = HMENU
page.10 {
special = directory
// Page id of help
special.value = 33
1 = TMENU
1.expAll = 1
# wraps all entries (outer array)
1.wrap = [|]
1 {
noBlur = 1
# wraps only entires of 1 level, not the children entry
#NO.allWrap = {|},
NO.linkWrap = |
NO.ATagBeforeWrap = 0
NO.doNotLinkIt = 1
NO.stdWrap.htmlSpecialChars = 0
NO.stdWrap.cObject = COA
NO.stdWrap.cObject {
# gamekey/translation key taken from the abstract
5 = TEXT
5.value = {
10 = TEXT
10 {
field = abstract
htmlSpecialChars = 1
wrap = "key":"|",
}
# Link
20 = TEXT
20 {
field = uid
htmlSpecialChars = 1
wrap = "link":"/|"
typolink.parameter.field = uid
typolink.returnLast = url
}
}
}
2 < .1
2.wrap = ,"children": [|]}
}
输出:
[
{"key":"page_a","link":"/de/a.html"
{"key":"page_b","link":"/de/b.html","children":
[
{"key":"page_c","link":"/de/c.html"
{"key":"page_d","link":"/de/d.html"
{"key":"page_e","link":"/de/e.html"
]}
{"key":"page_f","link":"/de/f.html","children":
[
{"key":"page_g","link":"/de/content/g.html"
]
}
]
解决方案(有效的json):
lib.header >
config.disableAllHeaderCode = 1
config.doctype = none
# set json header
config.additionalHeaders = Content-type:application/json
# keep typo3 from "tidying up" -> perfectly valid json
config.xhtml_cleaning = 0
# Delete and reset the page object
page = PAGE
# Page context
page.10 = HMENU
page.10 {
special = directory
// Page id of help
special.value = 576
}
page.10.1 = TMENU
page.10.1 {
expAll = 1
noBlur = 1
wrap = [|]
NO {
wrapItemAndSub = {|}, |*| {|}, |*| {|}
linkWrap = |
ATagBeforeWrap = 0
doNotLinkIt = 1
stdWrap.htmlSpecialChars = 0
stdWrap.cObject = COA
stdWrap.cObject {
# gamekey/translation key taken from the abstract
10 = TEXT
10 {
field = title
htmlSpecialChars = 1
wrap = "title":"|",
}
# Link
20 = TEXT
20 {
field = uid
htmlSpecialChars = 1
wrap = "uri":"/|",
typolink.parameter.field = uid
typolink.returnLast = url
}
}
}
}
# second layer is a bit different
page.10.2 = TMENU
page.10.2 {
expAll = 1
noBlur = 1
wrap = |
stdWrap.wrap = "children": [|]
NO {
wrapItemAndSub = {|}, |*| {|}, |*| {|}
linkWrap = |
ATagBeforeWrap = 0
doNotLinkIt = 1
stdWrap.htmlSpecialChars = 0
stdWrap.cObject = COA
stdWrap.cObject {
# gamekey/translation key taken from the abstract
10 = TEXT
10 {
field = title
htmlSpecialChars = 1
wrap = "title":"|",
}
# Link
20 = TEXT
20 {
field = uid
htmlSpecialChars = 1
wrap = "uri":"/|"
typolink.parameter.field = uid
typolink.returnLast = url
}
}
}
IFSUB = 1
IFSUB {
wrapItemAndSub = {|}, |*| {|}, |*| {|}
linkWrap = |
ATagBeforeWrap = 0
doNotLinkIt = 1
stdWrap.htmlSpecialChars = 0
stdWrap.cObject = COA
stdWrap.cObject {
# gamekey/translation key taken from the abstract
10 = TEXT
10 {
field = title
htmlSpecialChars = 1
wrap = "title":"|",
}
# Link
20 = TEXT
20 {
field = uid
htmlSpecialChars = 1
wrap = "uri":"/|",
typolink.parameter.field = uid
typolink.returnLast = url
}
}
}
}
# All further sub levels are like levels 2
page.10.3 < page.10.2
page.10.4 < page.10.3
请注意,如果第1级节点没有子节点,则必须包含另一个IFSUB。就我而言,这是不可能的。
答案 0 :(得分:2)
对于菜单创建,请查看wrapItemAndSub
,它可以帮助您将父元素包裹在子元素周围。
可以在CheatSheet corner找到有关可用包装的详细概述。具体来说,您可以查看stdWrap菜单备忘单(Direct link)。
此外,请查看不同的菜单状态,尤其是IFSUB
,以检测是否有任何子项。
你必须在这里应用一些反向逻辑。更具体的状态首先匹配,否则您将回退到NO
。因此,如果您想对无子女条件做出反应,那么您必须将正常设置设为IFSUB
并使用NO
作为无子女案例。
答案 1 :(得分:1)
# Menu as JSON
menuJSON = PAGE
# create absolute urls
menuJSON.config.absRefPrefix = https://www.yourdomain.com/
menuJSON {
typeNum = 2342
config {
disableAllHeaderCode = 1
doctype = none
# set json header
additionalHeaders = Content-type:application/json
# disable debug for valid json
debug = 0
# disable xhtml cleaning for valid json
xhtml_cleanin = 0
# TODO: disable in production
no_cache = 1
}
10 = HMENU
10 {
special = directory
special.value = 1
special.depth = 4
special.forceAbsoluteUrl = 1
1 = TMENU
1 {
expAll = 1
noBlur = 1
wrap = [|]
NO {
wrapItemAndSub = {|}, |*| {|}, |*| {|}
linkWrap = |
ATagBeforeWrap = 0
doNotLinkIt = 1
stdWrap.htmlSpecialChars = 0
stdWrap.cObject = COA
stdWrap.cObject {
# gamekey/translation key taken from the abstract
10 = TEXT
10 {
field = title
htmlSpecialChars = 1
wrap = "title":"|",
}
# Link
20 = TEXT
20 {
field = uid
htmlSpecialChars = 1
wrap = "uri":"|"
typolink.parameter.field = uid
typolink.returnLast = url
}
}
}
# same as NO but with , after the uri
IFSUB < .NO
IFSUB = 1
IFSUB {
stdWrap.cObject {
20 {
wrap = "uri":"|",
}
}
}
}
# second layer is a bit different
2 < .1
2 {
wrap = |
stdWrap.wrap = "children": [|]
}
# All further sub levels are like levels 2
3 < .2
4 < .3
5 < .4
6 < .5
7 < .6
8 < .7
# last layer has no children
8.IFSUB = 0
}
}
答案 2 :(得分:0)
您可以使用t3lib_pageSelect来获取页面菜单。只需在控制器操作中创建一个新实例,并给rootnode构建菜单。
/**
* fetchNavigationTree
*
* @param integer $rootPage
* @param array $pageTree
* @return string
*/
protected function fetchNavigationTree($rootPage, $pageTree = array()) {
$this->pageSelect = t3lib_div::makeInstance('t3lib_pageSelect');
$this->pageSelect->init(false);
$pageTree = $this->pageSelect->getMenu(
$rootPage,
'uid, pid, title, doktype, url, subtitle, description, media, nav_hide, subtitle',
'sorting',
'AND nav_hide = 0',
0
);
foreach($pageTree as &$page) {
$page['subPages'] = $this->fetchNavigationTree($page['uid'], $pageTree);
if(empty($page['subPages']) || $page['subPages'] == null) {
unset($page['subPages']);
}
}
return $pageTree;
}