diff --git a/docs/template.md b/docs/template.md
index e69de29..aee92af 100644
--- a/docs/template.md
+++ b/docs/template.md
@@ -0,0 +1,110 @@
+# Templating
+
+## Variables
+
+By default, these variables are given to a CMS view:
+
+* `_node`: the current node (`App\Core\Entity\Site\Node`)
+* `_page`: the current page (`App\Core\Entity\Site\Page\Page`)
+* `_menu`: the menu of the current node (`App\Core\Entity\Site\Menu`)
+* `_navigation`: the current navigation (`App\Core\Entity\Site\Navigation`)
+* `_domain`: the current domain
+* `_locale`: the current locale
+* `_store`: an instance of `App\Core\Site\SiteStore`
+
+## Page
+
+You can access a page's blocks this way:
+
+```
+{% set myBlock = _page.myBlock.value %}
+
+{{ myBlock }}
+```
+
+## Menu
+
+### Retrieve all menus
+
+```
+{% set menus = _navigation.menus %}
+```
+
+### Retrieve a specific menu:
+
+```
+{% set menu = _navigation.menu('menu_code') %}
+```
+
+### Display a menu
+
+```
+{% set menu = _navigation.menu('menu_code') %}
+
+
+ {% for item in menu.rootNode.children %}
+ {% if item.isVisible %}
+ {% set isActive = _store.isActiveNode(item, true) %}
+
+ -
+ {% if not item.disableUrl %}
+ {% set url = item.hasExternalUrl ? item.url : url(node.routeName, {_domain: domain}) %}
+ {{ item.label }}
+ {% else %}
+ {{ item.label }}
+ {% endif %}
+
+ {% set children = node.allChildren %}
+
+
+ {% for child in children %}
+ ...
+ {% endfor %}
+
+
+ {% endif %}
+ {% endfor %}
+
+```
+
+## URL and path
+
+Murph has somes twig functions to manage URLs:
+
+### Generic functions
+
+* Same as [twig url](https://symfony.com/doc/current/reference/twig_reference.html#url) but catches all exceptions:
+ `{{ safe_url(routeName, options, relative) }}`: same as [twig url](https://symfony.com/doc/current/reference/twig_reference.html#url) but catches all exceptions
+* Same as [twig url](https://symfony.com/doc/current/reference/twig_reference.html#path) but catches all exceptions:
+ `{{ safe_path(routeName, options, relative) }}`
+
+### Node functions
+
+* Generates a URL using a node:
+ `{{ node_url(node, options, relative) }}`
+* Generates a path using a node:
+ `{{ node_path(node, options, relative) }}`
+* Generates a URL using a node and catches all exceptions:
+ `{{ safe_node_url(node, options, relative) }}`
+* Generates a path using a node and catches all exceptions:
+ `{{ safe_node_path(node, options, relative) }}`
+
+### Filters
+
+When a content could contains tags (eg: '{{url://my_route}}`), use `murph_url`. This the example below:
+
+| Code | Output |
+| ---- | ------ |
+| `{{ content }}` | `A link to the contact page` |
+| `{{ content|murph_url }}` | `A link to the contact page` |
+
+## String builder
+
+The string builder builds a string using a format and an object or an array.
+
+Examples:
+
+* `{{ 'Entity ID is {id}'|build_string(myEntity) }}` will output: `Entity ID is 42`
+* `{{ 'Hello, {user.displayName}!'|build_string(myEntity) }}` will output `Hello, John doe!`
+
+In case of an not accessible property, no exception will be thrown.