port over base HTML layout from PHP to FastAPI+Jinja2

+ Mounted static files (at web/html) to /static.
+ Added AURWEB_VERSION to aurweb.config (this is used around HTML
  to refer back to aurweb's release on git.archlinux.org), so we
  need it easily accessible in the Python codebase.
+ Implemented basic Jinja2 partials to put together whole aurweb
  pages. This may be missing some things currently and is a WIP
  until this set is ready to be merged.
+ Added config [options] aurwebdir = YOUR_AUR_ROOT; this configuration
  option should specify the root directory of the aurweb project.
  It is used by various parts of the FastAPI codebase to target
  project directories.

Added routes via aurweb.routers.html:
    * POST /language: Set your session language.
    * GET /favicon.ico: Redirect to /static/images/favicon.ico.
        * Some browsers always look for $ROOT/favicon.ico to get an icon
          for the page being loaded, regardless of a specified "shortcut
          icon" given in a <link> directive.
    * GET /: Home page; WIP.

* Updated aurweb.routers.html.language passes query parameters to
  its next redirection.

When calling aurweb.templates.render_template, the context passed should
be formed via the aurweb.templates.make_context. See
aurweb.routers.html.index for an example of this.

Signed-off-by: Kevin Morris <kevr@0cost.org>
This commit is contained in:
Kevin Morris 2021-03-29 15:20:04 -07:00
parent 1ff822bb14
commit 2df90ce280
18 changed files with 339 additions and 2 deletions

57
aurweb/templates.py Normal file
View file

@ -0,0 +1,57 @@
import copy
import os
from datetime import datetime
from http import HTTPStatus
import jinja2
from fastapi import Request
from fastapi.responses import HTMLResponse
import aurweb.config
from aurweb import l10n
# Prepare jinja2 objects.
loader = jinja2.FileSystemLoader(os.path.join(
aurweb.config.get("options", "aurwebdir"), "templates"))
env = jinja2.Environment(loader=loader, autoescape=True,
extensions=["jinja2.ext.i18n"])
# Add tr translation filter.
env.filters["tr"] = l10n.tr
def make_context(request: Request, title: str, next: str = None):
""" Create a context for a jinja2 TemplateResponse. """
return {
"request": request,
"language": l10n.get_request_language(request),
"languages": l10n.SUPPORTED_LANGUAGES,
"title": title,
# The 'now' context variable will not show proper datetimes
# until we've implemented timezone support here.
"now": datetime.now(),
"config": aurweb.config,
"next": next if next else request.url.path
}
def render_template(path: str, context: dict, status_code=int(HTTPStatus.OK)):
""" Render a Jinja2 multi-lingual template with some context. """
# Create a deep copy of our jinja2 environment. The environment in
# total by itself is 48 bytes large (according to sys.getsizeof).
# This is done so we can install gettext translations on the template
# environment being rendered without installing them into a global
# which is reused in this function.
templates = copy.copy(env)
translator = l10n.get_raw_translator_for_request(context.get("request"))
templates.install_gettext_translations(translator)
template = templates.get_template(path)
rendered = template.render(context)
return HTMLResponse(rendered, status_code=status_code)