Continue blog implementation

This commit is contained in:
2026-10-05 19:48:08 +01:00
parent 179a830fa9
commit 41993928ab
8 changed files with 38 additions and 11 deletions
+4
View File
@@ -26,6 +26,8 @@ projects = ContentArea(
root_templ='projects.html',
post_templ='article.html',
name='projects',
title='Projects',
desc='A selection of projects I\'ve been involved in',
import_name=__name__
)
@@ -34,6 +36,8 @@ blog = ContentArea(
root_templ='blog.html',
post_templ='post.html',
name='blog',
title='Blog',
desc='Less formal writing, usually something I\'ve been working on that isn\'t worthy of a project write up',
import_name=__name__
)
+14 -4
View File
@@ -5,12 +5,13 @@ import json
from datetime import datetime
import frontmatter
from markdown import markdown
import readtime
from bs4 import BeautifulSoup
from flask import render_template, Response, Blueprint
from .storage import LocalStorage
class ContentArea(Blueprint):
def __init__(self, directory: LocalStorage, root_templ: str, post_templ: str, *args, **kwargs):
def __init__(self, directory: LocalStorage, root_templ: str, post_templ: str, title: str, desc: str, *args, **kwargs):
self.md_directory = directory
super().__init__(*args, **kwargs)
@@ -26,6 +27,8 @@ class ContentArea(Blueprint):
self.root_templ = root_templ
self.post_templ = post_templ
self.title = title
self.desc = desc
def processor(self) -> dict:
''' Jninja processors '''
@@ -34,7 +37,14 @@ class ContentArea(Blueprint):
post_soup = BeautifulSoup(html, 'html.parser')
all_text = ' '.join([x.get_text() for x in post_soup.findAll('p')])
return ' '.join(all_text.split()[:200])
return dict(get_excerpt=get_excerpt)
def get_readtime(post: str) -> str:
return readtime.of_html(post).text
def get_readtime_mins(post: str) -> int:
return readtime.of_html(post).minutes
return dict(get_excerpt=get_excerpt, get_readtime=get_readtime, get_readtime_mins=get_readtime_mins)
def human_date(self, iso_date: str) -> str:
''' Jninja filter to convert an ISO date to human readable. '''
@@ -87,9 +97,9 @@ class ContentArea(Blueprint):
return render_template(self.root_templ,
articles=articles_to_return,
all_categories=categories,
title='Projects',
title=self.title,
page_title='Projects - ',
description='A selection of projects I\'ve been involved in')
description=self.desc)
def category(self, category_id: str) -> str:
''' Load the page for a given category '''
+2
View File
@@ -18,6 +18,7 @@
"headline": {{ metadata.title | tojson }},
"datePublished": "{{ metadata.date }}",
"image": "https://{{ url }}/image/{{ metadata.image }}",
"timeRequired": "PT{{ get_readtime_mins(post) }}M",
"author": {
"@type": "Person",
"name": "Jake Charman",
@@ -42,6 +43,7 @@
<main>
<section id="article">
<h1>{{ metadata.title}} </h1>
<p>{{ get_readtime(post) }} read</p>
<p>{{ metadata.date | human_date }}</p>
<hr />
{{post|safe}}
+5 -4
View File
@@ -14,8 +14,6 @@
</nav>
<h2>{{ title }}</h2>
<p>{{ description }}</p>
<p style="text-align: center; font-weight: bold; font-style: italic;">This page is relatively new. I'm adding projects as fast as I can but feel free to <a href="/contact">contact me</a> if you want to know about something in particular.</p>
<section id="blog">
{% for row in articles %}
<div class="blog-post">
{% if row.get('link') is not none %}
@@ -44,10 +42,13 @@
{% endif %}
<h3>{{ row.title }}</h3>
</a>
<p class="blogpost-description">{{ row.description }}</p>
<p class="blogpost-date">{{ row.date | human_date }}</p>
<p>{{ get_readtime(row.content) }} read</p>
<hr />
<p class="blogpost-description">{{ get_excerpt(row) }}... <a href="/blog/{{ row.id }}">Read more</a></p>
<hr />
{% for category in row.categories %}
<a class="blogpost-category" href="/projects/category/{{ category }}"> {{ all_categories.get(category, {}).get('title', '') }}{{ ", " if not loop.last }}</loop></a>
<a class="blogpost-category" href="/blog/category/{{ category }}"> {{ all_categories.get(category, {}).get('title', '') }}{{ ", " if not loop.last }}</loop></a>
{% endfor %}
</div>
</div>
+7 -2
View File
@@ -17,6 +17,7 @@
"@type": "BlogPosting",
"headline": {{ metadata.title | tojson }},
"description": {{ metadata.description | tojson }},
"timeRequired": "PT{{ get_readtime_mins(post) }}M",
"datePublished": "{{ metadata.date }}",
{% if metadata.updated %}
"dateModified": "{{ metadata.updated }}",
@@ -34,9 +35,9 @@
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://{{ url }}/writing/{{ metadata.id }}"
"@id": "https://{{ url }}/blog/{{ metadata.id }}"
},
"url": "https://{{ url }}/writing/{{ metadata.id }}",
"url": "https://{{ url }}/blog/{{ metadata.id }}",
"inLanguage": "en-GB"
}
</script>
@@ -56,7 +57,11 @@
<main>
<section id="article">
<h1>{{ metadata.title}} </h1>
<p>{{ get_readtime(post) }} read</p>
<p>{{ metadata.date | human_date }}</p>
{% if metadata.updated %}
<p>Updated: {{ metadata.updated | human_date }}</p>
{% endif %}
<hr />
{{post|safe}}
</section>
+1 -1
View File
@@ -47,7 +47,7 @@
<p class="article-description">{{ row.description }}</p>
<p class="article-date">{{ row.date | human_date }}</p>
{% for category in row.categories %}
<a class="article-category" href="/projects/category/{{ category }}"> {{ all_categories.get(category, {}).get('title', '') }}{{ ", " if not loop.last }}</loop></a>
<a class="article-category" href="/projects/category/{{ category }}"> {{ all_categories.get(category, {}).get('title', '') }}{{ ", " if not loop.last }}</a>
{% endfor %}
</div>
</div>
+1
View File
@@ -7,3 +7,4 @@ python-frontmatter>=1.1.0
requests>=2.32.3
pillow>=11.0.0
mod_wsgi>=5.0.2
readtime>=3.0.0
+4
View File
@@ -339,6 +339,10 @@ pre{
object-fit: cover;
}
#blog-main {
padding: 0 10px 0 10px;
}
.blog-post {
border: 5px solid #e5e5e5;
padding: 10px;