# Pages, layouts, navigation, variables and redirects in the Total.js CMS

> How the CMS turns a layout and a page into a public address: the element with id CMS, the fields of a page, variables, navigation scripts written with Tangular, redirects, the sitemap and which pages are visible.

Framework: cms
Product: CMS (cms@8071e48)
Language: en
Content-SHA256: 6dafba700a2c7e3e5e54ec031945442938cecfc7f1ff1b34d5c5aba4024662cf
Snapshot: c0700e321579725c5cf4f5ace1ad7d2866d1b4f93c24a63c0b41b6b7998e976c
Sources: 
Review: not-recorded

The CMS keeps the HTML of every layout and page as a file and its data (address, title, layout...) in the metadata of the site. A request to the public site finds a page by its address and renders it inside its layout.

## Layouts

A **layout** is a full HTML document. The element with `id="CMS"` marks the place where the content of the page goes:

```html
<!DOCTYPE html>
<html>
<head>
	<meta charset="utf-8">
</head>
<body>
	<header>$SITE</header>
	<div id="CMS"></div>
	<footer>@{year}</footer>
</body>
</html>
```

`Layouts/save` takes `name`, `icon`, `color`, `html` and a list of `scripts` that are added to every page of the layout. In the HTML, `$NAME` is replaced by the **variable** of that name (see below) and `@{year}` by the current year.

## Pages

A **page** has a `name`, a `layoutid` (required), an address `url`, and optional `title`, `description`, `keywords`, `language`, `parentid`, `icon`, `color` and the flags `disabled`, `auth`, `pinned` and `nocache`. Its HTML (saved with `pages_save_html`) is what goes inside the `id="CMS"` element.

- If you leave `url` empty the CMS makes one from the name: `Hello World` becomes `/hello-world/`, and under a parent page the address starts with the address of the parent.
- The public site serves a page when its `url` equals the requested address, it is not `disabled` and its `language`, when set, equals the language of the request.
- The response gets `<title>` (the `title`, or the `name`, followed by the name of the site for every page except `/`), the description and the keywords, a script that counts the visits (`/visitors.js`) and the style of the widgets that the page uses.
- `auth` pages are served only to a signed-in visitor. The CMS asks your code who the visitor is: define `FUNC.auth = function($) { ... }` (for example in a file of `definitions/`) and call `$.success(user)`. Without that function everybody is anonymous and an `auth` page answers 404.
- A disabled page, an unknown address and a page of another language answer 404. The sitemap `/sitemap.xml` lists the pages that are not disabled.

## Variables

The plugin *Variables* keeps a list of `NAME: value` pairs (`Variables|save` with `vars`). Any `$NAME` in a layout or a page becomes its value when the page is served, which is useful for a phone number, a company name or a link that appears in many places. An unknown `$NAME` stays as written.

## Navigation

A navigation is a menu described in the admin (a name and a tree of links with `name`, `url`, `title`, `icon`, `color`, `target`, `hidden`, `highlight` and `children`) and drawn by your layout with a template written with Tangular. Put a script in the layout:

```html
<nav>
	<script type="text/navigation" name="main">
		{{ foreach m in value.children }}
			<a href="{{ m.url }}"{{ if m.url === value.url }} class="on"{{ fi }}>{{ m.name }}</a>
		{{ end }}
	</script>
</nav>
```

When the layout is saved, a navigation called `main` is created if it does not exist; then edit its links in the plugin *Navigation*. In the template, `value.children` is the list of visible links, `value.url` is the address being served. Give the script a `name`; with only an `id` the compiler accepts it but saving the layout does not answer.

There is also `<script type="text/breadcrumb">` for the trail of parent pages.

## Redirects

A redirect has a `url`, a `target` and `permanent`. The public site checks the redirects before the pages: `/old/` answered with the page of `/about/` when its target was `/about/`.

## Cache

Compiled pages are cached; saving a page, layout, widget or variable clears what depends on it, and a service that runs every two minutes also clears the compiled views.
