Documentation

Tag: markdown

Markdown site directory structure

Markdown site directory structure A Markdown site in Everlock is a Git repository. Every file you push is either served directly, rendered as a page, or used as site infrastructure. This page explains what each file and directory does, why it exists, and how Everlock treats it. The rules described here only apply to sites running in markdown mode. In html mode, all files are served as-is and none of this structure is interpreted. --- Top-level overview A minimal but fully functional site might look like this: my-site/ ├── site.toml ├── index.md ├── about.md ├── assets/ │ └── style.css ├── images/ │ └── logo.svg ├── layouts/ │ ├── base.html │ ├── single.html │ └── list.html ├── shortcodes/ │ └── callout.html └── docs/ ├── _index.md ├── getting-started.md └── reference.md More complex sites add data/, format variant templates, and additional section directories. --- site.toml — site-wide configuration site.toml at the root configures global metadata and structural behavior. Everlock reads it on every request; you do not need to restart to see changes. title = "My Site" description = "A site served by Everlock" base_url = "https://example.com" timezone = "Europe/Berlin" paginate_by = 12 sitemap = true ignore_dirs = ["out", "vendor"] [nav] links = [ { label = "Home", url = "/" }, { label = "Docs", url = "/docs/" }, { label = "About", url = "/about" }, ] [markdown] syntax_highlighting = true highlight_style = "InspiredGitHub" [taxonomies] category = "categories" | Field | Purpose | |---|---| | title | Site name used in <title> tags and templates | | description | Default meta description for all pages | | base_url | Absolute URL base, used for sitemap and RSS | | timezone | Optional IANA timezone name used by template date helpers such as today() and date_format; defaults to UTC when omitted | | paginate_by | Items per page on list pages; omit to disable pagination | | sitemap | Set to true to serve /sitemap.xml; defaults to false. Requires base_url for correct absolute URLs. Each URL's <lastmod> is the page's frontmatter date, or the date of its last content change when none is set | | nav.links | Navigation items available to templates as site.nav.links | | markdown.syntax_highlighting | Toggle code block syntax highlighting | | markdown.highlight_style | Name of a Syntect highlight theme | | taxonomies | Custom taxonomy fields; each key maps a URL prefix to a frontmatter field | | ignore_dirs | Root-relative directories to skip when scanning markdown and serving files; defaults to [] | site.toml is internal infrastructure. It is never served over HTTP. Ignored directories In markdown mode Everlock automatically skips any path component that starts with a dot (for example .git/, .cursor/, .venv/). Files under those directories never become pages, never appear in section listings, and are not served as static assets. Use ignore_dirs to extend that filter to non-hidden directories — typical candidates are generated output folders or vendored dependencies you keep in the repo for tooling but do not want published: ignore_dirs = ["out", "vendor", "generated/cache"] Entries are root-relative and match a directory and everything beneath it. --- index.md — the root page The file index.md at the root of the repository becomes the page at /. It is the only page that lives at the root without a directory. index.md → / Example: --- title: My Site date: 2026-01-01 --- Welcome This is the home page. If you want a section directory to have its own landing page, use _index.md inside that directory instead (see below). --- _index.md — section metadata and landing pages _index.md is a special file that lives inside a section directory. It is not a regular content page. It provides: - a title for the generated section listing - optional introductory content displayed above the list of child pages - an optional layout override for the section listing template - a draft flag to suppress the section docs/ ├── _index.md ← section metadata ├── getting-started.md └── reference.md When you visit /docs/, Everlock: 1. reads docs/_index.md for the section title and intro 2. lists all child .md files in docs/ as a generated page index 3. uses the layout: from _index.md (or falls back to list.html) 4. never exposes _index itself as a link in the listing Example _index.md: --- title: Documentation layout: blog_list --- The full reference for running and extending Everlock. Without a _index.md, the section title defaults to the URL path and no intro text is shown. The listing still works. Choosing a section layout By default, section listings use list.html. To use a different template, set layout: in _index.md: --- title: Project updates layout: blog_list --- This tells Everlock to render the /updates/ listing with layouts/blog_list.html instead of layouts/list.html. The blog_list.html template receives the same page, pages, and pagination context variables as list.html. --- Regular content pages Any .md file that is not index.md or _index.md becomes a content page at a URL derived from its path: about.md → /about docs/reference.md → /docs/reference updates/2026-01-15-release.md → /updates/2026-01-15-release Subdirectories become URL segments automatically. You do not need to register routes. Requests for a legacy .html address are caught automatically: when no such file exists in the repo but the markdown source does, Everlock redirects to the extensionless route — /about.html redirects to /about, and /docs/index.html redirects to /docs. Sites migrated from generators that publish .html URLs (such as Hugo with uglyurls) keep their inbound links working without any redirect configuration. Frontmatter Every page can have a YAML frontmatter block at the top: --- title: My page title date: 2026-01-15 tags: [guide, setup] categories: reference draft: false layout: article description: A short description for search and meta tags. series: - getting-started-series my_custom_key: some value --- Page content starts here. | Field | Meaning | |---|---| | title | Page title shown in <title>, headings, and listings | | date | Publication date; used for sorting and RSS | | tags | List of tags; powers /tags/ routes automatically | | draft: true | Hides the page from listings, search, RSS, and direct access | | layout | Template name (without .html) inside layouts/; defaults to single.html | | description | Per-page meta description; falls back to site.toml description | | series | List of series names this page belongs to; enables prev/next navigation | Any key not in the set above becomes an extra field available to templates as page.extra.your_key. Any key whose value is a YAML list of strings becomes available as page.extra_lists.your_key. This is how series and custom taxonomies work. Draft pages Setting draft: true excludes the page from all generated output: it will not appear in listings, the search index, RSS, sitemaps, or tag pages. It is also not accessible over HTTP directly. --- title: Work in progress draft: true --- Content here is invisible until draft is removed. ---

Taxonomies and tag pages

Taxonomies are a way to group pages by shared properties. Every Markdown site automatically gets a tag taxonomy at `/tags/`. You can define additional taxonomies — such as categories, authors, or seri

Writing and customizing templates

Writing and customizing templates Everlock uses [Tera](https://keats.github.io/tera/) as its template engine. Tera's syntax is similar to Jinja2 and Django templates. Templates live in the layouts/ directory of your site repository. This page explains the syntax, the context variables available in each template, and common customization patterns. Template syntax basics Output a variable <h1>{{ page.title }}</h1> Double braces output the value of a variable. Any HTML in the value is escaped by default. Output raw HTML safely <div class="content"> {{ page.content | safe }} </div> The | safe filter tells Tera the value is already trusted HTML and should not be escaped. Use this for rendered Markdown content. Conditionals {% if page.git_date %} <p class="meta">Updated {{ page.git_date }}</p> {% endif %} {% if page.tags %} <ul> {% for tag in page.tags %} <li><a href="/tags/{{ tag }}">{{ tag }}</a></li> {% endfor %} </ul> {% endif %} Loops {% for link in site.nav.links %} <a href="{{ link.url }}">{{ link.label }}</a> {% endfor %} Default values <time>{{ p.git_date | default(value=p.date) | default(value="") }}</time> Filters chain left to right. | default(value=x) substitutes x when the left side is empty or undefined. String filters {{ page.title | upper }} {{ tag | replace(from="-", to=" ") | title }} Common Tera filters: upper, lower, title, trim, replace, truncate, length, first, last. Date helpers Everlock adds a small date layer on top of Tera for Markdown sites: <p>Now: {{ now() }}</p> <p>Today: {{ today() }}</p> {% if page.date is before(date=now()) %} <p>This page date is in the past.</p> {% endif %} <time>{{ page.date | date_format(format="%Y-%m-%d") }}</time> Accepted input formats: - YYYY-MM-DD - RFC3339 timestamps such as 2026-06-11T08:30:00Z today() and date-only comparisons use the site timezone from site.toml. If no timezone is set, Everlock falls back to UTC. --- Template inheritance Every template in Everlock extends base.html. The pattern uses {% extends %} and {% block %}: layouts/base.html defines named blocks: <!doctype html> <html> <head> <title>{% block title %}{{ page.title }} | {{ site.title }}{% endblock %}</title> </head> <body> <nav> {% for link in site.nav.links %} <a href="{{ link.url }}">{{ link.label }}</a> {% endfor %} </nav> <main> {% block main %}{% endblock %} </main> </body> </html> layouts/single.html fills in the block: {% extends "base.html" %} {% block main %} <article> <h1>{{ page.title }}</h1> <div class="content">{{ page.content | safe }}</div> </article> {% endblock %} Any block not overridden in the child template renders from the parent. A child can call {{ super() }} to include the parent block's content and then add to it. --- Context variables reference Available in all templates | Variable | Type | Content | |---|---|---| | site.title | string | Site title from site.toml | | site.description | string | Site description from site.toml | | site.base_url | string | Base URL from site.toml | | site.timezone | string | Optional site timezone used by today() and date formatting | | site.nav.links | list | Navigation links, each with .label and .url | | data | map | All .toml files from the data/ directory | In single.html (content pages) | Variable | Type | Content | |---|---|---| | page.title | string | Title from frontmatter | | page.content | string | Rendered HTML of the page body | | page.summary | string | HTML of content before

Site backend

The site backend lets Everlock host websites directly from Git-backed content stores. Each site is mapped to one or more hostnames and backed by a repository that holds the actual content. Push change

2026-05-20 sites markdown backend

This site on Everlock

This public website is itself hosted by an Everlock instance. That matters because the site is not only talking about Everlock. It is also a working example of how Everlock hosts a documentation site.