How to create a static web

2019-03-12
Web html Blog Flask Python



Here you can learn how to create a static webpage using Flask. Check the full example on github.

You only need some html knowledge.

1. Install requirements

Run:

pip install -r requirements.txt

This will install the following libraries:

flask: to create the webpage
frozen-flask: to make it static
markdown: to transform from markdown to html
oyaml: to work with ordered yamls
pygments: to display beautiful code snipets when transforming markdown

2. html templates

The first thing you will need are some html templates. I suggest that you use at least one base.html as the basic template and then other templates for each page.

The base.html file should have the basic structure, for example:

src/templates/base.html
<!DOCTYPE html>
<html lang="en">
  <title>Test page</title>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <!-- Custom styles -->
  <link rel="stylesheet" href="{{ url_for('static', filename='villoro.css') }}">

  <body>
    <!-- Add children body -->
    {% block body %}{% endblock %}
  </body>
</html>

The template I created in github has a navbar and footer but the basics are the same.

Then we can create the about.html page template using:

src/templates/about.html
{% extends "base.html" %}

{% block body%}
  <div class="w3-content w3-padding">
    <h1>{{ title }}</h1>

    {% autoescape false %} {{ description }} {% endautoescape %}

  </div>
{% endblock %}

{{ title }} and {{ description }} are parameters that we will pass to the flask template.

3. Flask app and freezer

The index.py will be the actual Flask app. It will only render the templates.

src/index.py
from flask import Flask, render_template

@APP.route("/about.html")
def about():
    """ about me page """

    return render_template("about.html", title="Title1", description="Hello world")

if __name__ == "__main__":
    APP.run(debug=True)

As you can see we are passing title and description as parameters as commented before.

Now you can run python src/index.py to view the app at localhost:5000.

Then you can create the freeze.py file that will create the static html files.

src/freeze.py
from flask_frozen import Freezer
from index import APP

FREEZER = Freezer(APP)


if __name__ == "__main__":
    FREEZER.freeze()

Now if you run python src/freeze.py you will crate the folder src/build with the static webpage.

4. Using yamls

In order to make it easier to customize the pages I suggest using yaml files. They are like json files but more compact.

For example you can create the file about.yaml with:

src/content/about.yaml
title: Title 1
description: Hello **world**

I suggest that you also transform the description from markdown to html since it will give you more flexibility. To do all of that you should modify the file index.py to read that yaml.

src/index.py
import oyaml as yaml

from markdown import markdown
from flask import Flask, render_template

APP = Flask(__name__)


def _read_yaml(filename):
    """ auxiliar function to raad a yaml """

    with open(f"src/content/{filename}.yaml", encoding="utf-8") as file:
        out = yaml.load(file)

    # Transform from markdown to html
    if "description" in out:
        out["description"] = markdown(out["description"], extensions=["fenced_code", "codehilite"])

    return out

@APP.route("/about.html")
def about():
    """ about me page """

    return render_template("about.html", **_read_yaml("about"))


if __name__ == "__main__":
    APP.run(debug=True)

5. css and images

To use custom css files and/or images simply place them in the folder src/static/. For using them you can:

<!-- Use a css -->
<link rel="stylesheet" href="{{ url_for('static', filename='file.css') }}">

<!-- Use an image -->
<img src="/static/image.jpg" alt="image"/>

6. Hosting the webpage

I strongly recommend using Netlify since they do a lot of things for free. Some of them you probably didn't know that you should do them (or at least I didn't).

It is really easy to set up. The most imporant steps are:

  1. Login with your github account.
  2. Link to the repository where you have the project
  3. Tell the build command (which should be python src/freeze.py)

And with that you will have your custom static webpage up and running. It will be very fast and very customizable.