Extending HMENU with extensions records - typo3

In my extension there are categories and products. I want the categories to be shown as submenu.
My page tree looks like this:
Home
Clothes (uid: 2)
Special Offers (uid: 3)
Workwear (uid: 4)
On pages "Clothes" (uid: 2) and "Workwear" (uid: 4) I have a plugin that will show the categories and products.
The categories to be shown are defined in TS setup (with an ext+ template on each pages) like this:
plugin.tx_productsdb.settings.categories = 1,2,3,4
the typoscript for my subnavigation looks like this:
nav.subnavigation = COA
nav.subnavigation {
10 = HMENU
10 {
entryLevel = 0
1 = TMENU
1 {
wrap = <ul>|</ul>
NO = 0
NO.wrapItemAndSub = <li class="first">|</li> |*| <li>|</li> |*| <li class="last">|</li>
ACT = 1
ACT.wrapItemAndSub = <li class="active first">|</li> |*| <li class="active">|</li> |*| <li class="active last">|</li>
ACT.ATagParams = class="active"
CUR < .ACT
}
2 < .1
2.wrap = <ul class="level2">|</ul>
3 < .1
3.wrap = <ul class="level3">|</ul>
}
}
I already tried to use the itemArrayProcFunc property of HMENU, but I couldn't find an example on how to use it with my namespaced extension.
i tried this:
10 = HMENU
10 {
entryLevel = 0
itemArrayProcFunc = Vendor\Extension\Hooks\Subnavigation->process
And here's the function:
class Subnavigation
{
/**
* #param $menuArr
* #param $conf
*/
public function process(&$menuArr, &$conf)
{
// show me, that something is happening here ... pretty please!
\TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($menuArr);
exit;
}
}
If you've got any example on how to do it, please let me know.
Thanks in advance.

I have a project with products and categories.
The categories should be displayed in the menu and I solved it by JavaScript which is calling an AJAX method.
The AJAX method calls a predefined page type e.g. index.php?id=xx&type=xx
The TypoScript looks like this:
menuItems = PAGE
menuItems.typeNum = xx
menuItems {
config {
disableAllHeaderCode = 1
no_cache = 1
}
10 = USER_INT
10.userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
10 {
extensionName = ExtensionName
pluginName = Plugin
vendorName = Vendor
controller = Product
action = getMenu
switchableControllerActions {
Product {
1 = getMenu
}
}
view < plugin.tx_plugin.view
persistence < plugin.tx_plugin.persistence
settings < plugin.tx_plugin.settings
}
}
The controller action looks like this:
/**
* #return void
*/
public function getMenuAction()
{
$menuItems = [];
$categories = $this->categoryRepository->findAll();
foreach ($categories as $category) {
/** #var Category $category */
$menuItems[] = [
'name' => $category->getTitle(),
'link' => $this->getLinkForCategory($category),
'id' => $category->getUid()
];
}
$this->view->assign('menuItems', $menuItems);
echo $this->view->render();
exit;
}
In Fluid you only have to create the structure for the menu.

In the end, after many failed attempts, I discarded my approach with itemArrayProcFunc.
My solution has some similarities to the one Thomas posted.
I'm using a TS condition and build the navigation completely on my own.
[PIDinRootline = 2] || [PIDinRootline = 3]
lib.subnav >
lib.subnav = USER_INT
lib.subnav {
userFunc = TYPO3\CMS\Extbase\Core\Bootstrap->run
vendorName = Vendor
extensionName = ExtensionName
pluginName = pluginName
controller = Controller
action = getSubnavigation
view < plugin.tx_plugin.view
persistence < plugin.tx_plugin.persistence
settings < plugin.tx_plugin.settings
}
[global]
And my controller action:
public function getSubnavigationAction()
{
$rootline = $this->pageRepository->getRootLine($GLOBALS['TSFE']->id);
// assumption: main page is always on level 1
$rootId = $rootline[1]['uid'];
$treePids = $this->getTreePids($rootId);
$pages = $this->pageRepository->getMenuForPages($treePids, 'uid, pid, title', 'sorting', ' AND hidden=0 AND deleted=0');
$rootPage = $pages[$rootId];
$tree = $this->buildTree($rootPage, $pages);
$menu = $this->buildMenu($tree);
$current = $this->argumentService->getArgument('tx_productsdb_categories', 'category');
$parent = 0;
if($this->argumentService->hasArgument('tx_productsdb_categories', 'parent')) {
$parent = $this->argumentService->getArgument('tx_productsdb_categories', 'parent');
}
$this->view->assign('parent', $parent);
$this->view->assign('current', $current);
$this->view->assign('menu', $menu);
$this->view->assign('settings', $this->settings);
}
The menu is then build in Fluid.

Related

TYPO3 - Sidebar navigation li has no 'active' class when on page (active/current)

TYPO3 - Sidebar navigation li has no 'active' class when on page (active/current). I have this sidebar navigation ... but the li has no active added when on a specifc page. Does anybody see what's wrong?
lib.navigation = COA
lib.navigation {
20 = HMENU
20 {
entryLevel = 1
1 = TMENU
1 {
expAll = 1
#collapse = active
wrap = <ul class="sidebar-nav" id="menu">|</ul>
NO {
subst_elementUid = 1
ATagBeforeWrap = 1
allStdWrap.insertData = 1
wrapItemAndSub = <li>|</li>
}
ACT <.NO
ACT.wrapItemAndSub = <li class="active">|</li>
CUR <.ACT
#CUR <.NO
#CUR = 1
CUR.wrapItemAndSub = <li class="active">|</li>
#CUR.linkWrap = <strong>|</strong>
...
}
....
}
}
Try adding ACT = 1. Unlike NO, ACT and CUR are not active by default.
See https://docs.typo3.org/typo3cms/TyposcriptReference/MenuObjects/CommonItemStates/Index.html for more information about this.

TYPO3 language menu with tx_news - hide language from menu if news record is not translated

I want to hide a language from my language menu if a news record is not translated.
The following setup works perfectly for pages. So if a page has no translation, the "English" is not shown in the language menu on the website.
I would like to have this behaviour for not translated news records as well.
The language menu so far:
lib.language = COA
lib.language {
20 = HMENU
20 {
special = language
special.value = 0,1
special.normalWhenNoLanguage = 0
wrap =
1 = TMENU
1 {
noBlur = 1
NO = 1
NO {
linkWrap = <li>|</li>
stdWrap.override = Deutsch || English
stdWrap {
typolink {
parameter.data = page:uid
additionalParams = &L=0 || &L=1
ATagParams = hreflang="de-DE" || hreflang="en-GB"
addQueryString = 1
addQueryString.exclude = L,id,cHash,no_cache
addQueryString.method = GET
useCacheHash = 1
no_cache = 0
}
}
}
ACT < .NO
ACT.linkWrap = <li class="active">|</li>
USERDEF1 = 1
USERDEF1 {
ldoNotLinkIt = 1
stdWrap.cObject = TEXT
stdWrap.cObject.value =
}
USERDEF2 = 1
USERDEF2 {
doNotLinkIt = 1
stdWrap.cObject = TEXT
stdWrap.cObject.value =
}
}
}
wrap = <ul id="language_menu" class="language-menu">|</ul>
}
My typoscript configuration:
config.sys_language_mode = strict
config.sys_language_overlay = hideNonTranslated
LocalConfiguration.php
[FE][hidePagesIfNotTranslatedByDefault] = 1
You have to manually set the USERDEF1 state. This Utility class should help: https://gist.github.com/birger-fuehne/a8a97c94ec9346d691174462ccbfcfcc

Put the menu link url in an attribute

I need to make a menu without any links but with the url in an attribute.
The url should be in data-href="|" but now only the title will be printed in the attribute.
Is there a way to only return the url and not the link. ie. http://example.com instead of Example
Or does anyone know a different solution?
lib.mainMenu = HMENU
lib.mainMenu {
entryLevel = 1
wrap = <ul id="dropDownMenu">|</ul>
1 = TMENU
1 {
noBlur = 1
expAll = 1
NO = 1
NO {
wrapItemAndSub = <li class="nochildren">|</li>
stdWrap2.wrap = <span>|</span>
}
ACT < .NO
ACT.wrapItemAndSub = <li class="active nochildren">|</li>
# if has children
IFSUB < .NO
IFSUB.wrapItemAndSub = <li class="haschildren">|</li>
IFSUB.allWrap = |
# if has children and is active
ACTIFSUB < .IFSUB
ACTIFSUB.wrapItemAndSub = <li class="active haschildren">|</li>
ACTIFSUB.allWrap = |
}
2 < .1
2 {
wrap = <ul id="subMenu">|</ul>
NO.ATagParams = rel="nofollow"
NO.stdWrap2.insertData = 1
NO.stdWrap2.wrap = <span data-href="|" class="link">{field:title}</span>
NO.doNotLinkIt = 1
IFSUB < .NO
ACTIFSUB < .IFSUB
}
3 < .2
}
Try this (untested code):
lib.mainMenu = HMENU
lib.mainMenu {
entryLevel = 1
wrap = <ul id="dropDownMenu">|</ul>
1 = TMENU
1 {
noBlur = 1
expAll = 1
NO = 1
NO {
wrapItemAndSub = <li class="nochildren">|</li>
stdWrap2.wrap = <span>|</span>
}
ACT < .NO
ACT.wrapItemAndSub = <li class="active nochildren">|</li>
# if has children
IFSUB < .NO
IFSUB.wrapItemAndSub = <li class="haschildren">|</li>
IFSUB.allWrap = |
# if has children and is active
ACTIFSUB < .IFSUB
ACTIFSUB.wrapItemAndSub = <li class="active haschildren">|</li>
ACTIFSUB.allWrap = |
}
2 < .1
2 {
wrap = <ul id="subMenu">|</ul>
NO {
doNotShowLink = 1
stdWrap2 {
wrap >
cObject = TEXT
cObject {
typolink {
parameter.field = uid
returnLast = url
}
insertData = 1
wrap = <span data-href="|" class="link">{field:nav_title//field:title}</span>
}
}
}
IFSUB < .NO
ACTIFSUB < .IFSUB
}
3 < .2
}
The above answer only works as long as you don't have any mountpoints. As soon as you have mountpoints in your page tree, these links will not be generated correctly.
To force a HMENU to output plain URLs without a surrounding a-Tag and page title even when using mountpoints, you need to define the IProcFunc property of HMENU.
I've written a small method which can be called through IProcFunc which will remove the a-Tags and replace the page title with the URL of the link.
<?php
class UserFuncUtils {
/**
* Modifies sitemap links. Whith this modification, a menu will only generate a plain url instead of an <a>-Tag
*
* This is an IProcFunc for a HMENU. The only parameter supplied by this method call is $this->I from the
* Menu ContentObject. The function call expects a modified $I array to be returned.
*/
function IProcFunc_plainURL($I) {
// Show what $I has to offer
// print \TYPO3\CMS\Extbase\Utility\DebuggerUtility::var_dump($I, NULL, 8, FALSE, FALSE, FALSE, array(), array());
// Remove opening and closing tags and replace title with href attribute. This results in a plain URL being rendered by the menu
$I['parts']['ATag_begin'] = '';
$I['parts']['ATag_end'] = '';
$I['parts']['title'] = $I['linkHREF']['HREF'];
return $I;
}
}
?>
Just save this small class somewhere (e.g. /fileadmin/libs/class.userFuncUtils.php) and include it with
includeLibs.userFuncUtils = fileadmin/libs/class.userFuncUtils.php
and then set the IProcFunc property of HMENU to point to this user function
lib.mainMenu = HMENU
lib.mainMenu.IProcFunc = UserFuncUtils->IProcFunc_plainURL
This should do the trick.

Typo3 tt_news add Parameter to URL

how can i read out the current id from tt_news and add this as a parameter to the url
a small review of my TYPOSCRIPT
2 = TMENU
2 {
wrap = <ul class="naviMainLevel2"> | </ul>
NO {
wrapItemAndSub = <li> | </li>
}
ACT = 1
ACT {
wrapItemAndSub = <li class="active"> | </li>
#get current tt_news id add it to the menu
additionalParams.data = GP:tx_ttnews|tt_news
additionalParams.intval = 1
additionalParams.wrap = &tx_events_pi1[newsUid]=|
#returns only &tx_events_pi1[newsUid]=0
#maybe is it possible with RECORDS tt_news.mbl_newsevent, to get the id?
}
CUR = 1
CUR < .ACT
}
url should then look like this: www.example.com/news/news-tech?&tx_events_pi1[newsUid]=55
Updated:
i think this is a problem with the extension mbl_newsevent it shows only news with an registration option and a button with the current tt_news id...generated with this TS:
plugin.tt_news.mbl_newsevent {
registrationLink_typolink {
title.data = LLL:EXT:mbl_newsevent/locallang.xml:registerLinkLabel
parameter = {$powermail.plugin.pid}
parameter.override.field = tx_mblnewsevent_regurl
additionalParams.field = uid
additionalParams.intval = 1
additionalParams.wrap = &tx_powermail_pi1[eventUid]=|
#this returns the correct tt_news id for the button
}
}
i need the same way for my url....
If I understood correctly, you need to correct your code in a following way:
2 = TMENU
2 {
wrap = <ul class="naviMainLevel2"> | </ul>
NO {
wrapItemAndSub = <li> | </li>
}
ACT = 1
ACT {
wrapItemAndSub = <li class="active"> | </li>
#parameter.override.field = tt_news_id ||uid
# ^ you don't need this line, becasue you still need
# the current page id in url and it shouldn't be overriden
# by some other param
# next you need to get current tt_news uid from GET
# as you mentioned in your comment
additionalParams.data = GP:tx_ttnews|tt_news
additionalParams.intval = 1
additionalParams.wrap = &tx_events_pi1[newsUid]=|
}
CUR = 1
CUR < .ACT
}

How to add title to breadcrumb from the database of extention in typo3?

Using kickstart i created one extension for listing category and product.And i need to display the both category title/name & product title/name in my breadcrumb .At present i coded for calling from the database(" 40 = RECORDS") it is only showing the
RESULT :- HOME > Page Name »
My Url:-http://www.domain.com/page_name/
lib.breadcrumb=COA
lib.breadcrumb {
40 = RECORDS
40 {
dontCheckPid = 1
tables = TABLE_NAME
source.data = GPvar:tx_pi1_NAME|EXTKEY
conf.EXTKEY = TEXT
conf.EXTKEY.field = FIELD_NAME
wrap = » |
}
10 = HMENU
10 {
special = rootline
# "not in menu pages" should show up in the breadcrumbs menu
includeNotInMenu = 1
1 = TMENU
# no unneccessary scripting.
1.noBlur = 1
# Current item should be unlinked
1.CUR = 1
1.target = _self
1.wrap = <div class="breadcrumb-class"> | </div>
1.NO {
stdWrap.field = title
ATagTitle.field = nav_title // title
linkWrap = ||*| > |*|
}
# Current menu item is unlinked
1.CUR {
stdWrap.field = title
linkWrap = ||*| &nbsp>&nbsp&nbsp |*|
doNotLinkIt = 1
}
}
}
Here is an example from the news extension. You can use the same approach for your extension.
http://forge.typo3.org/projects/extension-news/wiki/Add_news_to_breadcrumb_menu
We can add field title to breadcrumb from the database of any extention that which we create in typo3.
lib.breadcrumb = COA
lib.breadcrumb {
stdWrap.wrap = <ul class="breadcrumb">|</ul>
entryLevel = 1
10 = HMENU
10 {
special = rootline
1 = TMENU
1 {
noBlur = 1
NO = 1
NO {
wrapItemAndSub = <li>|</li>
ATagTitle.field = subtitle // title
linkWrap = ||*| ›&nbsp |*|
stdWrap.htmlSpecialChars = 1
}
CUR <.NO
CUR {
wrapItemAndSub = <li class="active">|</li>
}
}
}
101=RECORD
101 {
tables = tx_table_name
source.data = GPvar:tx_plugin_name|param //param passing in the url
conf.tx_besiproduct_product = TEXT
conf.tx_besiproduct_product.field = field_name
conf.tx_besiproduct_product.required = 1
conf.tx_besiproduct_product.wrap = <li >|</li>
}
}