set up web routing and templates

This commit is contained in:
evilchili 2025-09-27 16:20:08 -07:00
parent 8ec9f41b6c
commit 0ce3845a13
7 changed files with 83 additions and 16 deletions

View File

@ -6,6 +6,7 @@ from types import SimpleNamespace
from dotenv import dotenv_values from dotenv import dotenv_values
from flask import Flask from flask import Flask
from grung.db import GrungDB from grung.db import GrungDB
from grung.exceptions import UniqueConstraintError
from tinydb.storages import MemoryStorage from tinydb.storages import MemoryStorage
from ttfrog import schema from ttfrog import schema
@ -41,6 +42,8 @@ DATA_ROOT=~/.dnd/ttfrog/
ADMIN_USERNAME=admin ADMIN_USERNAME=admin
ADMIN_EMAIL= ADMIN_EMAIL=
THEME=default
""" """
def __init__(self): def __init__(self):
@ -85,7 +88,9 @@ ADMIN_EMAIL=
else: else:
self.db = GrungDB.with_schema(schema, self.path.database) self.db = GrungDB.with_schema(schema, self.path.database)
self.web = Flask(self.config.NAME) self.theme = Path(__file__).parent / 'themes' / "default"
self.web = Flask(self.config.NAME, template_folder=self.theme)
self.web.config["SECRET_KEY"] = self.config.SECRET_KEY self.web.config["SECRET_KEY"] = self.config.SECRET_KEY
self._initialized = True self._initialized = True
@ -99,10 +104,19 @@ ADMIN_EMAIL=
Bootstrap the database entries by populating the first Page, the Admin user and the Admins group. Bootstrap the database entries by populating the first Page, the Admin user and the Admins group.
""" """
self.check_state() self.check_state()
self.db.save(schema.Page(parent_id=None, stub="", title="_", body="")) try:
admin = schema.User(name=self.config.ADMIN_USERNAME, email=self.config.ADMIN_EMAIL) self.db.save(schema.Page(parent_id=None, stub="", title="_", body=""))
self.db.save(admin) except UniqueConstraintError:
self.db.save(schema.Group(name="admins", users=[admin])) pass
try:
admin = self.db.save(schema.User(name=self.config.ADMIN_USERNAME, email=self.config.ADMIN_EMAIL))
except UniqueConstraintError:
pass
try:
self.db.save(schema.Group(name="admins", users=[admin]))
except UniqueConstraintError:
pass
sys.modules[__name__] = ApplicationContext() sys.modules[__name__] = ApplicationContext()

View File

@ -61,6 +61,7 @@ def run(context: typer.Context):
""" """
The default CLI entrypoint is ttfrog.cli.run(). The default CLI entrypoint is ttfrog.cli.run().
""" """
import ttfrog.web
ttfrog.app.web.run() ttfrog.app.web.run()

View File

@ -1,6 +1,4 @@
from typing import List from grung.types import Collection, Field, Record
from grung.types import Field, Record
class User(Record): class User(Record):
@ -8,7 +6,7 @@ class User(Record):
class Group(Record): class Group(Record):
_fields = [Field("name", unique=True), Field("users", List[User])] _fields = [Field("name", unique=True), Collection("users", User)]
class Page(Record): class Page(Record):

View File

@ -0,0 +1,34 @@
<!DOCTYPE html>
<html>
<head>
{% block head %}
<meta charset="utf-8">
<title>{% block title %}TTFROG{% endblock %}</title>
<link rel="icon" type="image/x-icon" href="{{ url_for('static', filename='favicon.ico') }}">
{% block styles %}
<link rel="stylesheet" type="text/css" href="{{ url_for('static', filename='style.css' ) }}">
{% endblock %}
{% endblock %}
</head>
<body>
<nav>
<ul>
<li><a href="{{ url_for('index') }}">Home</a></li>
</ul>
</nav>
<main>
{% for message in get_flashed_messages() %}
<div class="alert">
{{ message }}
</div>
{% endfor %}
{% block content %}{% endblock %}
</main>
<footer>
{% block footer %}
{% endblock %}
</footer>
{% block scripts %}{% endblock %}
</body>
</html>

View File

@ -0,0 +1 @@
HI

View File

@ -0,0 +1,6 @@
{% extends "base.html" %}
{% block content %}
<h1>{{ page.title }}</h1>
{{ page.content }}
{% endblock %}

View File

@ -1,9 +1,22 @@
from ttfrog.app import initialize from ttfrog import app
from flask import Response, render_template
_context = initialize() from tinydb import where
app = _context.flask import logging
@app.route("/", defaults={"path": ""}) logger = logging.getLogger(__name__)
def serve(path):
return "HELLO"
@app.web.route("/")
def index():
page = app.db.Page.search(where('stub') == "")
return render_template("page.html", page=page[0])
@app.web.route("/<stub>")
def page_view(stub):
page = app.db.Page.search(where('stub') == stub)
if not page:
logger.info(f"No page found for {stub = }")
return Response(f"{stub}: not found", status=404)
return render_template("page.html", page=page[0])