how to create a static site with python

  1. first up, I strongly recommend you try pelican.

  2. prepare directory structure

    mkdir content output templates
  3. prepare templates

    cd templates

    cat index.html

    {% extends "layout.html" %}
    {% block content %}
    {% for post in posts %}
            <h2>{{loop.index}}: <a href="posts/{{ post.title }}.html">{{post.title}}</a> </h2>
    {% endfor %}
    {% endblock %}

    cat post.html

    {% extends "layout.html" %}
    {% block content %}
    {% endblock %}

    cat layout.html

    <!DOCTYPE html>
    <html lang="en">
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <body class="container">
        {% block content %} {% endblock %}
  4. prepare code


    import os
    from jinja2 import Environment, FileSystemLoader
    from markdown2 import markdown
    POSTS = {}
    for markdown_post in os.listdir('content'):
        file_path = os.path.join('content', markdown_post)
        with open(file_path, 'r') as file:
            POSTS[markdown_post] = markdown(, extras=['metadata'])
    POSTS = {
        post: POSTS[post] for post in sorted(POSTS, key=lambda post: POSTS[post].metadata['title'])
    env = Environment(loader=FileSystemLoader('templates'))
    index_template = env.get_template('index.html')
    post_template = env.get_template('post.html')
    posts_metadata = [POSTS[post].metadata for post in POSTS]
    index_html = index_template.render(posts=posts_metadata)
    with open('output/index.html', 'w') as file:
    os.makedirs('output/posts/', exist_ok=True)
    for post in POSTS:
        post_metadata = POSTS[post].metadata
        post_data = {
            'title': post_metadata['title'],
            'content': POSTS[post]
        post_html = post_template.render(post=post_data)
        post_file_path = 'output/posts/{title}.html'.format(title=post_metadata['title'])
        with open(post_file_path, 'w') as file:
  5. copy to a web server

    cp -r output/* /var/www/html/