add header/footer template
This commit is contained in:
parent
d8b491bc33
commit
070c23720b
6 changed files with 54 additions and 17 deletions
|
@ -12,6 +12,7 @@ dependencies = [
|
|||
"jinja2>=3.1.6",
|
||||
"marko[codehilite]>=2.1.4",
|
||||
"python-frontmatter>=1.1.0",
|
||||
"rich>=14.0.0",
|
||||
"starlette>=0.47.1",
|
||||
"typer>=0.16.0",
|
||||
"uvicorn>=0.34.3",
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
from rich import print
|
||||
from zona.models import Item, Metadata, ItemType
|
||||
from zona import markdown as zmd
|
||||
from zona import templates as tmpl
|
||||
from zona.templates import Templater
|
||||
from zona import util
|
||||
from pathlib import Path
|
||||
import frontmatter
|
||||
|
@ -74,21 +75,24 @@ def discover(root: Path, out_dir: Path) -> list[Item]:
|
|||
item.destination = (
|
||||
out_dir / relative.parent / name / "index.html"
|
||||
)
|
||||
rel_url = item.destination.parent.relative_to(out_dir)
|
||||
item.url = "" if rel_url == Path(".") else rel_url.as_posix()
|
||||
items.append(item)
|
||||
return items
|
||||
|
||||
|
||||
def build(root: Path, items: list[Item]):
|
||||
env = tmpl.init_templates(root / "templates")
|
||||
templater = Templater(root / "templates")
|
||||
for item in items:
|
||||
dst = item.destination
|
||||
print(item)
|
||||
# create parent dirs if needed
|
||||
if item.type == ItemType.MARKDOWN:
|
||||
assert item.content is not None
|
||||
# parse markdown and render as html
|
||||
raw_html = zmd.md_to_html(item.content)
|
||||
# TODO: test this
|
||||
rendered = tmpl.render_item(item, raw_html, env)
|
||||
rendered = templater.render_item(item, raw_html)
|
||||
util.ensure_parents(dst)
|
||||
dst.write_text(rendered, encoding="utf-8")
|
||||
else:
|
||||
|
|
|
@ -9,9 +9,10 @@ class Metadata:
|
|||
title: str
|
||||
date: date
|
||||
description: str | None
|
||||
style: str | None = "static/style.css"
|
||||
style: str | None = "/static/style.css"
|
||||
header: bool = True
|
||||
footer: bool = True
|
||||
template: str = "page.html"
|
||||
|
||||
|
||||
class ItemType(Enum):
|
||||
|
|
|
@ -1,19 +1,48 @@
|
|||
from pathlib import Path
|
||||
from jinja2 import Environment, FileSystemLoader, select_autoescape
|
||||
from zona.models import Item
|
||||
from zona.markdown import md_to_html
|
||||
|
||||
|
||||
def init_templates(template_dir: Path) -> Environment:
|
||||
return Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
autoescape=select_autoescape(["html", "xml"]),
|
||||
)
|
||||
def get_header(template_dir: Path) -> str | None:
|
||||
md_header = template_dir / "header.md"
|
||||
html_header = template_dir / "header.html"
|
||||
if md_header.exists():
|
||||
return md_to_html(md_header.read_text())
|
||||
elif html_header.exists():
|
||||
return html_header.read_text()
|
||||
|
||||
|
||||
def render_item(item: Item, content: str, env: Environment) -> str:
|
||||
template = env.get_template("post.html")
|
||||
meta = item.metadata
|
||||
assert meta is not None
|
||||
return template.render(
|
||||
title=meta.title, content=content, url=item.url, metadata=meta
|
||||
)
|
||||
def get_footer(template_dir: Path) -> str | None:
|
||||
md_footer = template_dir / "footer.md"
|
||||
html_footer = template_dir / "footer.html"
|
||||
if md_footer.exists():
|
||||
return md_to_html(md_footer.read_text())
|
||||
elif html_footer.exists():
|
||||
return html_footer.read_text()
|
||||
|
||||
|
||||
class Templater:
|
||||
def __init__(self, template_dir: Path):
|
||||
self.env: Environment = Environment(
|
||||
loader=FileSystemLoader(template_dir),
|
||||
autoescape=select_autoescape(["html", "xml"]),
|
||||
)
|
||||
self.template_dir: Path = template_dir
|
||||
self.header: str | None = get_header(template_dir)
|
||||
self.footer: str | None = get_footer(template_dir)
|
||||
|
||||
def render_item(self, item: Item, content: str) -> str:
|
||||
env = self.env
|
||||
meta = item.metadata
|
||||
assert meta is not None
|
||||
template = env.get_template(meta.template)
|
||||
header = self.header if self.header and meta.header else False
|
||||
footer = self.footer if self.footer and meta.footer else False
|
||||
return template.render(
|
||||
content=content,
|
||||
url=item.url,
|
||||
metadata=meta,
|
||||
header=header,
|
||||
footer=footer,
|
||||
)
|
||||
|
|
|
@ -147,7 +147,7 @@ p {
|
|||
style.write_text(style_content)
|
||||
|
||||
items = discover(tmp_path, outd)
|
||||
build(items)
|
||||
build(tmp_path, items)
|
||||
html = (outd / "post" / "index.html").read_text()
|
||||
assert html.strip() == "<h1>Hello World</h1>"
|
||||
s = (outd / "static" / "style.css").read_text()
|
||||
|
|
2
uv.lock
generated
2
uv.lock
generated
|
@ -382,6 +382,7 @@ dependencies = [
|
|||
{ name = "jinja2" },
|
||||
{ name = "marko", extra = ["codehilite"] },
|
||||
{ name = "python-frontmatter" },
|
||||
{ name = "rich" },
|
||||
{ name = "starlette" },
|
||||
{ name = "typer" },
|
||||
{ name = "uvicorn" },
|
||||
|
@ -400,6 +401,7 @@ requires-dist = [
|
|||
{ name = "jinja2", specifier = ">=3.1.6" },
|
||||
{ name = "marko", extras = ["codehilite"], specifier = ">=2.1.4" },
|
||||
{ name = "python-frontmatter", specifier = ">=1.1.0" },
|
||||
{ name = "rich", specifier = ">=14.0.0" },
|
||||
{ name = "starlette", specifier = ">=0.47.1" },
|
||||
{ name = "typer", specifier = ">=0.16.0" },
|
||||
{ name = "uvicorn", specifier = ">=0.34.3" },
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue