How to build a menu with defined pages

2.9k views Asked by At

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.

3

There are 3 answers

2
barcasal On BEST ANSWER

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>
0
Jürgen Kleiß On

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.

0
kapale On

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