Skip to content

Commit 2a5d272

Browse files
committed
Add post templates for some common formats
I never remember the basics, so this should help me get started
1 parent 179e2d3 commit 2a5d272

File tree

11 files changed

+480
-0
lines changed

11 files changed

+480
-0
lines changed

content/templates/hero-image.md

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
---
2+
title: Hero Image Long Post Template
3+
slug: hero-image-template
4+
date: 2026-01-02T00:00:00
5+
category: templates
6+
tags:
7+
- long-form
8+
- templates
9+
author: Chris Rose
10+
email: offline@offby1.net
11+
summary: A template for long-form posts with a hero image
12+
status: draft
13+
---
14+
15+
:::{figure} {static}/images/godspeed_columbia-jeff_parker.jpeg
16+
:alt: Hero image
17+
:name: hero-image
18+
:width: 100%
19+
20+
A compelling hero image that sets the tone for the entire piece
21+
:::
22+
23+
## Introduction
24+
25+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
26+
27+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
28+
29+
## The Context
30+
31+
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
32+
33+
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit.
34+
35+
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident.
36+
37+
## Deep Dive
38+
39+
Similique sunt in culpa qui officia deserunt mollitia animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis est et expedita distinctio. Nam libero tempore, cum soluta nobis est eligendi optio cumque nihil impedit quo minus id quod maxime placeat facere possimus.
40+
41+
Omnis voluptas assumenda est, omnis dolor repellendus. Temporibus autem quibusdam et aut officiis debitis aut rerum necessitatibus saepe eveniet ut et voluptates repudiandae sint et molestiae non recusandae.
42+
43+
Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat.
44+
45+
## Reflection
46+
47+
Quis autem vel eum iure reprehenderit qui in ea voluptate velit esse quam nihil molestiae consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla pariatur.
48+
49+
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
50+
51+
## Conclusion
52+
53+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
54+
55+
The journey continues, and there's always more to explore and understand. This is just the beginning of a much longer conversation.

content/templates/photo-essay.md

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
---
2+
title: Photo Essay Template
3+
slug: photo-essay-template
4+
date: 2026-01-02T00:00:00
5+
category: templates
6+
tags:
7+
- photography
8+
- templates
9+
author: Chris Rose
10+
email: offline@offby1.net
11+
summary: A template for photo essay posts with hero images, inline images, and galleries
12+
status: draft
13+
gallery: "{photo}galleries/snoqualmie-2021{Snoqualmie Tunnel 2021}"
14+
---
15+
16+
:::{figure} {static}/images/2010-05-27/4640816392_3bb5b43058_m.jpg
17+
:alt: Hero image
18+
:name: hero-image
19+
20+
Caption for the hero image
21+
:::
22+
23+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.
24+
25+
Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum. Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium.
26+
27+
:::{figure} {static}/images/2010-04-28/4558862091_0e02dc987a_m.jpg
28+
:alt: A single image in the middle
29+
:name: middle-image
30+
31+
This is a caption for the middle image
32+
:::
33+
34+
Totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
35+
36+
Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
37+
38+
(gallery)=
39+
## Manual Gallery
40+
41+
:::{figure} {static}/images/2010-04-24/4546986289_46eb805ea3.jpg
42+
:alt: Gallery image 1
43+
44+
First gallery image
45+
:::
46+
47+
:::{figure} {static}/images/2010-04-24/4547600790_a317b75c6a.jpg
48+
:alt: Gallery image 2
49+
50+
Second gallery image
51+
:::
52+
53+
:::{figure} {static}/images/2010-04-25/4552030124_c8d9f40e9a_m.jpg
54+
:alt: Gallery image 3
55+
56+
Third gallery image
57+
:::
58+
59+
:::{figure} {static}/images/2010-04-28/4558862091_0e02dc987a_m.jpg
60+
:alt: Gallery image 4
61+
62+
Fourth gallery image
63+
:::

content/templates/plain-text.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
---
2+
title: Plain Text Post Template
3+
slug: plain-text-template
4+
date: 2026-01-02T00:00:00
5+
category: templates
6+
tags:
7+
- templates
8+
author: Chris Rose
9+
email: offline@offby1.net
10+
summary: A template for plain text posts without images
11+
status: draft
12+
---
13+
14+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.
15+
16+
Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
17+
18+
## A Section
19+
20+
Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore veritatis et quasi architecto beatae vitae dicta sunt explicabo.
21+
22+
Nemo enim ipsam voluptatem quia voluptas sit aspernatur aut odit aut fugit, sed quia consequuntur magni dolores eos qui ratione voluptatem sequi nesciunt.
23+
24+
## Another Section
25+
26+
Neque porro quisquam est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit, sed quia non numquam eius modi tempora incidunt ut labore et dolore magnam aliquam quaerat voluptatem.
27+
28+
At vero eos et accusamus et iusto odio dignissimos ducimus qui blanditiis praesentium voluptatum deleniti atque corrupti quos dolores et quas molestias excepturi sint occaecati cupiditate non provident, similique sunt in culpa qui officia deserunt mollitia animi.
29+
30+
## Conclusion
31+
32+
Itaque earum rerum hic tenetur a sapiente delectus, ut aut reiciendis voluptatibus maiores alias consequatur aut perferendis doloribus asperiores repellat. The end.

content/templates/til.md

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
---
2+
title: "TIL: Template Example"
3+
slug: til-template-example
4+
date: 2026-01-02T00:00:00
5+
category: TIL
6+
tags:
7+
- til
8+
- templates
9+
author: Chris Rose
10+
email: offline@offby1.net
11+
summary: A template for Today I Learned posts
12+
status: draft
13+
---
14+
15+
Today I learned something interesting about this topic.
16+
17+
:::{figure} {static}/images/2021-05-07/badge.jpg
18+
:alt: Example image
19+
:width: 400px
20+
21+
An example image to illustrate the concept
22+
:::
23+
24+
Lorem ipsum dolor sit amet, consectetur adipiscing elit. Sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. This was particularly surprising because I hadn't expected it to work this way.
25+
26+
The key takeaway is that you should always check the documentation before assuming how something works. This simple discovery saved me hours of debugging and made my workflow much more efficient.

pelicanconf.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,7 @@ def __post_init__(self):
238238
"myst_enable_extensions": {
239239
"linkify", # Auto-detect links
240240
"colon_fence", # Enable ::: directive syntax for dropdowns
241+
"attrs_inline", # Enable {#id} and {.class} syntax for headings
241242
},
242243
"myst_disable_syntax": [], # Don't disable any syntax
243244
"myst_heading_anchors": 3, # Add anchors to headings

tasks.py

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,77 @@ def new_post(c, title=None, post_type="md"):
280280
c.run(f"git add '{new_post_path}'")
281281

282282

283+
@task
284+
def new_post_from_template(c, template, title=None, category=None, summary=None):
285+
"""Create a new post from a template (photo-essay, til, hero-image, plain-text)"""
286+
import re
287+
288+
template_map = {
289+
"photo-essay": "photo-essay.md",
290+
"til": "til.md",
291+
"hero-image": "hero-image.md",
292+
"plain-text": "plain-text.md",
293+
}
294+
295+
if template not in template_map:
296+
console.print(f"[bold red]Error:[/bold red] Unknown template '{template}'")
297+
console.print(f"Available templates: {', '.join(template_map.keys())}")
298+
return
299+
300+
# Get title if not provided
301+
if title is None:
302+
console.print("[bold magenta]Please enter the title:[/bold magenta]")
303+
title = Prompt.ask("Title", default="New Post")
304+
305+
# Get category if not provided
306+
if category is None:
307+
console.print("[bold magenta]Please enter the category:[/bold magenta]")
308+
category = Prompt.ask("Category", default="general-thoughts")
309+
310+
# Get summary if not provided
311+
if summary is None:
312+
console.print("[bold magenta]Please enter a summary:[/bold magenta]")
313+
summary = Prompt.ask("Summary", default="A new post")
314+
315+
# Read template
316+
template_path = (
317+
Path(__file__).parent / "content" / "templates" / template_map[template]
318+
)
319+
template_content = template_path.read_text()
320+
321+
# Generate new values
322+
slug = slugify(title)
323+
date = datetime.datetime.now().isoformat()
324+
325+
# Update frontmatter fields using regex
326+
content = re.sub(
327+
r"^title:.*$", f"title: {title}", template_content, flags=re.MULTILINE
328+
)
329+
content = re.sub(r"^slug:.*$", f"slug: {slug}", content, flags=re.MULTILINE)
330+
content = re.sub(r"^date:.*$", f"date: {date}", content, flags=re.MULTILINE)
331+
content = re.sub(
332+
r"^category:.*$", f"category: {category}", content, flags=re.MULTILINE
333+
)
334+
content = re.sub(
335+
r"^summary:.*$", f"summary: {summary}", content, flags=re.MULTILINE
336+
)
337+
338+
# Remove 'templates' tag from the tags list
339+
content = re.sub(r"^ - templates\n", "", content, flags=re.MULTILINE)
340+
341+
# Create new post file
342+
new_post_path = (
343+
Path(SETTINGS["PATH"])
344+
/ "posts"
345+
/ f"{datetime.date.today().isoformat()}-{slug}.md"
346+
)
347+
348+
new_post_path.write_text(content)
349+
console.print(f"[bold green]Created:[/bold green] {new_post_path}")
350+
351+
c.run(f"git add '{new_post_path}'")
352+
353+
283354
class Visitor(docutils.nodes.NodeVisitor):
284355
def __init__(self, doc):
285356
super().__init__(doc)

themes/offby1/scss/offby1.scss

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222

2323
// 4. Third-party components
2424
@import "offby1/littlefoot"; // Littlefoot footnotes with cyberpunk theme
25+
@import "offby1/magnific-popup"; // Lightbox for image galleries
2526

2627
// 5. Ad-blocker detection
2728
@import "nativeads.js";

themes/offby1/scss/offby1/_gallery.scss

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,80 @@
6464
transition: opacity 0.3s ease;
6565
}
6666

67+
// MyST-generated gallery sections
68+
// When using MyST markdown with gallery sections, it creates <section id="*gallery*">
69+
// with <figure class="align-default"> children
70+
section[id*="gallery"] {
71+
display: grid;
72+
grid-template-columns: repeat(auto-fill, minmax(300px, 1fr));
73+
gap: 1.5rem;
74+
margin: 3rem 0;
75+
76+
// The h1 heading should span all columns
77+
> h1, > h2 {
78+
grid-column: 1 / -1;
79+
font-size: 1.8rem;
80+
margin-bottom: 1rem;
81+
color: var(--color-primary);
82+
text-transform: uppercase;
83+
letter-spacing: 0.05em;
84+
}
85+
86+
// Style the figure elements as gallery items
87+
> figure.align-default {
88+
position: relative;
89+
margin: 0;
90+
border: 2px solid var(--color-surface);
91+
background: var(--color-surface);
92+
transition: all 0.3s ease;
93+
overflow: hidden;
94+
95+
&:hover {
96+
border-color: var(--color-primary);
97+
transform: translateY(-2px);
98+
box-shadow: 0 4px 12px rgba(0, 0, 0, 0.3);
99+
100+
img {
101+
transform: scale(1.05);
102+
}
103+
}
104+
105+
// The link wrapping the image
106+
> a.gallery-image {
107+
display: block;
108+
109+
img {
110+
width: 100%;
111+
height: 250px;
112+
object-fit: cover;
113+
display: block;
114+
transition: transform 0.3s ease;
115+
}
116+
}
117+
118+
// Caption styling
119+
figcaption {
120+
padding: 0.75rem;
121+
background: var(--color-surface-variant);
122+
123+
p {
124+
margin: 0;
125+
font-size: 0.875rem;
126+
color: var(--color-text-secondary);
127+
128+
.caption-text {
129+
color: var(--color-text);
130+
}
131+
132+
// Hide the permalink icon in captions
133+
.headerlink {
134+
display: none;
135+
}
136+
}
137+
}
138+
}
139+
}
140+
67141
// Responsive adjustments
68142
@media (max-width: $width-md) {
69143
.gallery-grid {
@@ -74,10 +148,28 @@
74148
.gallery-item img {
75149
height: 150px;
76150
}
151+
152+
section[id*="gallery"] {
153+
grid-template-columns: repeat(auto-fill, minmax(250px, 1fr));
154+
gap: 1rem;
155+
156+
> figure.align-default > a.gallery-image img {
157+
height: 200px;
158+
}
159+
}
77160
}
78161

79162
@media (max-width: $width-sm) {
80163
.gallery-grid {
81164
grid-template-columns: repeat(2, 1fr);
82165
}
166+
167+
section[id*="gallery"] {
168+
grid-template-columns: repeat(2, 1fr);
169+
gap: 0.75rem;
170+
171+
> figure.align-default > a.gallery-image img {
172+
height: 150px;
173+
}
174+
}
83175
}

0 commit comments

Comments
 (0)