Generate page headers #36

Open
opened 2024-06-16 17:52:04 +02:00 by ktyl · 0 comments
Owner

Page headers are not dynamically generated.

Page preambles are currently generated using a static inc_html/header.html file which is the same for every page, meaning every page has the same metadata. Page titles are then awkwardly inserted by injecting templates before and after a bit of text.

<head>
    <meta charset="UTF-8"/>
    <meta name="viewport" content="width=device-width, initial-scale=1.0 minimum-scale=1" />
    <meta name="description" content="computer whisperer" />
    <meta name="keywords" content="Cat Flynn, Ktyl, Portfolio, Showreel, Blog, Gallery"/> <!-- blog, gallery -->
    <link rel="canonical" href="https://ktyl.dev/">
    <link rel="stylesheet" href="styles.css" />
    <link rel="icon" type="image/x-icon" href="favicon.ico" />

    <script src="https://kit.fontawesome.com/ad50bb2e16.js" crossorigin="anonymous"></script>
    <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> -->
    <!-- <script src="main.js"></script> -->
</head>

The entire <head> section should be generated per-page to provide the correct keywords and description, removing the need for the #header.html template. Instead, a Python processing step can be run on input HTML files to generate an appropriate header. The <head> tag should be inserted directly before <body>.

TOML metadata

Per-page information required can be written directly into the source file using a TOML format, and replaced with a fully generated header with the relevant repeated includes for styles, etc. The Python processor can read this metadata directly from the input file.

+++
description = computer whisperer
keywords = Cat Flynn, Ktyl, Portfolio, Showreel, Blog, Gallery
+++

This Python function can read a TOML block out of a file.

import re

def read_metadata(path):
    pattern = re.compile(r"^\+{3}\n((?:.*|\n)*)\n\+{3}$")

    metadata = {}

    with open(path) as f:
        match = re.search(pattern, f.read())
        lines = match.group(1).split('\n')
        for l in lines:
            pair = [s.strip() for s in l.split('=')]
            metadata[pair[0]] = pair[1]

    return metadata

print(read_metadata(path))

Metadata should not be included in the output file. We therefore need to match the whole block and substitute it with nothing. This function will return a string containing the contents of the file, minus the metadata block.

import re

def strip_metadata(path):
    pattern = re.compile(r"(\+{3}\n(?:.*|\n)*\n\+{3})")

    with open(path) as f:
        return re.sub(pattern, "", f.read())

Metadata values can then be injected into a template using str.replace(). In the case that no metadata was provided for that page, we should exit with an error exit code. We could provide default metadata, but that would get harder to check as the site scales, so it would be better to fail the build entirely and force metadata to be included.

Page headers are not dynamically generated. Page preambles are currently generated using a static `inc_html/header.html` file which is the same for every page, meaning every page has the same metadata. Page titles are then awkwardly inserted by injecting templates before and after a bit of text. ```html <head> <meta charset="UTF-8"/> <meta name="viewport" content="width=device-width, initial-scale=1.0 minimum-scale=1" /> <meta name="description" content="computer whisperer" /> <meta name="keywords" content="Cat Flynn, Ktyl, Portfolio, Showreel, Blog, Gallery"/> <!-- blog, gallery --> <link rel="canonical" href="https://ktyl.dev/"> <link rel="stylesheet" href="styles.css" /> <link rel="icon" type="image/x-icon" href="favicon.ico" /> <script src="https://kit.fontawesome.com/ad50bb2e16.js" crossorigin="anonymous"></script> <!-- <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script> --> <!-- <script src="main.js"></script> --> </head> ``` The entire `<head>` section should be generated per-page to provide the correct keywords and description, removing the need for the `#header.html` template. Instead, a Python processing step can be run on input HTML files to generate an appropriate header. The `<head>` tag should be inserted directly before `<body>`. # TOML metadata Per-page information required can be written directly into the source file using a [TOML](https://toml.io/en/) format, and replaced with a fully generated header with the relevant repeated includes for styles, etc. The Python processor can read this metadata directly from the input file. ```toml +++ description = computer whisperer keywords = Cat Flynn, Ktyl, Portfolio, Showreel, Blog, Gallery +++ ``` This Python function can read a TOML block out of a file. ```py import re def read_metadata(path): pattern = re.compile(r"^\+{3}\n((?:.*|\n)*)\n\+{3}$") metadata = {} with open(path) as f: match = re.search(pattern, f.read()) lines = match.group(1).split('\n') for l in lines: pair = [s.strip() for s in l.split('=')] metadata[pair[0]] = pair[1] return metadata print(read_metadata(path)) ``` Metadata should not be included in the output file. We therefore need to match the whole block and substitute it with nothing. This function will return a string containing the contents of the file, minus the metadata block. ```py import re def strip_metadata(path): pattern = re.compile(r"(\+{3}\n(?:.*|\n)*\n\+{3})") with open(path) as f: return re.sub(pattern, "", f.read()) ``` Metadata values can then be injected into a template using [str.replace()](https://www.w3schools.com/python/ref_string_replace.asp). In the case that no metadata was provided for that page, we should exit with an error exit code. We could provide default metadata, but that would get harder to check as the site scales, so it would be better to fail the build entirely and force metadata to be included.
ktyl added the
enhancement
label 2024-06-16 17:52:17 +02:00
ktyl added this to the Simplify site generation project 2024-06-16 17:52:24 +02:00
ktyl self-assigned this 2024-06-17 21:45:20 +02:00
Sign in to join this conversation.
No Milestone
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: ktyl/ktyl.dev#36
No description provided.