Apacible Theme: Complete Features Guide
This comprehensive guide demonstrates all features and capabilities of the Apacible Hugo theme. From basic markdown to advanced shortcodes, image processing, and technical content—everything you need to know is here.
Introduction
The Apacible theme is a minimalist Hugo theme prioritizing accessibility and smolweb principles, with unique dithered image support. This guide covers every feature with practical examples.
Markdown Features
The theme supports all standard Markdown features with beautiful styling.
Headings
Headings create clear hierarchy in your content:
Heading Level 2
Heading Level 3
Heading Level 4
Emphasis
Normal text, bold text, italic text, bold and italic text, and strikethrough text.
Lists
Unordered lists:
- First item
- Second item
- Third item
Ordered lists:
- First item
- Indented item
- Indented item
- Second item
- Third item
Links
There is a link and another link to example.com.
Tables
Basic table:
| Syntax | Description | Test Text |
|---|---|---|
| Header | Title | Here’s this |
| Paragraph | Text | And more |
With alignment:
| Syntax | Description | Test Text |
|---|---|---|
| Left | Center | Right |
| Paragraph | Text | And more |
Blockquotes
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Praesentium, nisi saepe dolor unde iusto dolore nam, vero optio consequuntur repudiandae et! Atque libero expedita laudantium cupiditate, sit explicabo sequi ipsa!
Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Nested blockquote: Praesentium, nisi saepe dolor unde iusto dolore nam, vero optio consequuntur repudiandae et! Atque libero expedita laudantium cupiditate, sit explicabo sequi ipsa!
Footnotes
Lorem ipsum dolor sit, amet1 words consectetur2 adipisicing elit.
Horizontal Rule
Shortcodes
Shortcodes extend Markdown with powerful custom functionality.
Callouts
Callouts are useful for highlighting important information.
Quotes
Beautifully styled quotes for highlighting important statements.
Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world.
The best way to predict the future is to invent it.
Detail/Expandable Content
Click to expand: Lorem ipsum dolor sit, amet consectetur adipisicing elit.
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Praesentium, nisi saepe dolor unde iusto dolore nam, vero optio consequuntur repudiandae et! Atque libero expedita laudantium cupiditate, sit explicabo sequi ipsa!
Lorem ipsum dolor sit, amet consectetur adipisicing elit. Praesentium, nisi saepe dolor unde iusto dolore nam, vero optio consequuntur repudiandae et! Atque libero expedita laudantium cupiditate, sit explicabo sequi ipsa!
Collection Shortcode
The collection shortcode displays structured data from TOML/YAML/JSON files in various styles. Perfect for showcasing projects, books, movies, music, or any structured content.
Usage:
Create a data file in data/projects.toml:
[[collection]]
title = "Project Name"
subtitle = "Project subtitle"
content = "Project description"
link = "https://example.com"
image = "/assets/project.jpg"
year = "2024"
tags = ["web", "design"]
rating = 5
[[collection]]
title = "Another Project"
# ... more fields
Then use the shortcode:
{{< collection file="projects.toml" style="card" filter="year" >}}
Styles:
card: Full card with image, title, description, and metadatasimple-card: Simplified card with just title and brief infolist: Minimal list style with optional iconscard-grid: Grid of cards with imagescard-grid-compact: Compact grid layoutcard-horizontal: Horizontal card layouthorizontal: Horizontal layout variantinline: Inline list layoutposter-grid: Grid of poster images only
Parameters:
file: Path to TOML/YAML/JSON file with collection data (indata/directory)style: Display style (optional, default: “card”)filter: Enable filtering - “year” or “date” (optional)category_filter: Enable category-based filtering (optional)
Collection Item Fields:
title: Item title (required)subtitle: Optional subtitlecontentordescription: Item descriptionlinkorurl: Link to itemimageorimg: Image URLyear: Year field for filteringdateordate_read: Date field for filteringcategory: Category for category filteringtags: Array of tagsrating: Numeric rating (1-5, displayed as stars)director: Director name (for movies)author: Author name (for books)artist: Artist name (for music)label: Label/studio/publisherrole: Role/positionicon: Icon URL (for list style)footer: Footer textdraft: Set totrueto hide itemtype: Set to"br"to create a separator/break
Filtering:
When filter="year" is enabled, buttons appear to filter items by year. When filter="date" is enabled, filtering works by the year extracted from date_read fields. Category filtering works similarly with category_filter enabled.
Example with Filtering:
{{< collection file="books.toml" style="card" filter="date" >}}
This will display books with year-based filtering buttons, allowing readers to filter by the year they were read.
Last Modified Date Shortcode
The lastmod shortcode displays the last modified date of the current page inline. Useful for indicating content freshness.
Usage:
This page was last updated on {{< lastmod >}}.
Or with custom format:
Last modified: {{< lastmod format="January 2, 2006" >}}
Parameters:
format: Date format string (optional, defaults to site’sdate_formator “January 2006”)
Features:
- Automatically detects last modified date from:
- Page’s
Lastmodfield - Git commit information (if enabled)
- Page’s
Datefield (fallback) - Current date (if none available)
- Page’s
- Respects site’s date format configuration
- Inline display for flexible placement
Combining Shortcodes
You can combine shortcodes for rich content:
Mathematics is the language with which God has written the universe.
Dithered Images
The theme includes unique dithered image functionality. Images are shown in their dithered form by default, which reduces file size while maintaining a unique aesthetic. Click “→ show original” link below each image to toggle between dithered and original versions.
Single Dithered Image
Image not found: example-dithered-images/trees.jpg
The dithering effect reduces the image to a limited color palette, creating a distinctive retro aesthetic while significantly reducing file size—perfect for the smolweb philosophy. The dithered shortcode automatically creates the dithered version using Hugo’s native image processing—no pre-processing required!
Side-by-Side Comparison
For direct comparison, here’s the same image shown in both forms:
Image not found:
How It Works
Processing: Images are dithered using Hugo’s native images.Dither filter with Floyd-Steinberg algorithm:
- Method: Floyd-Steinberg (smooth, high-quality dithering)
- Palette: 5-color grayscale (
#1a1a1a,#4d4d4d,#808080,#b3b3b3,#e6e6e6) - Strength: 0.9 (strong but not harsh)
- Serpentine: Enabled (alternating scan direction for better quality)
The dithering is applied automatically during Hugo’s build process—no external tools or pre-processing required!
Toggle Mechanism: The shortcode generates HTML with both versions. A button in the caption toggles visibility between dithered and original versions. The toggle uses vanilla JavaScript for progressive enhancement.
Benefits:
- Smaller Files: Dithered images are typically 40-60% smaller
- Faster Loading: Reduced bandwidth usage
- Progressive Enhancement: Original available on demand
- Unique Style: Distinctive visual identity
- Retro Appeal: Nostalgic 8-bit aesthetic
- High Contrast: Often more readable
- Smolweb Aligned: Minimal data transfer
- User Choice: Original available when needed
- Accessibility: High contrast improves readability
Usage:
{{< dithered
src="assets/trees.jpg"
alt="A forest scene"
caption="A dithered forest scene"
width="800"
>}}
Note: The dithered shortcode automatically generates the dithered version during build using Hugo’s native image processing. No pre-dithered files or external scripts needed!
Technical Details:
- Algorithm: Floyd-Steinberg dithering with 5-color grayscale palette
- Color Space: Grayscale conversion before dithering
- Format: Supports JPEG, PNG, WebP, AVIF
- Responsive: Hugo’s image processing creates optimized sizes
- Automatic: Dithering applied during build—no pre-processing required
Gallery Shortcode
The gallery shortcode displays a grid of dithered thumbnails with a Lightense lightbox for full-size viewing. Perfect for showcasing multiple images in an organized grid layout.
Usage:
Create a data file in data/gallery-data.toml:
[[images]]
src = "/assets/image1.jpg"
alt = "Description 1"
caption = "Optional caption 1"
[[images]]
src = "/assets/image2.jpg"
alt = "Description 2"
caption = "Optional caption 2"
Then use the shortcode:
{{< gallery file="gallery-data.toml" columns="3" >}}
Parameters:
file: Path to TOML/YAML/JSON file with gallery data (indata/directory)columns: Number of columns (optional, default: 3)thumb_width: Width for thumbnails (optional, default: 300)thumb_height: Height for thumbnails (optional, default: 200)full_width: Width for full view (optional, default: 2400)full_height: Height for full view (optional, default: 1600)thumb_quality: Quality for thumbnails (optional, default: 75)full_quality: Quality for full-size images (optional, default: 95)
Features:
- Dithered thumbnails by default
- Click to view full-size original in lightbox
- Responsive grid layout
- Lazy loading for performance
- Automatic image optimization
Image Gallery Shortcode
The img_gallery shortcode creates a simple grid of images with dithered/original toggle support. Use it when you want to embed multiple images directly in your content.
Usage:
{{< img_gallery columns="3" >}}
{{< img src="assets/image1.jpg" alt="Image 1" caption="Caption 1" >}}
{{< img src="assets/image2.jpg" alt="Image 2" caption="Caption 2" dithered="true" >}}
{{< img src="assets/image3.jpg" alt="Image 3" caption="Caption 3" >}}
{{< /img_gallery >}}
Parameters:
columns: Number of columns (optional, default: 3)
Each img shortcode inside supports all the same parameters as the standalone img shortcode, including dithered, width, height, etc.
Features:
- Flexible grid layout
- Supports dithered/original toggle per image
- Responsive design
- Works with all image shortcode features
Spoiler Gallery Shortcode
The spoiler-gallery shortcode displays a gallery that’s hidden by default, perfect for spoiler-sensitive content like movie screenshots or plot-revealing images.
Usage:
Create a data file in data/movie-screenshots.toml:
[[images]]
src = "/assets/screenshot1.jpg"
alt = "Screenshot 1"
caption = "Scene description"
[[images]]
src = "/assets/screenshot2.jpg"
alt = "Screenshot 2"
caption = "Another scene"
Then use the shortcode:
{{< spoiler-gallery file="movie-screenshots.toml" columns="3" label="Show Screenshots (Spoilers)" >}}
Parameters:
file: Path to TOML/YAML/JSON file with gallery data (indata/directory)columns: Number of columns (optional, default: 3)label: Button text to show gallery (optional, default: “Show Screenshots (Spoilers)”)hide_label: Button text to hide gallery (optional, default: “Hide Screenshots”)thumb_width: Width for thumbnails (optional, default: 300)thumb_height: Height for thumbnails (optional, default: 200)full_width: Width for full view (optional, default: 2400)full_height: Height for full view (optional, default: 1600)thumb_quality: Quality for thumbnails (optional, default: 75)full_quality: Quality for full-size images (optional, default: 95)
Features:
- Hidden by default with toggle button
- Accessible with ARIA attributes
- Responsive grid layout
- Perfect for spoiler-sensitive content
Code Blocks & Syntax Highlighting
The theme supports syntax highlighting for many programming languages.
HTML
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<h1>Hello World</h1>
<p>Welcome to my site.</p>
</main>
<script src="script.js"></script>
</body>
</html>
CSS
:root {
--primary-color: #3498db;
--secondary-color: #2ecc71;
--font-stack: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
}
.container {
max-width: 1200px;
margin: 0 auto;
padding: 2rem;
}
@media (prefers-color-scheme: dark) {
:root {
--primary-color: #5dade2;
--secondary-color: #58d68d;
}
}
Python
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from typing import List, Optional
app = FastAPI()
class Item(BaseModel):
id: int
name: str
description: Optional[str] = None
price: float
items_db = []
@app.get("/items", response_model=List[Item])
async def get_items():
return items_db
@app.post("/items", response_model=Item)
async def create_item(item: Item):
items_db.append(item)
return item
JavaScript
function binarySearch(arr, target) {
let left = 0;
let right = arr.length - 1;
while (left <= right) {
const mid = Math.floor((left + right) / 2);
if (arr[mid] === target) {
return mid; // Found!
} else if (arr[mid] < target) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1; // Not found
}
SQL
-- Create a users table
CREATE TABLE users (
id SERIAL PRIMARY KEY,
username VARCHAR(50) UNIQUE NOT NULL,
email VARCHAR(100) UNIQUE NOT NULL,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);
-- Query with joins
SELECT
u.username,
u.email,
COUNT(p.id) as post_count
FROM users u
LEFT JOIN posts p ON u.id = p.user_id
GROUP BY u.id, u.username, u.email
HAVING COUNT(p.id) > 5
ORDER BY post_count DESC;
Bash
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m' # No Color
echo -e "${GREEN}Starting deployment...${NC}"
# Run tests
if npm test; then
echo -e "${GREEN}Tests passed!${NC}"
else
echo -e "${RED}Tests failed!${NC}"
exit 1
fi
The theme supports many more languages including Go, Ruby, PHP, Java, C++, Rust, and more. All code is displayed with appropriate syntax highlighting based on the language identifier in the code fence.
Mathematical Notation (KaTeX)
Mathematical equations rendered beautifully with KaTeX.
Inline Math
The quadratic formula is $x = \frac{-b \pm \sqrt{b^2-4ac}}{2a}$ when $a \ne 0$.
Einstein’s famous equation: $E = mc^2$
Block Math
The Fourier transform:
$$ F(\omega) = \int_{-\infty}^{\infty} f(t) e^{-i\omega t} dt $$The Cauchy-Schwarz Inequality:
$$\left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right)$$To enable math rendering, add math = true to your post frontmatter.
Mermaid Diagrams
Powered by Mermaid
Mermaid diagrams are great for visualizing processes, workflows, and relationships.
Sequence Diagram
sequenceDiagram
participant web as Web Browser
participant blog as Blog Service
participant account as Account Service
participant mail as Mail Service
participant db as Storage
Note over web,db: The user must be logged in to submit blog posts
web->>+account: Logs in using credentials
account->>db: Query stored accounts
db->>account: Respond with query result
alt Credentials not found
account->>web: Invalid credentials
else Credentials found
account->>-web: Successfully logged in
Note over web,db: When the user is authenticated, they can now submit new posts
web->>+blog: Submit new post
blog->>db: Store post data
par Notifications
blog--)mail: Send mail to blog subscribers
blog--)db: Store in-site notifications
and Response
blog-->>-web: Successfully posted
end
end
Flowchart
graph LR
A[Square Rect] -- Link text --> B((Circle))
A --> C(Round Rect)
B --> D{Rhombus}
C --> D
Git Graph
%%{init: { 'logLevel': 'debug', 'theme': 'base', 'gitGraph': {'rotateCommitLabel': false}} }%%
gitGraph
commit id: "feat(api): ..."
commit id: "a"
commit id: "b"
commit id: "fix(client): .extra long label.."
branch c2
commit id: "feat(modules): ..."
commit id: "test(client): ..."
checkout main
commit id: "fix(api): ..."
commit id: "ci: ..."
branch b1
commit
branch b2
commit
Quadrant Chart
quadrantChart
title Reach and engagement of campaigns
x-axis Low Reach --> High Reach
y-axis Low Engagement --> High Engagement
quadrant-1 We should expand
quadrant-2 Need to promote
quadrant-3 Re-evaluate
quadrant-4 May be improved
Campaign A: [0.3, 0.6]
Campaign B: [0.45, 0.23]
Campaign C: [0.57, 0.69]
Campaign D: [0.78, 0.34]
Campaign E: [0.40, 0.34]
Campaign F: [0.35, 0.78]
Long-Form Content & Structure
Long-form content serves an important purpose in the digital age. While short, snappy content has its place, deeper exploration of topics requires space to breathe and develop ideas fully.
Table of Contents
Enable automatic table of contents by adding toc = true to your frontmatter. This page has it enabled—check the sidebar!
Structure and Organization
Effective long-form content requires careful structure:
Clear Hierarchy: Use headings and subheadings to create a clear outline. Readers should be able to scan the structure and understand the flow of ideas at a glance.
Logical Progression: Ideas should build on each other. Each section should connect naturally to the next, creating a cohesive narrative or argument.
Visual Breaks: Break up text with:
- Subheadings
- Pull quotes
- Lists
- Images
- Code blocks
- Whitespace
Transitions: Good transitions between sections help readers follow your train of thought. They provide context and maintain momentum.
Writing Techniques
Storytelling: Even technical or educational content benefits from narrative elements. Stories make abstract concepts concrete and memorable.
Varied Sentence Structure: Mix short, punchy sentences with longer, more complex ones. This creates rhythm and keeps readers engaged.
Short sentences emphasize points. They create impact. Longer sentences, on the other hand, allow you to develop more nuanced ideas and explore the relationships between concepts, creating a more sophisticated and layered understanding of the topic at hand.
Active Voice: Active voice creates clearer, more direct writing. Instead of “mistakes were made,” say “we made mistakes.” It’s more honest and easier to read.
Concrete Examples: Abstract concepts become clearer with specific examples. Don’t just tell readers something—show them with real-world cases, data, or scenarios.
Outdated Content Alert
The theme can automatically alert readers when content is outdated. Enable it by adding to your frontmatter:
outdate_alert = true
outdate_alert_days = 90
When a post is older than the specified number of days, an alert will be displayed at the top of the post. This helps maintain content quality and informs readers when information may be stale.
Technical Examples
The theme excels at displaying technical content with proper formatting and syntax highlighting.
Algorithm Examples
Quick Sort (Python):
def quicksort(arr):
"""
Quick sort algorithm implementation.
Time complexity: O(n log n) average case
Space complexity: O(log n)
"""
if len(arr) <= 1:
return arr
pivot = arr[len(arr) // 2]
left = [x for x in arr if x < pivot]
middle = [x for x in arr if x == pivot]
right = [x for x in arr if x > pivot]
return quicksort(left) + middle + quicksort(right)
# Example usage
numbers = [3, 6, 8, 10, 1, 2, 1]
sorted_numbers = quicksort(numbers)
print(f"Sorted: {sorted_numbers}")
Configuration Files
TOML Configuration:
base_url = "https://example.com"
title = "My Site"
description = "A demo site"
compile_sass = true
minify_html = false
[markdown]
highlight_code = true
highlight_theme = "base16-ocean-dark"
render_emoji = false
JSON Configuration:
{
"name": "my-project",
"version": "1.0.0",
"description": "A sample project",
"main": "index.js",
"scripts": {
"start": "node index.js",
"dev": "nodemon index.js",
"test": "jest",
"build": "webpack --mode production"
},
"dependencies": {
"express": "^4.18.0",
"dotenv": "^16.0.0"
}
}
Additional Features
Dark Mode
The theme includes automatic dark mode with localStorage persistence. Users can toggle between light and dark themes, and their preference is saved.
Responsive Design
All features are fully responsive and work beautifully on mobile, tablet, and desktop devices.
Accessibility
The theme prioritizes accessibility with:
- WCAG compliant color contrasts
- Semantic HTML
- Keyboard navigation support
- Screen reader friendly markup
Performance
- Optimized image processing
- Minimal JavaScript
- Fast page loads
- Smolweb philosophy
Advanced Features
The theme includes several advanced features for power users and specific use cases.
Gemini Protocol Support
The theme includes full Gemini protocol support with .gmi templates for all page types:
- Homepage with bio and navigation
- Post listings and individual posts
- Tag and category pages
- Collections and consumed content
- Automatic “Web version” links
All Gemini templates use your site’s baseURL configuration, making them portable across domains. When you build your site, Gemini versions are automatically generated alongside HTML versions.
Usage:
Simply build your site normally:
hugo --minify
Gemini versions will be available at paths like:
index.gmi- Homepageposts/post-name.gmi- Individual poststags/tag-name.gmi- Tag pages
Newsletter Generation
Generate newsletter-ready HTML for email campaigns. The theme includes special templates that filter content by the current month and generate copy-paste ready HTML.
Monthly Picks Newsletter:
hugo --renderToMemory --renderStaticToDisk=false \
--baseURL="http://localhost:1313" \
-d public
# Access: http://localhost:1313/picks/list.newsletter.html
New Posts Newsletter:
# Access: http://localhost:1313/posts/list.newsletter.html
The templates filter content by the current month and generate HTML optimized for email platforms like Substack or Buttondown.
Consumed Content Tracking
Track and display books, movies, and music you’ve consumed with ratings and reviews.
Setup:
Create a consumed section in your content directory and add data files in data/consumed.toml:
[[collection]]
title = "Book Title"
author = "Author Name"
category = "books"
year = "2024"
rating = 4
date_read = "2024-11"
content = "Brief thoughts..."
review = "Detailed review..."
image = "/assets/book-cover.jpg"
link = "https://example.com/book"
Display:
Use the collection shortcode in your consumed section:
{{< collection file="consumed.toml" style="card" filter="date" >}}
Features:
- Track books, movies, music, and more
- Star ratings (1-5)
- Date-based filtering
- Category organization
- Reviews and brief thoughts
- Links to external resources
Giscus Integration
The theme includes custom-styled Giscus integration for comments. Giscus uses GitHub Discussions as a comment system.
Configuration:
Add to your hugo.toml:
[params.giscus]
repo = "yourusername/yourrepo"
repoId = "your-repo-id"
category = "Announcements"
categoryId = "your-category-id"
mapping = "pathname"
strict = false
reactionsEnabled = true
emitMetadata = false
inputPosition = "bottom"
theme = "preferred_color_scheme"
lang = "en"
The theme automatically styles Giscus comments to match your site’s design, including dark mode support.
Multilingual Support
The theme includes i18n support with English and Spanish translations included. Additional languages can be added by creating translation files in the i18n/ directory.
Configuration:
defaultContentLanguage = "en"
[languages]
[languages.en]
languageName = "English"
weight = 1
[languages.es]
languageName = "Español"
weight = 2
Features:
- Automatic language detection
- Language switcher in navigation
- Translated UI elements
- Per-language content organization
- RTL support ready
Conclusion
The Apacible theme provides a comprehensive set of features for creating beautiful, accessible, and performant websites. From basic markdown to advanced technical content, everything is designed to work together seamlessly.
Whether you’re writing blog posts, technical documentation, or long-form articles, the theme has the tools you need to create engaging, readable content.
For more information, see the theme README or explore the source code.