feat(micro): add microblogging section to homepage

- Add micro section display on homepage with RSS feed
- Support configurable section name via micro_section_name
- Add toggle via show_micro config option
- Create templates/partials/main_page_micro_list.html
- Add sass/parts/_micro.scss for styling
- Include RSS icon next to section heading

Closes #1
This commit is contained in:
Lee Kai Ze 2025-11-08 23:06:22 +08:00
parent 393c5a8cb9
commit 06c55da7b7
11 changed files with 256 additions and 0 deletions

View file

@ -10,6 +10,10 @@ projects_path = "projects/_index.md"
max_projects = 3
show_projects_first = false
social_media_card = "index.jpg"
micro_path = "micro/_index.md"
max_micro = 3
micro_section_name = "Latest Thoughts"
show_micro = true
+++
tabi is an accessible [Zola](https://www.getzola.org) theme with [search](@/blog/mastering-tabi-settings/index.md#search), [multi-language support](@/blog/faq-languages/index.md), [optional JavaScript](@/blog/javascript/index.md), a perfect Lighthouse score, and comprehensive documentation. Crafted for personal websites and blogs.

View file

@ -0,0 +1,6 @@
+++
title = "2025-11-08 14:30"
date = 2025-11-08T14:30:00+08:00
+++
Why Microblog: Thoughts decay without capture; short posts reduce friction between idea and publication.

View file

@ -0,0 +1,6 @@
+++
title = "2025-11-08 22:11"
date = 2025-11-08T22:11:53+08:00
+++
Writing clarifies thinking and compounds your expertise into searchable, permanent knowledge capital.

View file

@ -0,0 +1,6 @@
+++
title = "2025-11-08 22:26"
date = 2025-11-08T22:26:37+08:00
+++
Why use SSG: Pre-rendered HTML eliminates servers, databases, and runtime vulnerabilities while maximizing speed.

View file

@ -0,0 +1,6 @@
+++
title = "2025-11-08 23:00"
date = 2025-11-08T23:00:00+08:00
+++
Shipping code is better than perfect code. Ship it.

8
content/micro/_index.md Normal file
View file

@ -0,0 +1,8 @@
+++
title = "Micro"
description = "Short blogs"
sort_by = "date"
template = "section.html"
paginate_by = 20
generate_feeds = true
+++

View file

@ -12,6 +12,7 @@
@use 'parts/_image-hover.scss';
@use 'parts/_image-toggler.scss';
@use 'parts/_image.scss';
@use 'parts/_micro.scss';
@use 'parts/_misc.scss';
@use 'parts/_multilingual_quote.scss';
@use 'parts/_pagination.scss';

138
sass/parts/_micro.scss Normal file
View file

@ -0,0 +1,138 @@
// Micro posts section - force left alignment
#micro-posts {
margin-top: 4rem;
margin-left: 0;
margin-right: auto;
}
// Card container - left aligned, no centering
.micro-card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 3rem;
margin: 2rem 0;
margin-left: 0;
background-color: var(--navbar-color);
border: 1px solid var(--divider-color);
border-radius: 8px;
padding: 2rem;
}
// Left column header
.micro-header {
h2 {
display: flex;
align-items: center;
gap: 0.5rem;
margin: 0;
color: var(--text-color-high-contrast);
font-family: var(--header-font);
font-weight: 550;
font-size: 1.5rem;
line-height: 1.3;
}
.feed-link {
display: inline-flex;
align-items: center;
text-decoration: none;
}
.feed-icon {
display: block;
width: 1rem;
height: 1rem;
fill: var(--meta-color);
transition: fill 0.2s ease;
&:hover {
fill: var(--primary-color);
}
}
}
// Right column content
.micro-content-column {
display: flex;
flex-direction: column;
gap: 1.5rem;
}
// Individual micro post
.micro-item {
padding-bottom: 1.5rem;
border-bottom: 1px solid var(--divider-color);
&:last-child {
padding-bottom: 0;
border-bottom: none;
}
time {
display: block;
margin-bottom: 0.5rem;
color: var(--meta-color);
font-family: var(--sans-serif-font);
font-weight: 300;
font-size: 0.85rem;
}
}
// Micro post text
.micro-text {
color: var(--text-color);
font-family: var(--sans-serif-font);
font-weight: 400;
font-size: 0.9rem;
line-height: 1.5rem;
p {
margin: 0.5rem 0 1rem;
&:first-child {
margin-top: 0;
}
&:last-child {
margin-bottom: 0;
}
}
a {
color: var(--primary-color);
text-decoration: none;
&:hover {
color: var(--hover-color);
}
}
strong {
font-weight: 580;
}
}
// Mobile responsive
@media only screen and (max-width: 1100px) {
#micro-posts {
margin-top: 3rem;
}
.micro-card {
grid-template-columns: 1fr;
gap: 1.5rem;
padding: 1.5rem;
}
.micro-header h2 {
font-size: 1.3rem;
}
.micro-content-column {
gap: 1.2rem;
}
.micro-item {
padding-bottom: 1.2rem;
}
}

29
scripts/new-micro.sh Executable file
View file

@ -0,0 +1,29 @@
#!/usr/bin/env bash
# Quick micro post generator - eliminates title/date friction
set -euo pipefail
# Get current timestamp
NOW=$(date +"%Y-%m-%dT%H:%M:%S%:z")
FILENAME=$(date +"%Y-%m-%d-%H%M")
TITLE=$(date +"%Y-%m-%d %H:%M")
# Get content from stdin or prompt
if [ -t 0 ]; then
echo "Enter micro post content (Ctrl+D when done):"
CONTENT=$(cat)
else
CONTENT=$(cat)
fi
# Create post
cat > "content/micro/${FILENAME}.md" <<EOF
+++
title = "${TITLE}"
date = ${NOW}
+++
${CONTENT}
EOF
echo "Created: content/micro/${FILENAME}.md"

View file

@ -0,0 +1,48 @@
{% if section.extra.show_micro | default(value=true) %}
{% if section.extra.micro_path %}
{%- set micro_section = get_section(path=section.extra.micro_path) -%}
{%- if micro_section -%}
{%- set show_pages = micro_section.pages -%}
{%- set max_micro = section.extra.max_micro | default(value=5) -%}
{%- set section_name = section.extra.micro_section_name | default(value="Latest Thoughts") -%}
<div id="micro-posts">
<div class="micro-card">
<div class="micro-header">
<h2>
{{ section_name }}
{%- if micro_section.generate_feeds -%}
<a href="{{ get_url(path=micro_section.path ~ 'atom.xml', trailing_slash=false) | safe }}"
title="RSS Feed"
aria-label="RSS Feed">
<svg class="feed-icon" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24">
<circle cx="6.18" cy="17.82" r="2.18"/>
<path d="M4 4.44v2.83c7.03 0 12.73 5.7 12.73 12.73h2.83c0-8.59-6.97-15.56-15.56-15.56zm0 5.66v2.83c3.9 0 7.07 3.17 7.07 7.07h2.83c0-5.47-4.43-9.9-9.9-9.9z"/>
</svg>
</a>
{%- endif -%}
</h2>
</div>
<div class="micro-content-column">
{% for post in show_pages | slice(end=max_micro) %}
<div class="micro-item">
<time datetime="{{ post.date | date(format='%Y-%m-%d') }}">
{{ post.date | date(format='%d %b %Y · %H:%M') }}
</time>
<div class="micro-text">
{{ post.content | safe }}
</div>
</div>
{% endfor %}
</div>
</div>
{%- if show_pages | length > max_micro -%}
<div class="all-posts">
<a href="{{ get_url(path=micro_section.path, lang=lang) }}/">All {{ section_name | lower }}&nbsp;<span class="arrow"></span></a>
</div>
{%- endif -%}
</div>
{%- endif -%}
{% endif %}
{% endif %}

View file

@ -52,6 +52,10 @@
{%- include "partials/main_page_posts_list.html" -%}
{%- include "partials/main_page_projects_list.html" -%}
{%- endif -%}
{# Add micro posts section #}
{%- include "partials/main_page_micro_list.html" -%}
</main>
{%- include "partials/extra_features.html" -%}