Aug 18, 2023
I wanted to create a sub navigation tree on the left side in Lektor CMS for a menu item.
It should look and behave similiar to the the documentation menu in Lektor itself: https://www.getlektor.com/docs/
It took me a moment to understand how to achieve that
Starting with Lektor's Quickstart project as an example I made the necessary adjustments for the project page.

The whole Lektor project can be downloaded from here.
Two Column Layout
I used a suggestion from W3schools how to divide the various elements such as header, footer, container, navigation tree (left) and content (right): https://www.w3schools.com/css/css_website_layout.asp

I adjusted the cascading style sheet file accordingly with header, footer, .page, .leftcolumn, .rightcolumn.
styles.css:
* {
box-sizing: border-box;
}
body {
font-family: 'Verdana', sans-serif;
padding: 10px;
margin: 0 auto;
width: 80%;
}
header,
footer,
.page {
padding: 10px;
background: #daeef3;
overflow: hidden;
}
footer {
font-size: x-small;
}
header,
footer,
.center {
text-align: center;
}
header h1 {
color: #169bbd;
margin: 0;
font-weight: normal;
font-size: 42px;
}
nav ul {
list-style: none;
margin: 0;
padding: 0;
}
nav a {
float: left;
display: block;
text-align: center;
padding: 14px 16px;
text-decoration: none;
color: #2a99b6;
}
nav a:hover {
color: #33bbdf;
text-decoration: underline;
}
/* Create two unequal columns that floats next to each other */
/* Left column */
.leftcolumn {
font-size: 0.85em;
float: left;
width: 16%;
}
/* Right column */
.rightcolumn {
float: left;
width: 84%;
padding-left: 20px;
}
.leftcolumn ul {
list-style: none;
}
.leftcolumn a {
text-decoration: none;
color: #2a99b6;
}
.leftcolumn a:hover {
color: #33bbdf;
text-decoration: underline;
}
.leftcolumn .active,
nav .active {
color: #33bbdf;
}
.rightcolumn p {
white-space: pre-line;
}
.rightcolumn strong {
color: #169bbd;
font-weight: normal;
}
/* Clear floats after the columns */
.page::after {
content: "";
display: table;
clear: both;
}
@media screen and (max-width: 1200px) {
body {
width: 90%;
}
}
@media screen and (max-width: 960px) {
body {
width: 100%;
}
}
/* Responsive layout - when the screen is less than 800px wide, make the two columns stack on top of each other instead of next to each other */
@media screen and (max-width: 800px) {
.leftcolumn,
.rightcolumn {
width: 100%;
padding: 0;
}
}
/* Responsive layout - when the screen is less than 400px wide, make the navigation links stack on top of each other instead of next to each other */
@media screen and (max-width: 400px) {
nav a {
float: none;
width: 100%;
}
}
Model
The new model I created is projects.ini.
projects.ini
[model]
name = Projects
label = {{ this.title }}
hidden = yes
[children]
model = projects
order_by = sort_key, title
[fields.title]
type = string
[fields.body]
type = markdown
[fields.hidden]
type = boolean
default = false
Template File
I created an new template file for the projects. It extends base template layout.html and creates a navigation on the left side (CSS class leftcolumn) and the contents column on the right (CSS class rightcolumn).
The navigation menu for the projects is generated with Jinja 2 (according to the Lektor documentation here).
projects.html
{% extends "layout.html" %}
{% block title %}{{ this.title }}{% endblock %}
{% block body %}
<div class="leftcolumn">
<ul>
{% set root = site.get('/projects') %}
{% for child in root.children recursive %}
<li>
<a href="{{ child|url }}" {% if this.path == child._path %} class="active" {% endif %}>{{ child.title }}
</a>
</li>
{% endfor %}
</ul>
</div>
<div class="rightcolumn">
<h2>{{ this.title }}</h2>
{{ this.body }}
</div>
{% endblock %}