# 03. __Navigation__

[![+Professional Support](https://www.totaljs.com/img/badge-support.svg)](https://www.totaljs.com/support/) [![+Chat with contributors](https://www.totaljs.com/img/badge-chat.svg)](https://messenger.totaljs.com)

Each navigation needs to be defined in some `template`. The entire functionality of navigation is stored in the model `/models/navigations.js`.

__What should i know?__

- navigation can contain links with advanced settings
- navigation needs to be rendered manually
- all navigations are loaded into the memory when the app is started

## Create navigation

Each navigation needs to be defined in `templates` (__Pages__ section) and templates can contain unlimited counf of navigations, for example: `mainmenu`, `footer`, etc..

__Example__:

```html
@{navigation mainmenu:Main menu}
@{navigation footer:Footer menu}

<!DOCTYPE html>
<html>
	<head>
	...
```

- navigation must be defined via `@{navigation ID:NAME}` command in the page template
- navigation must be rendered manually by developer
- navigation is automatically created when the template is submitted
- CMS merges all navigations together according to the `ID`

## Add links

Links need to be added into the navigation manually. Just open `Pages` section and choose your navigation in the right panel. CMS shows all registered navigations:

![Navigations](/download/B20200130T000000030.png)

__Good to know__:
Some links can be linked automatically if the user choose a page according to the sitemap. User can specify in the Page settings what fields can be synchronized in navigations:

![Navigation in Page settings](/download/1711260952T2rqpv.png)

## Rendering

Navigations are stored in a global static object: `F.global.navigations` and each navigation needs to be rendered manually.

__Navigation item__:

```javascript
// var nav = MAIN.navigations.navigation_id;
// For example:
var nav = MAIN.navigations.mainmenu;

nav.url;
// Contains relative URL addresses. It's a quick access to rendering sub-links according to the URL
// returns {Array Object}

nav.children;
// Contains all registered links
// returns {Array Object}

nav.dateupdated;
// The last date of update
// returns {Datetime}

nav.stringify();
// Serializes this navigation to JSON
// returns {String}
```

__Link object__:

```javascript
var item = nav.url['/products/'];
// or
var item = nav.children[0];

item.parent;
// Contains a parent of this item and returns same object structure
// returns {Object}

item.level;
// Contains a number of level
// returns {Number}

item.children;
// Contains all children with same structure as this object
// returns {Array Object}

item.url;
// A link URL address
// returns {String}

item.name;
// A link name
// returns {String}

item.title;
// A title for tooltip
// returns {String}

item.target;
// A value for link "_target", can contain "_self" or "_blank"
// returns {String}

item.icon;
// An icon (font-awesome without "fa-")
// returns {String}

item.idpage;
// Page ID according to the sitemap
// returns {UID}

item.id;
// Unique identificator of link
// returns {String}

item.behaviour;
// This property can contain these values "default", "info", "warn", "highlight" or "special"
// This feature needs to be coded manually
// returns {String}

item.contains(url, [absolute]);
// Determines whether this item contains "url". It's a great solution for highlighting item in navigation
// @url {String} Relative URL address
// @absolute {Boolean} Only compares this item and its all childs (default: false)
// returns {Boolean}
```

## Rendering in views

I recommend to render a navigation in a `layout`, but navigation can be rendered everywhere. Just follow your needs.

__Quick rendering:__

```html
@{foreach m in MAIN.navigations.mainmenu.children)
	<a href="@{m.url}">@{m.name}</a>    
@{end}
```

__Wich icon, tooltip and target:__

```html
@{foreach m in MAIN.navigations.mainmenu.children}
	<a href="@{m.url}"@{if m.target === '_blank'} target="_blank"@{fi}@{if m.title} titlte="@{m.title}"@{fi}>@{if m.icon}<i class="fa fa-@{m.icon}"></i>@{fi}@{m.name}</a>    
@{end}
```

__With the first-level of children:__

```html
<nav>
@{foreach a in MAIN.navigations.mainmenu.children}

	<a href="@{a.url}">@{a.name}</a>
 
	@{if a.children.length}
		<nav>
		@{foreach b in a.children}
			<a href="@{b.url}">@{b.name}</a>
		@{end}
		</nav>
	@{fi}
	
@{end}
</nav>
```

__Render children according to the URL__:

```html
@{if MAIN.navigations.mainmenu.url[url] && MAIN.navigations.mainmenu.url[url].parent}

	<nav>
	@{foreach a in MAIN.navigations.mainmenu.url[url].parent.children}

		<a href="@{a.url}">@{a.name}</a>

		<!-- Rendering the first-level of children -->
		@{if a.children.length}
			<nav>
			@{foreach b in a.children}
				<a href="@{b.url}">@{b.name}</a>
			@{end}
			</nav>
		@{fi}
		
	@{end}
	</nav>

@{fi}
```