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;
}