Navigation
Now you should have a working site. However there is no way for a user to move between the pages of the site if they don't know exactly the url of the page. Through the power of Jinja2 templates we will now address this problem.
Let's now modify a little our template
...
<body>
{{page}}
<hr>
{{site}}
</body>
</html>
If you try to see the site in the browser you will see a very strange page.
Instead of your page now there are two python dictionaries.
That's because page
and site
are two dictionaries that are passed to every page, and the templates have to use this information to display the page.
We can see that the page
dictionary as a content
field and this is what we use to display what we have written.
The most interesting thing however is the site
dict.
In it there is a pages
field containing all the pages of our site.
We can use this information to create a header to navigate through the pages.
In general everytime you don't know how to add a certain feature to your site you should print what information is available to a page, because most of the things can be done simply using Jinja2 templates.
Let's now modify our template so that we can navigate through our site.
...
<body>
<nav>
{% for slug in site.pages %}
{% if url(slug) == page.url%}
<a href="{{ url(slug) }}" style="color: red">{{site.pages[slug].title}}</a>
{% else %}
<a href="{{ url(slug) }}">{{site.pages[slug].title}}</a>
{% endif %}
{% endfor %}
</nav>
<h1>{{page.title}}</h1>
{{page.content|html}}
</body>
</html>
This template is a little more complicated than the previous one. In the navigation part we iterate through each page slug (the slug is the page identifier), then we check if the slug corrisponds to the current page, so that we can style that url differently. Then we create a new link.
To print the page title we first have to retrieve the page with its slug (site.pages[slug]) then we print the title.
To obtain the location of the page we pass the slug to the url
function.
We could also have used simply the url
field of a page, just like this
<a href="{{ site.pages[slug].url }}">{{site.pages[slug].title}}</a>
However this is not recommended, as the url function makes the link absolute instead of relative, and this makes a big difference when the site grows.
Site name
In our navigation bar, other than the link to other pages, we should also have the name of our site.
We could hardcode it in our template but there is a better way. If we look in the site
dictionary we can see that there is a config
dictionary, and in it a field called name
.
It contains the name of the site, and it can be accessed from anywhere in our templates.
To use it we have to modify our template
...
<nav>
{{config.name}}
{% for slug in site.pages %}
...
If we see the page in the browser now there should be the word Example
before our links.
That's because it is the default name of the site if none is specified.
To set its value we have to modify main.py
...
k.config['name'] = 'The name of your site'
k.run()
Now there should be the name of your site on the top of every page!