This script uses a template to generate a static set of html files. I use this script
to generate my site!!.

you will need to have a base.html file in the templates/ directory that includes something
like this:

<div class="contained">
    {% for content in page_data.contents %}
        {% if content == '{{break}}\n' %}
            <div class="main-content-break"><br></div>
        {% else %}
            <div class="main-content">{{content}}</div>
        {% endif %}
    {% endfor %}
Note: the div classes can be changed however you want. you can find the styles being used
here by looking at this page's source

This script uses python3.10.7 and jinja2 3.1.2

Here's the code:

import os, shutil
from jinja2 import Environment, FileSystemLoader

# StaticSiteGen-J  by  max74.25  (
# StaticSiteGen-J © 2022 by max74.25 is licensed under CC BY-NC-SA 4.0
# You can find a copy of the license at

# Version 1

# Next Steps:
#  - Check what media is used by the files and package this (grab remote files, etc)
#  -

# Project Structure
# .  -- where this file is
# ./src/  -- where the input html files are
# ./templates/  -- where the template files are (the only one used is base.html)
# ./output/  -- this directory will be populated with the output of this script

class StaticSiteGenerator:
    source_directory = './src/'
    template_directory = './templates/'
    output_directory = './output/'

    def process_content(self, filename):
        lines = []
        output_lines = []
        title = 'pageName'  # the default title that is used if one isnt defined in the input file
        title_unset = True
        with open(filename, 'r') as file:
            lines = file.readlines()
        if lines != []:
            output_line = ''
            for line in lines:
                if '{{title}}' in line and title_unset:  # a line with this tag defines the title the page should have
                    title = line.replace('{{title}}', '').strip()
                    title_unset = False
                elif not '{{break}}\n' in line:  # a line with this tag will become a stylised page break
                    output_line += str(line) + '\n'
                    # keep this on a seperate var in list to make sure it gets picked up properly
                    # (the newline is so instances (like in this script) dont get picked up falsely)
                    output_line = ''
        return {'contents': output_lines, 'title': title}

    def __init__(self):
        env = Environment(loader=FileSystemLoader(self.template_directory))
        base_template = env.get_template('base.html')

        if os.path.exists(self.output_directory):

        for (root, directory, files) in os.walk(self.source_directory):
            if not os.path.exists(os.path.join(root).replace(self.source_directory, self.output_directory)):
                os.mkdir(os.path.join(root).replace(self.source_directory, self.output_directory))

            for file in files:
                path = os.path.join(root, file)
                out_path = os.path.join(root, file).replace(self.source_directory, self.output_directory)
                if path.endswith('.html'):
                    # if the file is html, render it into the template (it likes inserting double newlines for some reason)
                    output = base_template.render(page_data=self.process_content(path)).replace('\n\n', '\n')
                    with open(out_path, 'w') as out_file:
                    # otherwise, just copy the file
                    shutil.copy(path, out_path)

if __name__ == '__main__':
    s = StaticSiteGenerator()

StaticSiteGen-J by max74.25 is licensed under CC BY-NC-SA 4.0