Navigation menu support for pages and subpages

Coolhaus

Member
I am creating quite a lot of static HTML pages and I would like to have more than one level of pages show up in the navigational menus. The structure would be something like this:

Category 1
Page 1​
Subpage 1​
Subpage 2​
Subpage 3​
Page 2
Page 3​
Only one level of page links are supported which I am finding very limiting. I did play around with the pages option to automatically add a navigational menu for child and sibling nodes but again that assumes you setup your forum like this:

Category 1
Page 1
Subpage 1
Subpage 2​
Not a logical hierarchy if Subpage 1 should sit below Page 1. At the moment I am creating the Subpage links by hand and placing them in a custom HTML container in the sidebar, but it will be long winded and I will have to manually update the links should them change. The automatic navigational menu that is added to pages would be a great starting point if it wasn't for:
1. It only works one level deep​
2. The menu would need to be moved into the sidebar/elsewhere and restyled​

I appreciate Xenforo isn't designed as a portal but so many people are already pushing it beyond what it was designed to do. Anyone have any experience of a similar setup?
 
Edit this file:

library/XenForo/Model/Page.php

You can see the depth is specified in red:

Rich (BB code):
	public function getChildNodes(array $page)
	{
		$nodes = $this->_getNodeModel()->getChildNodesToDepth($page, 1, true);

		return $this->_prepareRelatedNodes($nodes);
	}

But if you increase that number then you need to edit the style to make display changes for the child links depending on depth:

Admin CP -> Appearance -> Templates -> pagenode_container

Add the red code (4 pieces). Or you can just copy the entire template below which is from XenForo 1.1.3 with the necessary code added:

Rich (BB code):
<xen:title>{$page.title}</xen:title>

<xen:navigation>
	<xen:breadcrumb source="$nodeBreadCrumbs" />
</xen:navigation>

<xen:container var="$head.openGraph">
	<xen:include template="open_graph_meta">
		<xen:set var="$url">{xen:link canonical:pages, $page}</xen:set>
		<xen:set var="$title">{$page.title}</xen:set>
	</xen:include>
</xen:container>

<xen:container var="$quickNavSelected">node-{$page.node_id}</xen:container>

<xen:container var="$bodyClasses">{xen:helper nodeClasses, $nodeBreadCrumbs, $page}</xen:container>

<xen:container var="$head.canonical">
	<link rel="canonical" href="{xen:link 'canonical:pages', $page}" /></xen:container>

<xen:if is="{$page.description}">
	<xen:description class="baseHtml">{xen:raw $page.description}</xen:description>
</xen:if>

<xen:require css="pagenode.css" />

<div id="pageNodeContent">

	<xen:if hascontent="true">
		<div id="pageNodeNavigation" class="secondaryContent">
			<div class="blockLinksList">
			<xen:contentcheck>
			
				<xen:if is="{$listSiblingNodes} && {$siblingNodes}">
				
					<xen:if is="{$parentNode}"><h3 class="parentNode"><a href="{$parentNode.href}"><span class="_depth0 depthPad">{$parentNode.value}</span></a></h3></xen:if>
					
					<ol class="siblingNodes">
						<xen:foreach loop="$siblingNodes" value="$node">
							<li class="{xen:if '{$node.node_id} == {$page.node_id}', 'currentNode', 'siblingNode'}">
								<a href="{xen:link {$node.routePrefix}, $node}" class="{xen:if '{$node.node_id} == {$page.node_id}', 'selected'}">
									<span class="_depth1 depthPad">{$node.title}</span>
								</a>
								<xen:if is="{$listChildNodes} && {$childNodes} && {$node.node_id} == {$page.node_id}">
									<ol class="childNodes">
									<xen:foreach loop="$childNodes" value="$childNode">

										<xen:set var="$childStyle">margin-left: {xen:calc '({$childNode.depth} - {$page.depth} - 1) * 20'}px;</xen:set>

										<li class="childNode" style="{$childStyle}"><a href="{xen:link {$childNode.routePrefix}, $childNode}">
											<span class="_depth2 depthPad">{$childNode.title}</span>
										</a></li>
									</xen:foreach>
									</ol>
								</xen:if>
							</li>
						</xen:foreach>
					</ol>
					
				<xen:elseif is="{$listChildNodes} && {$childNodes}" />
				
					<ol class="childNodes">
						<xen:foreach loop="$childNodes" value="$childNode">

							<xen:set var="$childStyle">margin-left: {xen:calc '({$childNode.depth} - {$page.depth} - 1) * 20'}px;</xen:set>

							<li class="childNode" style="{$childStyle}"><a href="{xen:link {$childNode.routePrefix}, $childNode}">
								<span class="_depth0 depthPad">{$childNode.title}</span>
							</a></li>
						</xen:foreach>
					</ol>
					
				</xen:if>
				
			</xen:contentcheck>
			</div>
		</div>
	</xen:if>

	<xen:hook name="pagenode_container_article">
	<article>{xen:raw $templateHtml}</article>
	</xen:hook>
	
	<div class="bottomContent">

		<xen:if is="{$page.log_visits}">
			<div class="pageCounter">
				<dl class="pairsInline pageStats">
					<dt>{xen:phrase published}:</dt> <dd>{xen:date $page.publish_date}</dd>
					<dt>{xen:phrase page_views}:</dt> <dd>{xen:number $page.view_count}</dd>
				</dl>
			</div>
		</xen:if>
	
		<xen:include template="share_page">
			<xen:set var="$url">{xen:link 'canonical:pages', $page}</xen:set>
		</xen:include>
	
	</div>
	
</div>

The result:

Screen shot 2013-01-14 at 2.30.55 PM.webp

This of course assumes you have siblings and/or children enabled for the page node:

Screen shot 2013-01-14 at 2.23.18 PM.webp
 
This is similar to what one person did with the NodesAsTabs addon (if you are interested in creating nav tabs for pages):

http://xenforo.com/community/resources/nodes-as-tabs.9/

...with a small modification:

http://xenforo.com/community/threads/nodes-as-tabs-with-tab-selection.23295/page-6#post-293965

...it can display multiple levels of child links in the popup which looks like this:

http://xenforo.com/community/threads/nodes-as-tabs-with-tab-selection.23295/page-6#post-293499

...but the child links are limited to one level deep once you enter the tab and they become a row of links.
 
Many thanks Jake that is a huge help - the first suggestion would seem to be the best for me as I really need that extra level of links. I can see how the drop down menu would work (as per your attachment) but once you enter the tab only one level of links can be shown (as a row of links). I hadn't considered that and the potential it would have to confuse users. I suppose it is possible to change that behavior so that navigation is done solely with the drop down menus? I will have to think about it.

I am already using your excellent NodesAsTabs addon and it is incredibly useful.
 
I made those edits and it does work giving me a secondary page navigation of the child links to the depth I specified (3 in this case). That in itself is useful but in my mind I had intended these links to also show up when the main category is also a tab (NodesAsTabs addon).

Currently the main navigation (on a tab) works like this:
Menu tab 1
----- Page 1

And only the secondary navigation shows the full structure:
Menu tab 1
----- Page 1
---------- Child 1
-------------------- Child 2
------------------------------ Child 3

The link you gave explains what I was trying to do http://xenforo.com/community/threads/nodes-as-tabs-with-tab-selection.23295/page-6#post-293499

I'm not sure how it should be handled to be honest, I really wanted a full drop-down style menu navigation so it may need some rethinking on my part. In the meantime I shall investigate the page navigation to see if it can be styled and moved to my liking. To work!
 
I ended up moving the page node navigation into the sidebar with a simple edit to the pagenode_container (wrapping the code in <xensiderbar>tags) - with some tweaks to the CSS its actually working quite well and still leaves the main HTML content of the page on the left. That drop-down menu solution does look pretty sleek though so I will give that a shot.
 
Top Bottom