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:

  1. First item
    1. Indented item
    2. Indented item
  2. Second item
  3. Third item

There is a link and another link to example.com.

Tables

Basic table:

SyntaxDescriptionTest Text
HeaderTitleHere’s this
ParagraphTextAnd more

With alignment:

SyntaxDescriptionTest Text
LeftCenterRight
ParagraphTextAnd 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.

Note
This is a note callout. Perfect for general information or reminders.
Tip
This is a tip callout. Great for sharing helpful hints or best practices.
Important
This is an important callout. Use it to highlight critical information that readers must know.
Warning
This is a warning callout. Use it to alert users about potential issues or problems.
Caution
This is a caution callout. Use it to warn about dangerous or risky actions.

Quotes

Beautifully styled quotes for highlighting important statements.

Imagination is more important than knowledge. Knowledge is limited. Imagination encircles the world.
Albert Einstein
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 metadata
  • simple-card: Simplified card with just title and brief info
  • list: Minimal list style with optional icons
  • card-grid: Grid of cards with images
  • card-grid-compact: Compact grid layout
  • card-horizontal: Horizontal card layout
  • horizontal: Horizontal layout variant
  • inline: Inline list layout
  • poster-grid: Grid of poster images only

Parameters:

  • file: Path to TOML/YAML/JSON file with collection data (in data/ 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 subtitle
  • content or description: Item description
  • link or url: Link to item
  • image or img: Image URL
  • year: Year field for filtering
  • date or date_read: Date field for filtering
  • category: Category for category filtering
  • tags: Array of tags
  • rating: 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/publisher
  • role: Role/position
  • icon: Icon URL (for list style)
  • footer: Footer text
  • draft: Set to true to hide item
  • type: 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’s date_format or “January 2006”)

Features:

  • Automatically detects last modified date from:
    • Page’s Lastmod field
    • Git commit information (if enabled)
    • Page’s Date field (fallback)
    • Current date (if none available)
  • Respects site’s date format configuration
  • Inline display for flexible placement

Combining Shortcodes

You can combine shortcodes for rich content:

Math in Callouts
You can include math in callouts: $f(x) = x^2 + 2x + 1$
Mathematics is the language with which God has written the universe.
Mathematician

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

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 (in data/ 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

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

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 (in data/ 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 - Homepage
  • posts/post-name.gmi - Individual posts
  • tags/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.


  1. First footnote. ↩︎

  2. Here’s the second footnote. ↩︎