Configure Template Engine

To use PH7 templates in you flask app you can use ph7.flask.PH7Templates.

from flask import Flask

from ph7.flask import PH7Templates

app = Flask(__name__)
templates = PH7Templates(templates_path="./templates")

Templates

Then you can define your views in the ./templates directory.

|_ templates
  |_ __init__.py # default/root view
  |_ dogs.py
@app.get("/")
def _home():
    return templates.render(
        name="root",
        context={},
    )

@app.get("/dogs")
def _dogs():
    return templates.render(
        name="dogs",
        context={},
    )

Stylesheets

Define your stylesheet using CSSObject and use Static Context to include the stylesheets in your views. First let's define templates/styles.py

from ph7 import CSSObject


class container(CSSObject):
    display = "flex"
    justify_content = "center"
    align_items = "center"
    flex_direction = "column"

    height = "100%"
    width = "100%"


class image(CSSObject):
    height = "200px"
    width = "400px"

    margin_bottom = "25px"

Next include the stylesheet by importing it and using one of the style classes.

from templates.script import fetchDog
from templates.styles import container, image

from ph7.context import ctx
from ph7.html import body, button, div, head, html, img

ctx.static.view(__name__)


template = html(
    head(
        ctx.static.include,
    ),
    body(
        div(
            img(
                src="#",
                id="image",
                alt="Click to fetch dog",
                class_name=image,
            ),
            button(
                "Click to fetch a dog",
                on={
                    "click": fetchDog(),
                },
            ),
            class_name=container,
        )
    ),
)

This is what the rendered view looks like

<html>
  <head>
    <link
      href="/static/css/templates_styles.css"
      rel="stylesheet"
      id="css.templates.styles"
    />
    <script
      src="/static/js/templates_script.js"
      type="text/javascript"
      id="js.templates.script"
    ></script>
  </head>
  <body>
    <div class="container">
      <img src="#" alt="Click to fetch dog" id="image" class="image" /><button
        onclick="fetchDog()"
      >
        Click to fetch a dog
      </button>
    </div>
  </body>
</html>

And this is what the rendered stylesheet looks like

.container {
  display: flex;
  justify-content: center;
  align-items: center;
  flex-direction: column;
  height: 100%;
  width: 100%;
}
.image {
  height: 200px;
  width: 400px;
  margin-bottom: 25px;
}

Note: In the final render of the stylesheet generated by static context, only the classes which have been used in a template will be included.

Scripts

Write your scripts using the ph7.js APIs.

from ph7.js import console, document, fetch, js_callable


@js_callable
async def fetchDog():
    console.log("Fetching dog")
    response = await fetch(
        "https://dog.ceo/api/breeds/image/random",
        {
            "method": "GET",
        },
    )
    data = await response.json()
    console.log("Dog fetched")
    document.getElementById("image").src = data.message

Use the function in the view

from templates.script import fetchDog
from templates.styles import container, image

from ph7.context import ctx
from ph7.html import body, button, div, head, html, img

ctx.static.view(__name__)


template = html(
    head(
        ctx.static.include,
    ),
    body(
        div(
            img(
                src="#",
                id="image",
                alt="Click to fetch dog",
                class_name=image,
            ),
            button(
                "Click to fetch a dog",
                on={
                    "click": fetchDog(),
                },
            ),
            class_name=container,
        )
    ),
)

This is what the rendered view looks like

<html>
  <head>
    <link
      href="/static/css/templates_styles.css"
      rel="stylesheet"
      id="css.templates.styles"
    />
    <script
      src="/static/js/templates_script.js"
      type="text/javascript"
      id="js.templates.script"
    ></script>
  </head>
  <body>
    <div class="container">
      <img src="#" alt="Click to fetch dog" id="image" class="image" /><button
        onclick="fetchDog()"
      >
        Click to fetch a dog
      </button>
    </div>
  </body>
</html>

And this is what the rendered script looks like

async function fetchDog() {
  console.log("Fetching dog");
  let response = await fetch("https://dog.ceo/api/breeds/image/random", {
    method: "GET",
  });
  let data = await response.json();
  console.log("Dog fetched");
  document.getElementById("image").src = data.message;
}