Siter is a static website generator written in Python 3, "Markdown with macros and variables" for my own simple needs.
$ siter new hello-world
$ tree hello-world/
hello-world/
βββ siter-pages
βΒ Β βββ index.md
βββ siter-template
βββ page.html
$ cat hello-world/siter-pages/index.md
{{!siter-def {{title}} {{Home Page}}}}
*Hello World!*
$ cat hello-world/siter-template/page.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="generator" content="Siter">
<title>{{!title}}</title>
</head>
<body>
{{!siter-md {{!siter-content}}}}
</body>
</html>
$ siter gen hello-world
$ tree hello-world/
hello-world/
βββ siter-out
βΒ Β βββ index.html
βββ siter-pages
βΒ Β βββ index.md
βββ siter-template
βββ page.html
$ cat hello-world/siter-out/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="generator" content="Siter">
<title>Home Page</title>
</head>
<body>
<p><em>Hello World!</em></p>
</body>
</html>
$ siter serve hello-world
A block is text enclosed between {{
and }}
. If the first character in a block is the evaluation marker !
, then the block is evaluated as a macro or variable. So {{!siter-modified %Y}}
might expand to 2099
if you're a time traveller, but {{siter-modified %Y}}
without the !
would just be replaced with the string literal siter-modified %Y
.
{{!siter-def {{image-album}} {{images}} {{
<div>
{{!images}}
</div>
}}}}
{{!siter-def {{image-element}} {{file text}} {{
<img src="media/{{!file}}" title="{{!text}}" alt="{{!text}}">
}}}}
{{!image-album
{{!image-element {{landscape.jpg}} {{A painting}}}}
{{!image-element {{ufo.jpg}} {{A photo}}}}
}}
<div>
<img src="media/landscape.jpg" title="A painting" alt="A painting">
<img src="media/ufo.jpg" title="A photo" alt="A photo">
</div>
When a macro takes a single argument like image-album
does above, you may ommit block tags around the argument for brevity.
All the built-in definitions start with siter-
.
Variable | About | Example |
---|---|---|
siter-content |
The evaluated page content, used by siter-template/page.html . |
<html><body>{{!siter-content}}</body></html> |
siter-generated |
YYYY-MM-DD date when the HTML file in siter-out was generated. |
<footer>Page generated on {{!siter-generated}}</footer> |
siter-modified |
YYYY-MM-DD date when the source file in siter-pages was last modified. |
<footer>Page updated on {{!siter-modified}}</footer> |
siter-name |
The page file name without extension. | <h1>{{!siter-name}}</h1> |
siter-path |
The page file path relative from root. | You are at {{!siter-path}} |
siter-root |
Relative path from the current page to the website root, so you can reference static files from nested pages. | <img src="{{!siter-root}}/photos/cloud.jpg"> |
Macro | About | Example |
---|---|---|
siter-def |
Bind a new macro or variable. | {{!siter-def {{page-title}} {{Home Page}}}} |
siter-if |
{{!siter-if {{flag}} {{then}} {{else}}}} evaluates {{then}} if the flag variable was previously declared ({{!siter-def flag}} ), or to {{else}} otherwise. The else block is optional. |
{{!siter-if {{show-heading}} {{<h1>Welcome!</h1>}}}} |
siter-md |
Runs Markdown on the supplied argument. | {{!siter-md **Hello world!**}} |
siter-anchor |
Makes the text argument suitable to use as an HTML anchor. | <a href="#{{!siter-anchor Hello World}}">Permalink</a> |
siter-datefmt |
Format a YYYY-MM-DD date with a Python time format string. |
<footer>Page last updated {{!siter-datefmt {{!siter-modified}} {{%b %Y}}}}</footer> |
siter-foreach |
Formats and chains files from a subdir under siter-foreach with a template file from siter-template . Takes an optional number limit. |
{{!siter-foreach {{news}} {{news.html}} {{10}}}} |
hello-world/
βββ siter-config/ # [Optional] Global definitions
βββ siter-foreach/ # [Optional] Markdown source files
βββ siter-out/ # [Required] The generated website
βββ siter-pages/ # [Required] Markdown source pages
βββ siter-static/ # [Optional] Static content
βββ siter-template/ # [Required] HTML templates
Siter uses Python-Markdown (with CodeHiliteExtension, FencedCodeExtension, and TocExtension) and Pygments for text formatting and code syntax highlighting, along with enum, http.server, os, shutil, socketserver, subprocess, sys, threading, time, and traceback from the standard library.
sudo apt install python3 python3-markdown python3-pygments
Copyright 2011-2025 Alex Margarit (alex@alxm.org)
Licensed under GNU GPL 3.0 (see COPYING
).