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.
Related
I try to build a simple menu where the field "subtitle" (if set) from the page is added as anchor to the link
MAINMENU2 = HMENU
MAINMENU2 {
special = directory
special.value = 1
1 = TMENU
1 {
expAll = 1
wrap = <ul class="menu">|</ul>
noBlur = 1
NO = 1
NO.stdWrap.typolink.section.field = subtitle
}
}
output: Page XY
expected: Page XY
How must the TypoScript look like to get this work?
You need to disable the automatic link building of TMENU with doNotLinkIt and then build the complete link with typolink:
NO {
doNotLinkIt = 1
stdWrap.typolink {
parameter.field = uid
section.field = subtitle
}
}
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>
}
}
}
I'm running a Typo3 v9.5.4 Onepager style Website. The content is loaded directly from the tt_content. The Website has two FE languages (German/English).
I have a CTA button which has an anchorlink. The button is create with typoscript. I created one button for the German version and one for the English verson bc they have another value and another ancorlink.
I'm not sure if I can access a tt_content field directly from a fluid viewhelper. This is my code i've tried
<f:if condition="{tt_content.sys_language_uid} == 1">
<f:then>
<f:format.raw>{buttonEn}</f:format.raw>
</f:then>
<f:else>
<f:format.raw>{buttonDe}</f:format.raw>
</f:else>
</f:if>
This is my Typoscript for the two button Objects
lib.buttonDe = TEXT
lib.buttonDe {
value = German Text
stdWrap.typolink.parameter = #anchorlinkDE
stdWrap.typolink.ATagParams = class="button"
}
lib.buttonEn = TEXT
lib.buttonEn {
value = English Text
stdWrap.typolink.parameter = #anchorlinkEN
stdWrap.typolink.ATagParams = class="button"
}
And this is the typoscript that loads the Content, the Languages Menu and the Fluidtemplate (the Onepager Content is loaded without a Fluidtemplate, it loads the content directly from tt_content):
//--------------------- One Pager Content
lib.sectionContent = HMENU
lib.sectionContent {
excludeUidList = 12,13,16,17,29
1 = TMENU
1 {
NO = 1
NO {
doNotLinkIt = 1
stdWrap >
stdWrap {
cObject = COA
cObject {
if.value = 4
if.equals.field = doktype
if.negate = 1
10 < temp.titleSectionId
10.wrap = <section id="|">
20 = CONTENT
20 {
table = tt_content
select {
pidInList.field = uid
orderBy = colPos,sorting
# Only selects Content where CE Layout is 0
where = (tt_content.layout = "0")
}
wrap = <div class="container">|</div>
renderObj < tt_content
}
30 = TEXT
30 {
wrap = </section>
}
}
}
}
}
}
//---------------------
// Language Selector
lib.langmenu = HMENU
lib.langmenu {
special = language
addQueryString = 1
special.value = {$config.language.uids}
1 = TMENU
1 {
wrap = <ul class="dg-langmenu row">|</ul>
NO = 1
NO {
stdWrap.current = 1
stdWrap.setCurrent = {$config.language.labels}
allWrap = <li class="col s6">|</li>
}
ACT < .NO
ACT.doNotLinkIt = 1
ACT.allWrap = <li class="act col s6">|</li>
}
}
page = PAGE
page{
10 = FLUIDTEMPLATE
10 {
templateName = TEXT
templateName.stdWrap{
cObject = TEXT
cObject{
data = levelfield:-2,backend_layout_next_level,slide
override.field = backend_layout
split {
token = pagets__
1.current = 1
1.wrap = |
}
}
ifEmpty = onePager
}
templateRootPaths {
10 = {$path.privat}Templates/
}
layoutRootPaths {
10 = {$path.privat}Layouts/
}
partialRootPaths {
10 = {$path.privat}Partials/
}
variables{
buttonDe < lib.buttonDe
buttonEnd< lib.buttonEn
}
}
So I'd like to load the buttonEn if the content has the sys_language_uid 1 (English) else I want it to load the buttonDe.
Do I need to create an Typoscript Object and then load this Object into the f:if viewhelper? If so how do I create this Typoscript Object.
Thanks for your help!
The easy way (pure typoscript)
lib.button = TEXT
lib.button {
value = English text
lang.de = Deutscher Text
stdWrap.typolink.parameter = #anchorlinkDE
stdWrap.typolink.ATagParams = class="button"
}
[siteLanguage("locale") == "en_EN.UTF-8"]
lib.buton.stdWrap.typolink.parameter = #anchorlinkEN
[global]
but the professional solution is configuring your labels in a language file (see answer from Thomas Löffler) and use:
lib.button = TEXT
lib.button {
lib.button.data = LLL:EXT:site_extension/Resources/Private/Language/locallang.xlf:button_label
stdWrap.typolink.parameter = #anchorlinkEN
stdWrap.typolink.ATagParams = class="button"
}
[siteLanguage("locale") == "de_DE.UTF-8"]
lib.buton.stdWrap.typolink.parameter = #anchorlinkDE
[global]
For language dependent constant data you might use typoscript conditions to redefine a value for your non default languages. (or define a fallback and conditions for each language.)
You should use a locallang file and refer to it in TypoScript.
Create a locallang file (copy an existing and remove all values) named locallang.xlf
Add your english label in there
Create a locallang file in the same folder with prepending de. in the filename (de.locallang.xlf) and add the german label
Refer to it in the TypoScript by using lib.button.data = LLL:EXT:your_ext/path/to/locallang/locallang.xlf:buttonLabel, see https://docs.typo3.org/typo3cms/TyposcriptReference/DataTypes/Index.html#lll
This TS getText function gets the label depending on the set language ID automatically and you only need one TS for the button.
Example: https://docs.typo3.org/typo3cms/TyposcriptIn45MinutesTutorial/UsingGetText/Index.html
In below TYPO3 script code get pages list from others menu item
I want to set order by latest pages with a limit parameter(limit=5)
special directory include submenu entries and display it at home page
[page|uid = 1]
lib.content_6.stdWrap.preCObject = HMENU
lib.content_6.stdWrap.preCObject {
1 = TMENU
wrap = <div class="wpContentElement wpReferenceList"><ul>|</ul></div>
special = directory
special.value = 94,95,97,378,445
includeNotInMenu = 1
special.range = 1|-2
1 {
NO.wrapItemAndSub = <li class="col-xs-12 col-sm-6 col-lg-3 col-xl-3">|</li>
NO.stdWrap.cObject = COA
NO.stdWrap.cObject {
10 = TEXT
10 {
field = title
wrap = <div>|</div>
}
20 = FILES
20 {
references {
table = pages
uid.field = uid
fieldName = tx_mask_referenceimage
}
renderObj = IMAGE
renderObj {
file.import.data = file:current:uid
file.treatIdAsReference = 1
file.height = 850c
file.width = 850c
}
}
}
}
}
[end]
Maximum can be done with maxItems, but there is no option for your own ordering. You might be able to abuse additionalWhere.
A cleaner solution would be to implement an own itemArrayProcFunc.
1 = TMENU
1 {
maxItems = 5
// additionalWhere = ORDER BY tstamp desc
itemArrayProcFunc = user_menuItemArrayProcFunc->process
}
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 = |,
}
}
}