How to build a menu with defined pages - typoscript2

In TYPO3 CMS you could build a menu with defined pages very easy. How does this work in Neos and Typoscript2?
Typoscript1 Code was:
Menu1 = HMENU
Menu1 {
special = directory
special.value = 1,6,7
wrap = <div class="somemenu">|</div>
}
For example i have this page structure:
Site1
Site2
Site3
Site4
Site5
Site6
Site7
And i want a menu which only contains Site1, Site6, Site7.
I need that menu in the footer.

I have found a way to create a menu with defined pages, by adding a checkbox in every page so I can select which pages I want to show in the menu.
Start by editing NodeTypes.yaml and extend the Page nodetype to have this extra property
ui:
inspector:
groups:
'footernav':
label: 'Footer Menu'
properties:
'footermenu':
type: boolean
defaultValue: FALSE
ui:
label: 'Show in footer?'
inspector:
group: 'footernav'
After that create a FooterMenu nodetype in the same file.
'Vendor.Site:FooterMenu':
superTypes: ['TYPO3.Neos.NodeTypes:Menu']
ui:
label: 'Footer Menu'
group: 'structure'
Create it's typoscript file.
prototype(Vendor.Site:FooterMenu) < prototype(TYPO3.Neos.NodeTypes:Menu) {
entryLevel = 1
templatePath = 'resource://Neos.Bootsite/Private/Templates/TypoScriptObjects/FooterMenu.html'
}
Edit Root.ts2 file and add in the Page object
footermenu = ${q(node).property('footermenu')}
Last but not least, create FooterMenu.html
{namespace neos=TYPO3\Neos\ViewHelpers}
<ul>
<f:render section="itemsList" arguments="{items: items}" />
</ul>
<f:section name="itemsList">
<f:for each="{items}" as="item">
<f:if condition="{item.node.properties.footermenu}">
<neos:link.node node="{item.node}">{item.label}</neos:link.node>
</f:if>
<f:if condition="{item.subItems}">
<f:render section="itemsList" arguments="{items: item.subItems}" />
</f:if>
</f:for>
</f:section>

thank you for this nice Idea. I wouldn't even call it a workaround. With neos we have to think in different ways... and this solution is really great and intuitive!
I had some headbanging moments cuz I didn't understand the way neos works...
I'm usually want to add elementary elements like navigation fix to the layout/template.
I didn't understood that this footermenu will appear as an element which you can add dynamically when you are logged in.
If somebody want's to know how he can add this fix to the template, so users can't remove it:
Add in your Route.ts2
page = Page {
head{ ... }
body{
//...
parts.footermenu = Vendorname.Sitename:FooterMenu
//...
}
}
In your template file e.g. (Vendorname.Sitename/Private/Templates/Page/Default.html):
{parts.footermenu -> f:format.raw()}
at the position where the menu should appear
Side note: in this example it has to be within the in order to work

I think best solution is already in the Demo Package. You can create a page FooterMenu which you don't want so show as a normal page on the page menu. Add your menu pages as child shortcut nodes to the page/node tree.
Then add this typoscript in your root.ts2
metaMenu = Menu {
entryLevel = 2
templatePath = 'resource://Vendor.PackageName/Private/Templates/TypoScriptObjects/FooterMenu.html'
maximumLevels = 1
startingPoint = ${q(site).children('footermenu').get(0)}
}
Create the template for the menu:
{namespace neos=TYPO3\Neos\ViewHelpers}
<f:render section="itemList" arguments="{items: items}" />
<f:section name="itemList">
<nav class="nav" role="navigation">
<ul class="nav nav-pills">
<f:for each="{items}" as="item" iteration="menuItemIterator">
<li class="{item.state}">
<neos:link.node node="{item.node}">{item.label}</neos:link.node>
</li>
</f:for>
</ul>
</nav>
</f:section>
The last think you have to do ist to place the footerMenu in your page template:
<div class="footer">
{parts.footerMenu -> f:format.raw()}
</div>
The only drawback of this solution is you have to use shortcuts and that is not the best solution for SEO i think. And the page loading time will be increased because of the redirect. But you don't have to extend some code and can use another solution when it is ready.

Related

How do I create a breadcrumb nav for a banner hero in 2sxc using C#?

Using 2sxc, I have a hero module that I use across the website on all pages. It looks like this:
It uses "#Content.Title" for the h1 tag so it displays "Scholarships". But I need to make a breadcrumb that gets the parent page's name of the current page. So in this case, "Teachers".
For example, this hero also exists on other pages like "Volunteer" and it has a parent of "Get Involved" so the breadcrumb would dynamically show "Get Involved".
So far, here's my code:
#if (#Dnn.Tab.ParentId != -1) {
<nav class="uppercase text-sm font-semibold tracking-wider"><span class="text-honeydew visited:text-honeydew">#Dnn.Tab.ParentID</span> <span>/</span></nav>
}
This works to handle heroes on a root page (to not show the breadcrumb). But I can only seem to output the ParentID.
How can I use the #Dnn.Tab.ParentID to get the Parent tab's name using c#? Or is there another way to go about this?
Easiest thing to do is use the TabController to turn a TabId in to a TabInfo
#using DotNetNuke.Entities.Tabs
#functions {
private TabInfo GetTabInfo(int tabId)
{
return TabController.Instance.GetTab(tabId, Dnn.Portal.PortalId);
}
}
So then just call it all in one like this with .ParentId...
<pre>
Debug:
Parent Page Name: #GetTabInfo(Dnn.Tab.ParentId).TabName
</pre>

Prevent dropdown close click outside does work in codeply/jsfiddle but not within my own project?

Hello guy's i have a problem for day's i have been trying. But nothing works. I want the same effect as this -> https://www.codeply.com/go/Ai786lQzd8/bootstrap-4-prevent-dropdown-close-click-outside.
I want the dropdown menu only to close when i click on the button. I copied the EXACT code to my own project and it closes when clicking outside? It shouldn't close like the codeply example. I don't understand how to fix this.
I tried changing the code with a click target id and then let the dropdown menu close when ID is clicked but that also doesn't work i am out of options to try. I hope someone can help me with this.
Here is my code
<li class='keep-open'>
<a id='dropdownMenuLogin' class='nav-link badge no-style-for-badge' data-toggle='dropdown' href='#'>Login</a>
<!-- Dropdown login begins here -->
<ul class='dropdown-menu dropdown-menu-login mt-1'>
<li class='p-3'>
<form method='POST' id='loginFormHeader'>
<!-- Login code should be here -->
</form>
</li>
</ul>
</li>
Here comes the jQuery code i tried it with:
$('IF NOT -> #dropdownMenuLogin').click(function() {
$('.keep-open').on({
"shown.bs.dropdown": function() { this.closable = false; },
"click": function() { this.closable = false; },
"hide.bs.dropdown": function() { return this.closable; }
});
});
I want it closable false IF NOT clicked on #dropdownMenuLogin. So i want it only to close and open when i click on "the button" like codeply link in my case it is a <a> #dropdownMenuLogin
But the start of fixing this problem is why does it work in codeply and not in my own project i copied exactly everything to test it and it just closes when clicking on the outside.
Jquery version: 3.4.1
Bootstrap version: 4.0.0

PDFKit navigate to page on click

I have used PDFKit to generate pdf from html. But is there a way to navigate to nth page on click of an section(box element) on the page ?
Generate PDF:
content = PDFKit.new("#{header_html}<div class='pdf_image'><img src='data:image/svg+xml;base64,#{ Base64.encode64(chart1.read).gsub("\n", '')}'></img></div>
<div class='pd_image' style='margin-top: 10%; page-break-after: always;'><img src='data:image/svg+xml;base64,#{ Base64.encode64(chart2.read).gsub("\n", '')}'></img></div>
<div class='pdf_image' style='margin-top: 10%;'><img src='data:image/svg+xml;base64,#{ Base64.encode64(chart3.read).gsub("\n", '')}'></img></div>",
orientation: 'landscape', margin_top: '0.2in', page_size: 'Letter')
send_data(content.to_pdf, filename: "all_charts.pdf", type: 'application/octetstream', disposition: 'inline')
Clicking on Box1 would do navigate to Page1 (current page).
Box 2 --> Page2
Box 3 --> Page3
Attached image explains what needs to happen.
Those are called as internal links.
Achieved with:
<a href='#box_1'></a>
<div name='box_1'></div>
Respectively for all boxes.
The only hurdle was with wkhtmltopdf enable internal links.

One page theme Bootstrap Navigation Link does not direct to another page, while it works for anchors inside the page

I have been using a bootstrap one page theme in my ASP MVC 5 app. Since it is one page, all the navigation links points to anchors inside the page. Then I needed an additional link to direct to another page, but it does not work. When I see the source code, the href is just fine, the hover is also fine, but when clicked it does nothing. Please help me spot the problem.
the problem is here:
<li class="active">Cart (2)</li>
here is the html code:
<nav class="fixed-top" id="navigation" style="top: 0px; opacity: 1;">
<div class="container">
<div class="row-fluid">
<div class="span12 center">
<!-- LOGO -->
<a class="brand pull-left" href="./">
<img src="/assets/images/logo.png" alt="Treble">
</a>
<!-- END LOGO -->
<!-- MOBILE MENU BUTTON -->
<div class="mobile-menu" data-toggle="collapse" data-target=".nav- collapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</div>
<!-- END MOBILE MENU BUTTON -->
<!-- MAIN MENU -->
<ul id="main-menu" class="nav-collapse collapse">
<li class="">Home</li>
<li class="">Product</li>
<li class="">About Us</li>
<li>News</li>
<li class="">Contact</li>
<li class="active">Cart (2)</li>
</ul>
<!-- END MAIN MENU -->
<!-- SOCIAL ICONS -->
<div class="social-icons pull-right" id="navRight">
info#panairsan.com
+62 (21) 580 7881
</div>
<!-- END SOCIAL ICONS -->
</div>
</div>
</div>
</nav>
Here is the related css classes:
.fixed-top {
position: fixed;
top: 0px;
opacity: 0;
filter: alpha(opacity=0);
}
#navigation #main-menu {
float: right;
}
#navigation .social-icons {
display: none;
}
I think that is all about the code, nothing else seems to be effecting the link. Please let me know if you need more code to solve this weird problem.
I tried this one also:
<a href="./ShoppingCart">
Adding a dot, like the logo that is able to go to home page (refresh the page), but still does not work.
Thanks
Update
I use jquery.scrollTo. Maybe there is something with this plugin?
The theme I use is this one:
Wrapbootsrap - Treble One Page Theme
UPDATE about jquery.scrollTo
I keep searching, and I am narrowing the problem to jquery.scrollTo. It seems that the plugin is preventing the page from going anywhere. Anywone here is experienced with jquery.scrollTo?
UPDATE Routing Mechanism:
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "Index", id = UrlParameter.Optional },
namespaces: new string[] { "percobaan2.Controllers" }
);
IMPORTANT UPDATE
the main problem: the link is active but it does not direct to the linked page. It does not even direct to a 404 page or anything. It just does not execute the href location.
In the href link call the class "external" like this:
<a href="./ShoppingCart"class="external">
i experienced the same some of the element may overlap your link, just increase the z-index of the link separately
I just solved this issue in my project.
The file plugin.js was causing the trouble, in my case, because the template itself was a one-page template.
I commented-out the line:
self.$nav.on('click.onePageNav', $.proxy(self.handleClick, self));
And the links in the nav just work fine.
I had a similar issue with the template. The application.js file has a script that makes this happen. So you should be able to just remove the
scroll class from the a tag to allow redirect.
/* use class="scroll" on the a element to activate*/
$(".scroll").click(function (event) {
event.preventDefault();
//calculate destination place
var dest = 0;
if ($(this.hash).offset().top > $(document).height() - $(window).height()) {
dest = $(document).height() - $(window).height();
} else {
dest = $(this.hash).offset().top - 50;
}
//go to destination
$('html,body').animate({
scrollTop: dest
}, 1500, 'swing');
/* Fix jumping of navigation. */
setTimeout(function() {
$(window).trigger('scroll');
}, 900);
return false;
});
here is the solution on this page:
a href is not going to other pages
open up your console and then click the inspection tools and then click on the link to open what script runs when you click on that link. you have to state an if statement to say: if (".navbar a" =! ".external"){here goes the rest of li that have external links and now it works}
and then add the external links to the li tags that have external links.
if (".navbar a" =! ".external"){
$(".navbar a, footer a[href='#myPage']").on('click', function(event) {
// Prevent default anchor click behavior
event.preventDefault();
// Store hash
var hash = this.hash;
// Using jQuery's animate() method to add smooth page scroll
// The optional number (900) specifies the number of milliseconds it takes to scroll to the specified area
$('html, body').animate({
scrollTop: $(hash).offset().top
}, 900, function(){
// Add hash (#) to URL when done scrolling (default click behavior)
window.location.hash = hash;
});
});
}
The bug is in the smooth scroll function event.preventDefault();
the best and most simple way to do it would be to add a .not('.ext_link')
to the smooth scroll function witch will look something like:
$(".navbar a, footer a[href='#myPage']").not('.ext_link').on('click', function(event) {
and the add to all the external links a class="ext_link"
Hope that works for you...

Updating appbar button using flyout menu

I have a question that is probably easy but I'm just overlooking.
So I've created an app bar with a single button on it that creates a flyout menu when pressed. The button is created so that it can hold an image.
<button class="app-button" style="-ms-high-contrast-adjust:none" data-win-control="WinJS.UI.AppBarCommand"
data-win-options="{id:'appButton',icon:'url(images/logo.png)',section:'global', type: 'flyout', flyout:select('#appFlyout')}">
</button>
On my flyout menu, I'm going to populate it with a list of items, but at the moment I've just hard coded a list of images, using CSS to supply an image to each button.
<div id="appFlyout" data-win-control="WinJS.UI.Flyout" aria-label="App Menu" style="visibility: visible;">
<ul class="appList" list-style-type: none style="width: 127.5px;">
<li id="app1List"><button id="app1" class="appButton"></button></li>
<li id="app2List"><button id="app2" class="appButton"></button></li>
<li id="app3List"><button id="app3" class="appButton"></button></li>
<li id="app4List"><button id="app4" class="appButton"></button></li>
<li id="app5List"><button id="app5" class="appButton"></button></li>
<li id="app6List"><button id="app6" class="appButton"></button></li>
</ul>
</div>
For the short term, I just need a way through my JavaScript to update the button on my appbar with the image of the button clicked in the flyout menu. I'm using the blank Windows Store App, so everything is located in default.(css/html/javascript).
I attempted to create a function that would update the button and then add that function to an event listener for app1 so that clicking it would update the appbar image but it wouldn't work. Looking past the poorly constructed list (as I said, it's just a stop gap for the moment), is there a better way to do those or do I need to do it how I thought and add an event listener to each button in the flyout menu?
Consider using WinJS.UI.ListView control for the list in the flyout. Refer a quickstart sample in case you have not used listview earlier.
It can be bound to an list with each item representing a button img. use iteminvoked event handler to set the selected button image, for the appbarcommand in the appbar.
below is not complete code. but part of the code, to give an idea.
var buttonFilePaths = [
{ iconFilePath: '/images/button1.png' },
{ iconFilePath: '/images/button2.png'},
{ iconFilePath: '/images/button3.png'}];
var list = new WinJS.Binding.List(buttonFilePaths);
// bind this list data source to the listview control.
listview.winControl.itemDataSource = list.dataSource;
// register for iteminvoked event when the item is tapped;
listView.addEventListern('iteminvoked', function (event)
{
var selectedIndex = event.detail.itemIndex;
var item = list.getAt(selectedIndex);
appButton.winControl.icon = item.iconFilePath;
});
html:
<div id='listview' data-win-control="WinJS.UI.ListView'
data-win-options="{ tapBehavior: 'invokeOnly', selectionMode: 'none', swipeBehavior: 'none'
, itemTemplate: select('#itemTemplate')}" >
</div>
<div id='itemTemplate' data-win-control='WinJS.Binding.Template'>
<div class='list-item'>
<img data-win-bind='src: iconFilePath' />
</div>
</div>