From afda9b4d1b749624daad83296e910b4f6d00f60f Mon Sep 17 00:00:00 2001 From: polarbean Date: Tue, 19 May 2026 19:28:06 +0100 Subject: [PATCH] Add blog post author bylines --- docs/source/_static/css/custom.css | 18 ++++++++++ docs/source/conf.py | 58 ++++++++++++++++++++++++++++++ 2 files changed, 76 insertions(+) diff --git a/docs/source/_static/css/custom.css b/docs/source/_static/css/custom.css index 157d5bea..fbed73e5 100644 --- a/docs/source/_static/css/custom.css +++ b/docs/source/_static/css/custom.css @@ -72,3 +72,21 @@ html[data-theme=dark] .bd-main img { flex-wrap: wrap; justify-content: space-between; } + +.blog-post-author { + border-left: 3px solid var(--pst-color-primary); + color: var(--pst-color-text-muted); + font-size: 1.12rem; + line-height: 1.5; + margin-top: -0.2rem; + margin-bottom: 2rem; + padding-left: 0.8rem; +} + +.blog-post-author a { + font-weight: 600; +} + +.blog-post-author .line:nth-child(2) { + font-size: 1rem; +} diff --git a/docs/source/conf.py b/docs/source/conf.py index 8323e363..72ade27f 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -14,6 +14,10 @@ # import sys # sys.path.insert(0, os.path.abspath('.')) +from ablog.blog import Blog +from docutils import nodes +from sphinx.errors import ExtensionError + # -- Project information ----------------------------------------------------- @@ -95,6 +99,60 @@ "Authorization": f"Bearer {os.environ.get('GITHUB_TOKEN', '')}", }, } + + +def add_blog_author_byline(app, doctree, docname): + """Add ABlog author metadata to individual blog post pages.""" + posts = getattr(app.env, "ablog_posts", {}).get(docname, []) + if len(posts) != 1: + return + + post = posts[0] + authors = post.get("author", []) + date = post.get("date") + if not authors or not date: + raise ExtensionError( + f"Blog post '{docname}' must define both author and date metadata." + ) + + byline = nodes.line_block(classes=["blog-post-author"]) + + if authors: + author_line = nodes.line() + author_line += nodes.Text("By ") + + blog = Blog(app) + author_catalog = blog.catalogs["author"].collections + for index, author in enumerate(authors): + if index: + author_line += nodes.Text(", ") + + author_page = author_catalog.get(author) + if author_page is None: + author_line += nodes.Text(author) + continue + + author_line += nodes.reference( + "", + author, + refuri=app.builder.get_relative_uri(docname, author_page.docname), + ) + + byline += author_line + + if date: + byline += nodes.line(text=date.strftime(app.config["post_date_format"])) + + for section in doctree.findall(nodes.section): + if section.children and isinstance(section.children[0], nodes.title): + section.insert(1, byline) + return + + +def setup(app): + app.connect("doctree-resolved", add_blog_author_byline) + + # Suppress strikethrough warnings - strikethrough is only supported in HTML suppress_warnings = ['myst.strikethrough']