Typoscript: HMENU render sub menu in parent element - typo3

By default the second level HMENU is rendered after the first element.
foo = HMENU
foo {
1 = TMENU
1.noBlur = 1
1.NO = 1
1.NO.expAll = 1
1.NO.wrap = <li class="second">|</li>
2 = TMENU
2.noBlur = 1
2.NO = 1
2.NO.wrap = <li class="second">|</li>
}
Default HTML :
<li>firstlevel 1</li>
<li class="second">secondlevel 1</li>
<li>firstlevel 2</li>
But what I want is :
<li>
firstlevel 1
<li class="second">secondlevel 1</li>
</li>
<li>firstlevel 2</li>
i.e. The second level is rendered inside the first, not after it. Any ideas appreciated!

You need to use:
1.NO.wrapItemAndSub
instead of:
1.NO.wrap
But you lack <ul> in your menu. It will not validate.
The proper menu should look smth like that:
foo = HMENU
foo {
1 = TMENU
1.wrap = <ul class="first">|</ul>
1.noBlur = 1
1.expAll = 1
1.NO.wrapItemAndSub = <li>|</li>
2 < .1
2.wrap = <ul class="second">|</ul>
}
Edit: Moved expAll from "1.NO" to "1"

Related

Count Childrens in a TYPOSCRIPT menu

i am wondering if there is a way in TYPOSCRIPT to count the childrens in a menu.
The output should be something like:
<ul class="ebene1" data-elements="4">
<li>Element 1</li>
<li>Element 2</li>
<li>Element 2</li>
<li>Element 2</li>
</ul>
My Code looks like this:
script.NAV = HMENU
script.NAV {
special = directory
special.value = 6
1 = TMENU
1 {
expAll = 1
noBlur = 1
wrap = <ul class="menu main" id="nav-main">|</ul>
NO = 1
NO.wrapItemAndSub = <li class="first element1">|</li> |*| <li class="element1">|</li> |*| <li class="last element1">|</li>
CUR = 1
CUR.wrapItemAndSub = <li class="first element1 current">|</li> |*| <li class="element1 current">|</li> |*| <li class="last element1 current">|</li>
...
Thanks, any help is really appreciated.
Use the register {register:count_MENUOBJ} like this should solve your problem.
1 = TMENU
1 {
NO = 1
NO {
wrapItemAndSub.insertData = 1
wrapItemAndSub = <li class="element-{register:count_MENUOBJ}">|</li>
}
}
Actually although that may be done as #Marcus showed (I believe that snippet works, didn't check) it is probably faster approach to us JavaScript for this; as easy as:
<ul class="ebene1">
<li>Element 1</li>
<li>Element 2</li>
<li>Element 3</li>
<li>Element X</li>
</ul>
<script>$('.ebene1').attr('data-elements', $('.menu > li').length);</script>
And CSS like:
.ebene1[data-elements="4"] {
background-color: yellow;
}
On the other hand...
If you have dynamic menu with unknown number of items, instead adding many CSS declarations like,
.ebene1[data-elements="3"] li {width: 33.333%;}
.ebene1[data-elements="4"] li {width: 25%;}
.ebene1[data-elements="5"] li {width: 20%;}
Avoid adding the data- attribute via JS and just change the width by calculating the correct value:
$('.ebene1 > li').css({width: 100 / $('.ebene1 > li').length + '%'});
You need the stdWrap function numrows. There you can add any table together with a select statement. Here is an example:
lib.countmenu = COA
lib.countmenu {
10 = HMENU
10.1 = TMENU
10.1 {
wrap = <ul>|</ul>
NO {
stdWrap.cObject = COA
stdWrap.cObject {
30 = TEXT
30.numRows.table = pages
30.numRows.select.pidInList.field = uid
30.numRows.select.where = nav_hide!=1 AND doktype!=5 AND doktype!=6
30.dataWrap = {field:title} [|]
}
wrapItemAndSub = <li>|</li>
}
}
}

TypoScript / Typo3 : How to use | to set the value more than once in the same wrapper?

How to put the same value inside {againTheSameValue} for the menu in TypoScript? I want the same value for both text of a-tag and href-value:
[eg: Home]
Here's my TypoScript:
lib.mainmenu = HMENU
lib.mainmenu {
entryLevel = 0
1 = TMENU
1{
wrap = <li class="hidden"></li><ul class="nav navbar-nav navbar-right"> | </ul>
noBlur = 1
NO = 1
NO {
#
# I want the href too have the same value as set by "|" for it's text
#
wrapItemAndSub = <li><a class="page-scroll" href="#">|</a></li>
doNotLinkIt = 1
stdWrap.htmlSpecialChars = 1
ATagTitle.field = title
ATagParams = class="page-scroll"
}
}
}
Please suggest.
You can play around with stdWrap and field:...:
wrapItemAndSub = <li><a class="page-scroll" href="#{field:title}">|</a></li>
wrapItemAndSub.insertData = 1
In case you want to manipulate your href attribute (e.g. make it lowercase), the code must be written the other way round:
wrapItemAndSub = <li><a class="page-scroll" href="#|">{field:title}</a></li>
wrapItemAndSub.insertData = 1
stdWrap.case = lower
As you see, you can't apply stdWrap to {field:...}, but you can swap positions in wrapItemAndSub and apply stdWrap to a menu item text.
Tested both variants under 7.3 - works.

Typoscript navigation with subpages

I am trying to implement my navigation with typoscript and I am having problems to understand how to wrap right.
I already have a base navigation with 1 level that is working fine.
Now I have pages that has subpages and other that don't have.
For the ones without subpages I want the behavior that I have now.
For the pages with subpages I want to add this as an dropdown menu.
The HTML code should look like this.
<ul class="nav">
<li class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Test0
<b class="caret"></b>
</a>
<ul class="dropdown-menu">
<li class="">DropwDownItem1</li>
</ul>
</li>
<li class="active">Test1</li>
<li>Test2</li>
<li>Test3</li>
</ul>
TypoScript:
lib.menu = HMENU
lib.menu {
special = list
special.value = 3,2
1 = TMENU
1 {
wrap = <ul class="nav">|</ul>
expAll = 1
NO.wrapItemAndSub = <li class="">|</li>
RO < .NO
RO = 1
CUR < .NO
CUR = 1
CUR.wrapItemAndSub = <li class="active">|</li>
ACT < .CUR
IFSUB = 1
IFSUB.wrapItemAndSub= <li class="dropdown">|</li>
IFSUB.ATagParams = class="dropdown-toggle" data-toggle="dropdown"
IFSUB.stdWrap.innerWrap= |<b class="caret"></b>
ACTIFSUB = 1
ACTIFSUB.wrapItemAndSub= <li class="dropdown">|</li>
ACTIFSUB.ATagParams = class="dropdown-toggle" data-toggle="dropdown"
ACTIFSUB.stdWrap.innerWrap= |<b class="caret"></b>
CURIFSUB = 1
CURIFSUB.wrapItemAndSub= <li class="dropdown">|</li>
CURIFSUB.ATagParams = class="dropdown-toggle" data-toggle="dropdown"
CURIFSUB.stdWrap.innerWrap= |<b class="caret"></b>
}
2 = TMENU
2 {
wrap = <ul class="dropdown-menu">|</ul>
expAll = 1
NO = 1
NO.wrapItemAndSub = <li>|</li>
}
}
//EDIT: I have changed the code but now when I click on an item in the dropdown menu the ul class="dropdown-menu" is wrapped two times and the dropdown isn't shown properly.
The option noBlur is removed since TYPO3 v6.0 and I read somewhere, that the RO state does something with javascript to show/hide the submenu - so I try not to use it. I rather do the showing/hiding via css.
I would've done it like this:
lib.menu = HMENU
lib.menu {
special = list
special.value = 3,2
1 = TMENU
1 {
expAll = 1
wrap = <ul class="nav">|</ul>
NO.wrapItemAndSub = <li>|</li>
CUR = 1
CUR.wrapItemAndSub = <li class="active">|</li>
ACT < .CUR
}
2 = TMENU
2 {
wrap = <ul>|</ul>
NO = 1
NO.wrapItemAndSub = <li>|</li>
}
}
Add the hover-effect via CSS:
.nav ul {
display: none;
}
.nav li:hover ul {
display: block;
}
The <ul> wrap of your subnavi should be around the TMENU. I don't think you need the ATagBeforeWrap as it only makes linkWrap within the <a> tag. So it should look like this (not tested):
lib.menu = HMENU
lib.menu {
special = list
special.value = 3,2
1 = TMENU
1 {
wrap = <ul class="nav">|</ul>
expAll = 1
NO.wrapItemAndSub = <li class="">|</li>
RO < .NO
RO = 1
CUR < .NO
CUR = 1
CUR.wrapItemAndSub = <li class="active">|</li>
ACT < .CUR
noBlur = 1
IFSUB = 1
IFSUB.wrapItemAndSub= <li class="dropdown">|</li>
}
2 = TMENU
2 {
wrap = <ul class="dropdown-menu">|</ul>
expAll = 1
noBlur = 1
NO = 1
NO.wrapItemAndSub = <li>|</li>
}
}
Here you can find good info about wraps, unfortunately it's in german: http://jweiland.net/typo3/typoscript/wrap-moeglichkeiten-und-hierarchie-in-menues.html
By the way: if you are using TYPO3 6+ the noBlur setting has been removed.
---> EDIT:
I shortened your code a little, but I really coudn't reproduce the problem. For me it's working fine. The li around the dropdown gets the dropdown class. But I don't see a duplicate of the <ul class="dropdown-menu">
special = list
special.value = 3,2
1 = TMENU
1 {
wrap = <ul class="nav">|</ul>
expAll = 1
NO = 1
NO.wrapItemAndSub = <li class="">|</li>
RO < .NO
CUR < .NO
CUR.wrapItemAndSub = <li class="active">|</li>
ACT < .CUR
IFSUB = 1
IFSUB.wrapItemAndSub= <li class="dropdown">|</li>
IFSUB.ATagParams = class="dropdown-toggle" data-toggle="dropdown"
IFSUB.stdWrap.innerWrap= |<b class="caret"></b>
ACTIFSUB < .IFSUB
CURIFSUB < .IFSUB
}
2 = TMENU
2 {
wrap = <ul class="dropdown-menu">|</ul>
expAll = 1
NO = 1
NO.wrapItemAndSub = <li>|</li>
}
This snippet I have used for internal page links:
I have used subtitle field for internal navigation.
for example:
<a href="#about>about</a>
Ourservice
menu.main_menu = HMENU
menu.main_menu {
#special = directory
#special.value = 2
1 = TMENU
1 {
wrap = <ul class="nav navbar-nav navbar-right">|</ul>
expAll = 1
noBlur = 1
NO = 1
NO {
doNotLinkIt = 1
allWrap.insertData = 1
allWrap = <li class="first menu-{field:uid}">|</li>
}
ACT < .NO
ACT {
ATagParams = class="active dropdown"
allWrap = <li class="active first menu-{field:uid}">|</li> |*| <li class="active menu-{field:uid}">|</li>
}
CUR < .NO
CUR {
ATagParams = class="parent_menu active"
allWrap = <li class="first active menu-{field:uid}">|</li> |*| <li class="active menu-{field:uid}">|</li>
}
}
}

Is there an ATagAfterWrap instead of ATagBeforeWrap or a wrapSubAndItem insted of wrapItemAndSub?

First of all I'm total newbie when it comes to Typoscript and just supposed to make some css adjustments to a page. However there is a small adjustment I'd like to make. Instead of this (the mentioned ATagBeforeWrap is used in this context):
<menulvl1>
<li>
<a>Menu-Lvl 1 Link</a>
<submenu>
<!--.... -->
</submenu>
</li>
</menulvl1>
Without ATagBeforeWrap (or set to 0), I read I would get this:
<li>
<a>
<submenu>
<!--.... -->
</submenu>
</a>
</li>
But what I want is this:
<li>
<submenu></submenu>
<a>Menu-Lvl 1Link</a>
</li>
EDIT:
This is the typoscript responsible for the rendering. Sorry for the mass of code:
# Copy basic menu object from TS template 'menu' so we don't have to repeat all that
#lib.menu.level2.wrap = TEXT
menu.top < menu.defaults
menu.top {
# Also show pages which have not-in-menu flag set in page properties
includeNotInMenu = 0
# Create a menu out of the pages specifically listed under special.value
special = directory
special.value = {$menu.top.pages}
entryLevel = 0
1 {
expAll = 1
wrap = <ul class="layer1">|</ul>
NO {
doNotShowLink = 0
wrapItemAndSub = <li class="first">|</li>|*|<li>|</li>|*|<li class="last">|</li>
ATagParams = class="layer1"
}
ACT{
wrapItemAndSub = <li class="first selected">|</li>|*|<li class="selected">|</li>|*|<li class="last selected">|</li>
ATagParams = class="layer1 active"
}
IFSUB < .NO
IFSUB.ATagParams = class="layer1"
CUR < .ACT
CUR.ATagParams = class="layer1 selected"
CURIFSUB < .ACT
CURIFSUB.ATagParams = class="layer1 selected"
}
2 < .1
2.wrap(
<div class="layer2" style="display:none;">
<div class="inner-wrapper">
)
#2.wrap.insertData = 1
2.NO.doNotLinkIt = 1
2.ACT.doNotLinkIt = 1
2.IFSUB.doNotLinkIt = 1
2.CUR.doNotLinkIt = 1
2.CURIFSUB.doNotLinkIt = 1
2.NO.wrapItemAndSub = <div class="layer2-col first">|</div>|*|<div class="layer2-col">|</div>|*|<div class="layer2-col last">|</div>
2.NO.ATagParams = class="layer2"
2.ACT.wrapItemAndSub = <div class="layer2-col first">|</div>|*|<div class="layer2-col">|</div>|*|<div class="layer2-col last">|</div>
2.ACT.ATagParams = class="layer2 selected"
2.IFSUB.wrapItemAndSub = <div class="layer2-col first">|</div>|*|<div class="layer2-col">|</div>|*|<div class="layer2-col last">|</div>
2.IFSUB.ATagParams = class="layer2"
2.CUR.wrapItemAndSub = <div class="layer2-col first">|</div>|*|<div class="layer2-col">|</div>|*|<div class="layer2-col last">|</div>
2.CUR.ATagParams = class="layer2 selected"
2.CURIFSUB.wrapItemAndSub = <div class="layer2-col first">|</div>|*|<div class="layer2-col">|</div>|*|<div class="layer2-col last">|</div>
2.CURIFSUB.ATagParams = class="layer2 selected"
2.NO.linkWrap = <span class="layer2-headline">|</span>
3 < .1
#3.NO.doNotLinkIt = 0
3.wrap = <ul class="layer2-wrap">|</ul>
3.NO.wrapItemAndSub = <li>|</li>
3.NO.ATagParams =
3.ACT.ATagParams = class="active"
3.IFSUB.ATagParams =
3.CUR.ATagParams = class="selected"
3.CURIFSUB.ATagParams = class="selected"
stdWrap.prepend.data = LLL:{$filepaths.l10n}:nav_top
}
and the defaults:
menu.defaults = HMENU
menu.defaults {
1 = TMENU
1 {
wrap = <ul>|</ul>
# Always unfold all sub-levels of the menu
expAll = 0
# Remove the (old) default behaviour which adds onfocus="blurLink(this);" to all links
noBlur = 1
# Define the normal state (not active, not selected) of menu items
# Using NO=1 to activate normal state is not necessary, but useful when copying
NO = 1
NO {
# Use the page title field the title property on the A-tag, but only if the navigation title is set
ATagTitle {
field = title
fieldRequired = nav_title
}
# Use the option-split feature to generate a different wrap for the last item on a level of the menu
# The last item on each level gets class="last" added for CSS styling purposes.
#
# See the TSref documentation for details about option split and other features:
# http://typo3.org/documentation/document-library/references/doc_core_tsref/current/
#wrapItemAndSub = <li class="first">|</li> |*| <li>|</li> |*| <li class="last">|</li>
wrapItemAndSub = <li>|</li>
# HTML-encode special characters according to the PHP-function htmlSpecialChars
stdWrap.htmlSpecialChars = 1
}
IFSUB = 1
IFSUB < .NO
IFSUB {
wrapItemAndSub = <li class="subpages">|</li>
ATagBeforeWrap = 1
}
# Copy properties of normal to active state, and then add a CSS class for styling
ACT = 1
ACT < .NO
ACT {
ATagParams = class="active"
}
# Copy properties of normal to current state, and then add a CSS class for styling
CUR = 1
CUR < .NO
CUR {
ATagParams = class="selected"
#wrapItemAndSub = <li class="selected">|</li>
}
CURIFSUB < .IFSUB
CURIFSUB {
ATagParams = class="selected"
}
}
2 < .1
3 < .2
stdWrap.prepend =< lib.srHint
}
Is this somehow possible?
I think the only way to do this is to use the before.cObject = HMENU and create a second menu based on the current value inside your wrap.

Typo3 - remove default target in external menu item

I have the below typoscript
lib.nav = HMENU
lib.nav {
wrap = <ul> | </ul>
1 = TMENU
1 {
expAll=1
NO {
|*| <ul><li> | </li></ul> |*| <ul><li> | </li></ul> || <ul><li class="last"> | </li></ul> |*|
wrapItemAndSub = |*| <li> | </li> |*| <li> | </li> || <li class="last"> | </li> |*|
stdWrap.cObject = CASE
stdWrap.cObject {
key.field = doktype
default = TEXT
default.field = title
default.typolink.parameter.data = field:uid
default.typolink.ATagBeforeWrap=0
3 < .default
3 {
stdWrap.htmlSpecialChars = 1
typolink {
parameter {
data >
dataWrap = http://{field:url}
}
}
}
}
doNotLinkIt = 1 # to avoid "<a>" repeated twice
subst_elementUid = 1
}
}
2 = TMENU
2 {
expAll=1
wrap = <ul> | </ul>
NO {
wrapItemAndSub = |*| <li> | </li> |*| <li> | </li> || <li> | </li> |*|
stdWrap.cObject = CASE
stdWrap.cObject {
key.field = doktype
default = TEXT
default.field = title
default.typolink.parameter.data = field:uid
default.typolink.ATagBeforeWrap=0
3 < .default
3 {
stdWrap.htmlSpecialChars = 1
typolink {
parameter {
data >
dataWrap = http://{field:url}
}
}
}
}
doNotLinkIt = 1 # to avoid "<a>" repeated twice
subst_elementUid = 1
}
}
}
Which seems to work well, however I have notice a slight glitch when I have an external url page in the nav. It generates the below code for an external url.
<ul>
<li>External Links
<ul>
<li><a target="_top" href="http://example.com/1">Example 1</a></li>
<li><a target="_top" href="http://example.com/2">Example 2</a></li>
<li><a target="_top" href="http://example.com/3">Example 3</a></li>
</ul>
</li>
</ul>
How do I remove this default setting? I want it to be configurable per page in the behaviour tab (link target field in LTS 4.5).
I also have the below set in my constants.
PAGE_TARGET =
content.pageFrameObj =
Set in setup the extTarget via config. It is default "_top".
# just set it to an empty string instead of _top
config.extTarget =