I need a drop-down menu that is a first level and second level menu. If you click example first menu item then this sub-menu is opening. First level must open in header section and second level must open in content section. Example is below. I can do to this when everything is one header section, but I don't know how to make it if sub-menu must be in another section.
Header section begin
Logo Menu link 1 Menu link 2 Menu link 3
Header section end
Content section begin
If cliked any menulink in above, then this item submenu opening here
...
Section end
<header id="section-header" class="section-header">
<div id="zone-header-wrapper" class="zone-header-wrapper">
<div class="menu-block-wrapper>
<ul class="menu">
<li class="first leaf menu-mlid">..<li>
<ul>
</div>
</div>
</header>
<section id="section-content" class="section-content">
<div id="zone-content-wrapper" class="zone-content-wrapper">
<div class="menu-block-wrapper>
<ul class="submenu">
<li class="first leaf menu-mlid">..<li>
</ul>
</div>
</div>
So far I have first level menu code below.
lib.mainNavi = HMENU
lib.mainNavi.entryLevel = 1
lib.mainNavi.1 = TMENU
lib.mainNavi.1 {
wrap = <ul class="menu">|</ul>
expAll = 0
NO.allWrap = <li class="first leaf menu-mlid">|</li>|*|<li class="expanded leaf menu-mlid">|<li>|*|<li class="has-separator leaf menu-mlid">|</li>
NO.ATagParams = |*| |*| class="has-separator"
}
Thank you for you answers!
You can render your submenu with typosript like you did with your main menu.
lib.submenu = HMENU
lib.submenu {
special = directory
special.value.data = leveluid:1
entryLevel = 1
1 = TMENU
1 {
...
}
}
From TSREF:
A HMENU of type special = directory lets you create a menu listing the subpages of one or more parent pages. The parent pages are defined in the property ".value".
So this will render you the subpages of the page you navigated to with your main menu, regardless where in its subpages you are. You can configure this to behave different of course.
Related
I want to create a popup menu with content elements of the items.
The structure in the backend is basically as follows:
Menu1
Submenu1.1
Submenu1.2
Submenu1.3
Menu2
Submenu2.1
Submenu2.2
Submenu2.3
Where Menu1 and Menu2 have content elements on the page.
I managed to access the content elements, however, the elements are rendered BEFORE the sub menu items. I need them after that.
What I get:
<div class="headeroverlay">
<div class="dropdown-overlay" id="overlay_4">
<!-- CONTENT ELEMENTS -->
<div class="contentimagesandtext">
<div class="item"><!-- Content Element 1 of Menu 1 --></div>
<div class="item"><!-- Content Element 2 of Menu 1 --></div>
</div>
<!-- SUB MENU -->
<div class="subnav-block">
<div class="subnav-link">Submenu1.1</div>
<div class="subnav-link">Submenu1.2</div>
<div class="subnav-link">Submenu1.3</div>
</div>
</div>
<div class="dropdown-overlay topdropdown" id="overlay_5">
<!-- same for Menu 2 -->
</div>
</div>
But I need content and submenu switched:
<div class="headeroverlay">
<div class="dropdown-overlay" id="overlay_4">
<!-- SUB MENU -->
<div class="subnav-block">
<div class="subnav-link">Submenu1.1</div>
<div class="subnav-link">Submenu1.2</div>
<div class="subnav-link">Submenu1.3</div>
</div>
<!-- CONTENT ELEMENTS -->
<div class="contentimagesandtext">
<div class="item"><!-- Content Element 1 of Menu 1 --></div>
<div class="item"><!-- Content Element 2 of Menu 1 --></div>
</div>
</div>
<div class="dropdown-overlay topdropdown" id="overlay_5">
<!-- same for Menu 2 -->
</div>
</div>
Here's my script so far:
lib.menuOverlay = HMENU
lib.menuOverlay{
1 = TMENU
1.expAll = 1
1.NO.doNotShowLink = 1
1.NO.wrapItemAndSub = <div class="dropdown-overlay topdropdown" id="overlay_{field:uid}">|</div>
1.NO.wrapItemAndSub.insertData = 1
# Append Content Elements to stdWrap2
1.NO.stdWrap2.append = CONTENT
1.NO.stdWrap2.append {
table = tt_content
select {
pidInList.stdWrap.data = field:uid
}
wrap = <div class="contentimagesandtext">|</div>
renderObj.stdWrap.wrap = <div class="item">|</div>
}
2 = TMENU
2.insertData = 1
2.wrap = <div class="subnav-block">|</div>
2.NO.wrapItemAndSub = <div class="subnav-link">|</div>
}
I tried adding the append to wrapItemAndSub. This will put the content elements after the submenus, but then I don't have a wrapper keeping them togehter.
Note that I need the Level-1 Page UID in the id tag of the wrapper
Question: How can I force the append to be AFTER the items, or alternatively, how can I add a wrapper around my wrapItemsAndSub, containing the parent UID?
you should care for your wraps.
you use stdWrap2 where you append your content. The append wraps the wrap-string of stdWrap2(which is empty), leaving the append the only value for stdWrap2.
now stdWrap2 has no marker where to split the wrap in before and after. So everything goes before the wrapped content. You need a split-marker in stdWrap2:
stdWrap2 = |
stdWrap2.append = ...
on the other side: you could use append as the only wrapping to get its value after the content.
Inspired by this answer, I managed to do what I need.
I append a COA to my first level menu, and put there the CONTENT and another HMENU with the sub-menu items, like this:
lib.menuOverlay = HMENU
lib.menuOverlay {
1 = TMENU
1.expAll = 1
1.NO.doNotShowLink = 1
1.NO.wrapItemAndSub = <div class="dropdown-overlay topdropdown" id="overlay_{field:uid}">|</div>
1.NO.wrapItemAndSub.insertData = 1
1.NO.stdWrap2.append = COA
1.NO.stdWrap2.append {
10 = HMENU
10 {
special = directory
special.value.data = field:uid
1 = TMENU
1.insertData = 1
1.wrap = <div class="subnav-block">|</div>
1.NO.wrapItemAndSub = <div class="subnav-link">|</div>
}
20 = CONTENT
20 {
table = tt_content
select {
pidInList.stdWrap.data = field:uid
}
wrap = <div class="contentimagesandtext">|</div>
renderObj.stdWrap.wrap = <div class="item">|</div>
}
}
}
I am trying to build a menu with typoscript, in which the 2nd level differs depending on the 1st level menu items - this is what I've tried so far, but it doesn't work as wanted:
lib.mainnav = HMENU
lib.mainnav {
wrap = <ul id="nv-main">|<li class="responav"><i class="fas fa-bars"></i></li></ul>
1 = TMENU
1 {
expAll = 1
NO = 1
NO.wrapItemAndSub = <li>|</li>
NO.stdWrap.htmlSpecialChars = 1
CUR = 1
CUR.wrapItemAndSub = <li class="current">|</li>
CUR.stdWrap.htmlSpecialChars = 1
}
# von 1 (TMENU) kopieren
2 < .1
2 {
expAll = 1
wrap = <div class="nv-main-sub-bg"><div class="nv-main-sub-wrapper clearfix">|</div></div>
wrap.override = <div class="nv-main-sub-bg"><div class="nv-main-sub-wrapper indented clearfix">|</div></div>
wrap.override.if {
value = 6
equals.data = page:uid
}
stdWrap.cObject = COA
stdWrap.cObject {
20 = HMENU
20 {
special = directory
special.value.data = field:pid
1 = TMENU
1 {
wrap = <div class="nv-main-col-sub"><ul>|</ul></div>
NO = 1
NO.allWrap = <li>|</li>
NO.stdWrap.htmlSpecialChars = 1
NO.after.cObject = COA
NO.after.cObject {
wrap = <div class="nv-main-info-wrapper"><div class="nv-main-col-info">|</div></div>
# Text aus dem Feld subtitle oder title der Seiteneigenschaften auslesen
10 = TEXT
10 {
value.field = subtitle // title
stdWrap.wrap = <p>|</p>
}
# Bild aus Reiter Resourcen der Seiteneigenschaften auslesen (nur bei Page-UID 4)
20 = FILES
20 {
if.value.field = pid
if.equals = 4
references {
table = pages
# Seiten-ID
uid.dataWrap= {field:uid}
fieldName = media
}
renderObj = IMAGE
renderObj {
file.width = 290c
file.height = 200c
file.import.data = file:current:uid
file.crop.data = file:current:crop
file.treatIdAsReference = 1
altText.data = file:current:title
##params = class="img-responsive"
wrap = |
}
}
# Text aus dem Feld "abstract" auslesen (nur bei Page-UID 6)
30 = TEXT
30 {
if.equals.field = pid
if.value = 6
value.field = abstract
stdWrap.wrap = <p class="b-sub">|</p>
}
}
CUR < .NO
CUR.allWrap = <li class="current">|</li>
}
}
}
}
}
This will create a 2-level-menu, where the 2nd level is a combination of the menu items each with a text info and a picture which already works. What I want is a different 2nd-level menu depending on the selected 1st level item. For this I need to change the wrapping and replace the image by additional text.
Can you please give me a hint? Thank you very much for your help!
Michael
EDIT:
Typo3 V. 8.7.16
Page Tree:
Item 1
-- Subitem 1 **with text and picture**
-- Subitem 2 **with text and picture**
-- Subitem 3 **with text and picture**
-- ...
-- Subitem XX **with text and picture**
Item 2
-- Subitem 1 **with text and picture**
-- Subitem 2 **with text and picture**
-- Subitem 3 **with text and picture**
-- ...
-- Subitem XX **with text and picture**
Item 3
-- Subitem 1 **only with text** (headline and copytext)
-- Subitem 2 **only with text** (headline and copytext)
-- Subitem 3 **only with text** (headline and copytext)
-- ...
-- Subitem XX **only with text** (headline and copytext)
Item 4
-- Subitem 1 ...
-- ...
Item 5
-- Subitem 1 ...
-- ...
HTML-structure:
<ul id="nv-main">
<li>
Item 1
<div class="nv-main-sub-bg">
<div class="nv-main-sub-wrapper clearfix">
<div class="nv-main-col-sub">
<ul>
<li>
Subitem 1 ** with text and picture **
<div class="nv-main-info-wrapper">
<div class="nv-main-col-info">
<p>XXX</p> <!— from title/subtitle —>
<img src=„XXX“ border="0"> <!— from Resources —>
</div>
</div>
</li>
<li> … </li>
<li> … </li>
<li> … </li>
…
</ul>
</div>
</div>
</div>
</li>
<li> … </li>
<li>
Item 3
<div class="nv-main-sub-bg">
<div class="nv-main-sub-wrapper **indented** clearfix">
<div class="nv-main-col-sub">
<ul>
<li>
Subitem 1 ** only with text **
<div class="nv-main-info-wrapper">
<div class="nv-main-col-info">
<p class="b-head">XXX</p> <!— from title/subtitle —>
<p class="b-sub">XXX</p> <!— from abstract —>
</div>
</div>
</li>
<li> … </li>
<li> … </li>
<li> … </li>
…
</ul>
</div>
</div>
</div>
</li>
<li> … </li>
<li> … </li>
</ul>
One solution would be to render all information for the second level and decide by CSS which parts will be shown (depending on a matching class set on the first level by a property of the level one page)
The other way would be (as Joey mentioned): build your .after object depending on the pid of the current page. either you have a list of pages, which have the special rendering 'only with text' or (more complicated) you use the pid to access a property of the level one page which indicates this special rendering.
The easy solution with a list of page uids could be:
2.after.cObject = CASE
2.after.cObject {
key.field = pid
default = COA
default {
// rendering of **with text and picture**
}
// uid of level1 page
123 = COA
123 {
// rendering of **only with text**
}
// alternative level1 page with this rendering:
234 < .123
}
If your option **only with text** means the same as **with text and picture** just without the picture you can modify your existing code (which seems very complictaed using the HMENU with special=directory) to blank the the picture:
NO.after.cObject.20.if {
isInList.field = pid
// store pages uids in constant like: 1,2,34,50,87
value = {$specialPagesUidsList}
negate = 1
}
I recently had a similar problem.
Second and third level navigation had to be the depending to the chosen item of the first level.
Do you need to have the second leven nested into the active item?
<ul class="first-level">
<li>item 1</li>
<li>item 2
<ul class="second-level">
<li>item 3</li>
</li>
</ul>
or could you handle a structure like this?
<ul class="first-level">
<li>item 1</li>
<li>item 2</li>
</ul>
<ul class="second-level">
<li>item 3</li>
</ul>
Usually dealing with the "position" within a menu is a job for option split, but this would need a completely rewritten second level, since it had to be put to the "after" part of the first level items.
But since the behaviour of a submenu is actually determined by the parent page it belongs to and not just by the position this parent page has got within the first level of the menu, you should go for a specific PID value instead of the position.
You can use "if" or a "cObject" CASE for that purpose, so that the second level can be changed based on the pid value of its items.
Can I execute that line of code
nav = request().path().toString()
inside of scala template like index.scala.html
I would like to have that code to check on witch side is user and to mark it on menu
using code like this in main.scala.html:
<li class="#("active".when(nav == "contact"))">
Contacts
</li>
I would recommend you different approach, create tag - resuable template, which takes Integer as an argument,
it will render menu and mark as an active different menuitem depends on value.
#(menuItem: Int)
<ul >
<li #if(menuItem==1){ class="active" } >
////
</li>
<li #if(menuItem==2){ class="active" }>
</li>
<li #if(menuItem==3){ class="active" }>
///
</li>
</ul>
from your contact page and any other page, call this tag with corresponding value, #views.html.tags.menu(1)
You can define variables like that if that is your question. If it is not your question than please try to explain your problem in more detail.
#nav = { #request().path().toString() }
I have a header menu and try to define different CSS classes for each item.
This is what I have:
20 = HMENU
20 {
special = directory
special.value = 107
1 = TMENU
1 {
wrap = <ul class="foo" id="mymenu">|</ul>
expAll = 1
NO = 1
NO.allWrap = <li class="first menu_{field:uid}">|</li> || <li class="menu_{field:uid}">|</li> || <li class="last menu_{field:uid}">|</li>
}
}
But in the HTML output I simply get class="first menu_{field:uid}" and nothing is replaced.
By the way: The page entries in the menu are links to external pages.
EDIT:
As our designer complained about the non-speaking class IDs we are abusing the body-class attribute now:
NO.allWrap = <li class="first {field:bodyclass_wrap_class}">|</li> || <li class="{field:bodyclass_wrap_class}">|</li> || <li class="last {field:bodyclass_wrap_class}">|</li>
You have to add NO.allWrap.insertData = 1, then the data will be inserted. allWrap is just a normal stdWrap, so the default features apply there.
BTW: I think your option split is still wrong. I guess you want to have it like this:
NO.allWrap = <li class="first menu_{field:uid}">|</li> |*| <li class="menu_{field:uid}">|</li> |*| <li class="last menu_{field:uid}">|</li>
I dont come forth. I want to wrap each given PID in its own unique wrap.
Here my code:
menutab.list = HMENU
menutab.list.special = directory
menutab.list.special.value = 7,8,9,10,11,12,13
menutab.list.1 = TMENU
menutab.list.1.wrap = <div>|</div>
...
So thats working fine. I get every submenu of given PIDs but now i'm searching for something like that:
menutab.list.special.value.wrap = <div id="current PID!"> | </div>
I hope someone understand my issue.
Big thanks!!
It depends which field you would like to display, but basically any field from the page record can be displayed into the output.
menutab.list = HMENU
menutab.list {
special = directory
special.value = 7,8,9,10,11,12,13
1 = TMENU
1 {
# stdWrap2 wraps the whole item, including the link
NO.stdWrap2.dataWrap = <div id="p{field:uid}">|</div>
}
}
This will give the following output:
<div id="p26">Test 0</div>
<div id="p27">Test 1</div>
<div id="p30">Test 2</div>
<div id="p31">Test 3</div>
<div id="p35">Test 4</div>
<div id="p36">Test 5</div>
<div id="p37">Test 6</div>
For more options, please take a look at the TSref and the stdWrap functions.
TSref
http://typo3.org/documentation/document-library/references/doc_core_tsref/4.4.0/view/toc/0/
stdWrap
http://typo3.org/documentation/document-library/references/doc_core_tsref/4.4.0/view/1/5/#id2618234
I think the easiest is to do something like that, not sure of the syntax... :
menutab.list.1 = HMENU
menutab.list.1 {
special = directory
special.value = 7
1 = TMENU
1.wrap = <div id="7"> | </div>
}
menutab.list.2 < menutab.list.1
menutab.list.2.special.value = 8
menutab.list.2.1.wrap = <div id="8"> | </div>
...
Not the best solution, but can work