Getting Pagecontent in HMENU - typo3

i'm creating a menu with HMENU in Typoscript. Now my question: is there a possibility to check if the linked paged as any content. if it has none how can i disable the link?
i'm generate the menu with the following code
NAV = HMENU
NAV{
entryLevel = 0
wrap = <ul class="nav">|</ul>
1 = TMENU
1.NO {
allWrap = <li class="nav-button"><p class="title">|</p></li>
}
1.ACT = 1
1.ACT {
allWrap = <li class="nav-button selected"><p class="title">|</p></li>
}
}

Untested!
You can check with numRows if there is any tt_content record on that page (you can use WHERE if you want to check only specific records). With required you define, that this menu item will only be rendered if numRows is greater then 1.
NAV.1.NO.allStdWrap.required.numRows {
table = tt_content
select {
# uid of this page, is the pid of the records to look for
pidInList.field = uid
}
}
NAV.1.ACT.allStdWrap < NAV.1.NO.allStdWrap

Related

HMENU: How to wrap page content into my menu?

I would like to build a full with dropdown menu based on page content defined into a folder.
The idea is to have:
MENU (folder)
- menu 1 (page)
- menu 2 (page)
My goal is to get the following output:
menu 1 content in menu 1 page
menu 2 content in menu 2 page
There is only one content bloc in the pages.
No problem to get the li with menu 1 / 2 but I cannotfind the way to get and wrap the page content.
My code looks like
menu.nav = HMENU
menu.nav {
special = directory
special.value = 214
entryLevel = 1
1 = TMENU
1.wrap = <ul>|</ul>
1.expAll = 1
1.NO = 1
1.NO.wrapItemAndSub.cObject = TEXT
1.NO.wrapItemAndSub.cObject.value = <li>|</ul></li>
1.NO.after.cObject = COA
1.NO.after.cObject {
10 = TEXT
10.value = <div class="dropdown">
20 = CONTENT
20 {
table = tt_content
select {
....
but I cannot figure out what is required here to get the content of the pages.
Does someone can help me with this issue?
Thanks in advance.
Regards
Joël
I'll try a solution here, hoping that I'm not simplifying too much your code,at least you could take it as a starting point:
menu.nav = HMENU
menu.nav {
special = directory
special.value = 214
1 = TMENU
1.wrap = <ul>|</ul>
1.NO {
wrapItemAndSub = <li>|</li>
after.cObject = CONTENT
after.cObject {
table = tt_content
select {
pidInList.field = uid
where = {#colPos} = 0
}
renderObj = < tt_content
wrap = <div class="dropdown">|</div>
}
}
}
I took this one as starting point.
I had a similar problem sometime ago, came upwith this code to make a menu containing database information.
It is not an answer, but it is a similar piece of code. Hopefully it gives you an idea.
It generates a list of links to pages which have "no_search" = 0 or another condition. There is also a database join made to get the pagepath or url of pages in the site.
Think you can do the same thing with your page content, output it as html.
lib.sitemap = CONTENT
lib.sitemap {
table = pages
select {
orderBy = pages.sorting
selectFields = pages.uid, pages.title, tx_realurl_pathcache.pagepath
join = tx_realurl_pathcache ON tx_realurl_pathcache.page_id=pages.uid
pidInList = 44
recursive = 7
where = (no_search="0") or (nav_hide=1 and no_search=0)
groupBy = tx_realurl_pathcache.page_id
}
renderObj = COA
renderObj.wrap = <li>|</li>
renderObj.10 = TEXT
renderObj.10 {
field = pagepath
wrap = <a href="|">
}
renderObj.20 = TEXT
renderObj.20.field = title
renderObj.30 = TEXT
renderObj.30.value = </a>
}
lib.sitemap.wrap = <ul> | </ul>
You have to do this
lib.navbar2 = COA
lib.navbar2.wrap = <nav>|</nav>
lib.navbar2 {
20 = HMENU
20.wrap = <ul>|</ul>
20 {
#entryLevel = 0
#excludeUidList = 11,12
1 = TMENU
1 {
wrap = |
expAll = 1
NO = 1
NO.allWrap >
NO.wrapItemAndSub = <li>|</li>
NO.after.cObject = COA
NO.after.cObject{
stdWrap.wrap = <div class="megamenu-wrapper">|</div>
20 = CONTENT
20 {
table = tt_content
select {
pidInList.field = uid
orderBy = sorting
where = colPos=4
languageField=sys_language_uid
}
}
20.wrap = |
}
ACT = 1
ACT < .NO
ACT.wrapItemAndSub = <li class="active">|</li>
CUR = 1
CUR < .NO
CUR.wrapItemAndSub = <li class="active">|</li>
}
}
}

TYPO3 hmenu disable one link

I have menu with 2 level. All links are clickable but I want to disable 1 link. This link is being used for opening submenu
<li class="sub-link">link1
<ul id="sub-menu">
<li>sublink</li>
<li>sublink2</li>
</ul> <!-- sub-menu -->
</li>
<li>link2</li>
<li>link3</li>
<li>link4</li>
<li>link5</li>
I want to disable link 1. I have such typoscript:
lib.menu.main = HMENU
lib.menu.main {
special = list
special.value = 22,154,88
alwaysActivePIDlist = 22
1 = TMENU
1.NO = 1
1.wrap = <ul>|</ul>
1.NO.wrapItemAndSub = <li>|</li>
1.IFSUB=1
1.IFSUB.wrapItemAndSub = <li class="sub-link">|</li>
2 < .1
2.wrap = <ul id="sub-menu">|</ul>
2.NO.wrapItemAndSub = <li>|</li>
}
How I can decide this problem?
So i got two possibilities for you to solve this problem:
The first one is to read the Typo3-Documentation and look up for "optionSplit" and "doNotLinkIt"-options. They should help you solving your problem within typoscript.
The other is to solve it using Javascript/JQuery. You could select the (in your example above) FIRST item of the menu and replace the link with whatever you want.
$(document).ready(function(){
$('.menu a').first().attr('href', '#');
});
I made you a fiddle with the whole example:
https://jsfiddle.net/bdrsssv7/
Make sure you do not insert the Javascript in the HTML template because it will not be available on pages with other html-templates then.
Just do a js-file and insert it via typoscript like this:
page.includeJS.file1 = fileadmin/yourTemplateLocation/yourFile.js
I hope one of the two solutions i mentioned could help you
Excluding a specific PID (18) from the menu in Typoscript:
lib.menu = HMENU
lib.menu {
special = rootline
special.range = 2,0
1 = TMENU
1 {
NO {
allWrap = <li> | </li>
doNotLinkIt.override = 1
doNotLinkIt.override.if {
value = 18
equals.field = uid
}
}
}
}
OR exclude multiple specific PIDs (18,19,20) from the menu
lib.menu.1.NO.doNotLinkIt.override.if {
value = 18,19,20
isInList.field = uid
}

Id counting in TYPO3 menu using register:count_MENUOBJ

I made the menu in TYPO3 for bootstrap framework. Everything working just fine, but I have problem with counting the id element using register:count_MENUOBJ. The whole menu is constructed from two parts - main menu and sub menu:
page = PAGE
page.10 = HMENU
page.10.special = directory
page.10.entryLevel = 0
page.10.maxItems = 6
page.10 {
1 = TMENU
1 {
wrap = <div class="row"><ul class="nav nav-tabs pull-right" id="myTab" role="tablist">|</ul></div>
noBlur = 1
expAll = 1
NO {
ATagTitle.field = title
wrapItemAndSub = <li class="dropdown">|</li>
stdWrap.htmlSpecialChars = 1
accessKey = 1
}
IFSUB < .NO
IFSUB = 1
IFSUB {
wrapItemAndSub = <li class="dropdown">|</li>
linkWrap= |
ATagParams = role="button" data-toggle="collapse" data-target="#item-{register:count_MENUOBJ}"
ATagParams.insertData = 1
ATagBeforeWrap = 1
stdWrap.htmlSpecialChars = 1
}
ACTIFSUB < .IFSUB
ACTIFSUB {
wrapItemAndSub = <li class="active dropdown">|</li>
}
ACT < .NO
ACT = 1
ACT {
wrapItemAndSub = <li class="active">|</li>
}
CURIFSUB < .IFSUB
CURIFSUB = 1
CURIFSUB {
wrapItemAndSub = <li class="active dropdown">|</li>
}
}
}
page.20 = HMENU
page.20.special = directory
page.20.entryLevel = 0
page.20.maxItems = 6
page.20 {
1 = TMENU
1 {
wrap = <div class="row"><div class="tab-content">|</div></div>
noBlur = 1
expAll = 1
NO.doNotShowLink = 1
}
# second level
2.maxItems = 5
2 = TMENU
2.stdWrap.wrap = <div class="tab-pane fade in active pull-right" id="item-{register:count_MENUOBJ}"><nav class="navbar navbar-default pull-right submenu" role="navigation"><ul class="nav navbar-nav in">|</ul></nav></div>
2.stdWrap.wrap.insertData = 1
2{
expAll = 1
NO{
ATagTitle.field = title
wrapItemAndSub = <li>|</li>
}
IFSUB = 1
IFSUB{
ATagTitle.field = title
wrapItemAndSub = <li>|</li>
}
}
}
In the first menu block links has the correct value: data-target="#item-1", data-target="#item-2" etc..
In the second block the all links are generated in this form: id="item-5" staring and ending on item-5
Any suggestions?
register:count_MENUOBJ is counting the menu-items in the context where it's used.
In the first menu it's used in the context of the main-items and therefore counting in the natural order of the menu-items like an index. This might be the reason that the function of register:count_MENUOBJ is still confusing, even usable in that context.
In the second menu register:count_MENUOBJ is used in the context of the sub-menu items and counting the sub-items on level 2. So if on level two are 3 sub-items the register is 3. If 5 sub-items it's 5. In this context register:count_MENUOBJ is not usable as index as the amount of sub-items never reflects the expected value according to the question.
Therefore to get unique id's it's common practice to use p{field:uid} for pages or for content-elements c{field:uid}.
Example:
...
NO.wrapItemAndSub = <li id="nav-main-p{field:uid}">|</li>
NO.wrapItemAndSub.insertData = 1
...
Another alternative is to use register:count_MENUOBJ in the second menu also on the first level. Question if the menu in the question would have the required properties then.
Use the MenuProcessor instead of HMENU. I always had problems with the custom rendering of HMENU and than i turned to MenuProcessor because the html markup may be created directly in fluid.
Typoscript:
page = PAGE
page.10 = FLUIDTEMPLATE
page.10 {
...
dataProcessing {
10 = TYPO3\CMS\Frontend\DataProcessing\MenuProcessor
10 {
as = navigationMain
}
}
}
FLUID:
<f:for each="{navigationMain}" as="menuItem">
<!-- There you have access to menu items -->
</f:for>
Documentation: https://docs.typo3.org/typo3cms/SitePackageTutorial/MainMenuCreation/Index.html
In general #David already gave all relevant information.
For clarification and as hint for an easier implementation:
In your example you used the count register in page.20.2.stdWrap.wrap. this Wrap is executed in context of second level menu, but after the menu is allready generated, so it contains the number of elements in this menu level.
You need to use the count register in first level, and so it is a wrap to the second level you can use it in .1.IFSUB.wrapItemAndSub, as you have no content in first level it will be a wrap only for the second level menu.
And also mentioned from #David:
You also could use the uids from the pages itself.
Use it in page.10, and in page.20.2 you could use the field pid from any page on that level.
As you want to use it out of the context of a menuItem you might get the problem: there is no real field pid. Either you do the wrap on the first page/ menuItem (hint: optionsplit) or do it in the first level again.
(I doubt that for .1.stdWrap you are in the context of the first level page, so you could use field uid.)
you probably have to insert the following (not tested):
page.15 = RESTORE_REGISTER
just before page.20 = HMENU ... normally used in combination with LOAD_REGISTER but it looks as if your second HMENU has the count_MENUOBJ stuck at the last value of the first ...

HMENU only pages with a specific value in custom field

I have a custom field (lets say its named myfield) in the table pages with the values 0, 1 or 2. I now want to create a HMENU for all pages that have a specific value (for example all pages with myfield=1) in this field.
How could I get this?
As far as I know I can not add a where-clause to the HMENU. So will I need a USER_INT for it?
Will it work somehow like this:
includeLibs.something = mypath/user_myclass.php
lib.servicenav = HMENU
lib.servicenav {
special = list
special.value = USER
special.value.userFunc = user_myclass->myFunction
special.value.myfieldvalue = 1 # 0, 1, or 3
}
user_myclass.php->myFunction:
function myFunction($a, $myfieldvalue) {
// - search all pages with $myfieldvalue
// - add all pids of this page to the returnvalue (as string)
$returnvalue = "5, 19, 200";
return $returnvalue;
}
Will this solution work? Are there better solutions?
Edit: cascavals solution:
It works in a small testproject with this:
lib.menu = HMENU
lib.menu{
special = list
special.value.cObject = CONTENT
special.value.cObject {
table = pages
select {
where = myfield=0
}
renderObj = TEXT
renderObj {
field = uid
wrap = |,
}
}
entrylevel = 1
1 = TMENU
1.NO = 1
1.NO.linkWrap =
<div class="menu">|</div>
überschreibt
2 < .1
2.NO.linkWrap =
<div class="menu-ebene2">|</div>
But it does not work in a bigger project with this (I get no output):
Also when I copy the Menu from above it does not work in this project..
lib.navigation = HMENU
lib.navigation {
special = list
special.value.cObject = CONTENT
special.value.cObject {
table = pages
select {
where = myfield=0
}
renderObj = TEXT
renderObj {
field = uid
wrap = |,
}
}
1 = TMENU
1 {
noBlur = 1
expAll = 0
wrap = <ul class="nav1">|</ul>
NO = 1
NO {
wrapItemAndSub = <li class="first">|</li> |*| <li>|</li> |*| <li class="last">|</li>
altText = subtitle // title
title = subtitle // title
}
CUR < .NO
CUR.ATagParams = class="active"
CUR.wrapItemAndSub = <li class="current first">|</li> |*| <li class="current">|</li> |*| <li class="current last">|</li>
ACT < .CUR
ACT = 1
ACT.ATagParams = class="active"
}
2 = TMENU
2 < .1
2 {
expAll = 0
wrap = <ul class="nav2">|</ul>
}
}
As special.value has stdWrap, you can still select page UIDs dynamically and create a comma-separated list that is expected:
lib.servicenav = HMENU
lib.servicenav {
special = list
special.value.cObject = CONTENT
special.value.cObject {
table = pages
select {
pidInList = [UID of the root page of your website]
recursive = 99
where = myfield=1
}
renderObj = TEXT
renderObj {
field = uid
wrap = |,
}
}
}

Typoscript menu jump to subpage

I want to create a menu with submenu, that's quiet straight forward via typoscript. The challenge is, that I want the parent levels to link directly to the first subpage if the content of the containing page is empty.
I know you can achieve that via shortcut links in the backend, but I want to, if possible, achieve that via typoscript.
Any ideas? I enclode the typoscript menu code I currently use.
lib.mainMenu = COA
lib.mainMenu{
10 = HMENU
10{
# Level 1, further levels are generic
1 = TMENU
1.noBlur = 1
1.expAll = 0
1.wrap = <ul data-role="listview" data-inset="true">|</ul>
1.NO = 1
1.NO.ATagBeforeWrap = 1
1.NO.insertData = 1
1.NO.wrapItemAndSub.insertData = 1
1.NO.wrapItemAndSub = <li id="menu_{field:uid}">|</li>
1.NO.ATagTitle.field = subtitle // title
1.ACT = 1
1.ACT.ATagBeforeWrap = 1
1.ACT.wrapItemAndSub.insertData = 1
1.ACT.wrapItemAndSub = <li id="menu_{field:uid}" class="active">|</li>
1.ACT.ATagTitle.field = subtitle // title
1.CUR = 1
1.CUR.ATagBeforeWrap = 1
1.CUR.wrapItemAndSub.insertData = 1
1.CUR.wrapItemAndSub = <li id="menu_{field:uid}" class="active">|</li>
1.CUR.ATagTitle.field = subtitle // title
}
20 < .10
20.entryLevel = 1
20.1.wrap = <ul data-role="listview" data-inset="true">|</ul>
30 < .20
30.entryLevel = 2
40 < .20
40.entryLevel = 3
}
Maybe you can build your solution based on hints from here:
http://typo3-blog.net/tutorials/news/if-funktionen-in-typo3.html
In the example from the link above, it's not a menu, but there's a subquery on a table (in your case tt_content) which will then be used to define if something's output or not:
temp.main = COA
temp.main.20 = COA
temp.main.20 {
[...]
wrap=<div class="meine-adressen">|</div>
stdWrap.if.isTrue.cObject = CONTENT
stdWrap.if.isTrue.cObject{
table = tt_address
select {
[...]
}
renderObj = TEXT
renderObj.value = 1
}
}
temp.main.21 = TEXT
temp.main.21 {
wrap=<div class="keine-adressen">|</div>
value = Keine Adressen gefunden
stdWrap.if.isFalse.cObject < temp.main.20.stdWrap.if.isTrue.cObject
}
But I'm not sure if this wouldn't give you headaches in a HMENU
I think it is possible using typoscript, but I dont know how to do it.
The below typoscript may help you:
Typoscript to find the number of content elements in a page:
lib.emptypage = CONTENT
lib.emptypage{
table = tt_content
select{
selectFields = count(uid) AS count
pid = id
}
renderObj = COA
renderObj {
10 = TEXT
10 {
value = {field:count}
insertData = 1
}
}
wrap = |
}
If count is equal to zero, then the page is empty.
Typoscript to get the first subpage:
lib.firstsubpage= HMENU
lib.firstsubpage {
maxItems = 1
1 = TMENU
1 {
NO = 1
}
}
Please share your typoscript solution after implementing it.