Table of Contents

Getting Started

This guide covers everything you need to know to create, customize, and deploy your first Bliki site.

What is Bliki?

Bliki is a static site generator that combines two content paradigms: blogs and wikis.

Blogs organize content chronologically. Posts have dates, tags, and draft states. Readers browse the timeline or filter by tags.

Wikis organize content topically. Pages are linked together, forming a network of information. Readers follow links between related topics.

Bliki does both. You write Markdown files in a content/ folder. Bliki renders them as a complete static website. Each file can be a blog post, a wiki page, or anything in between.

The pages you visit are statically generated — fast, portable, cacheable. But behind the scenes, JavaScript bridges the gap between static and dynamic: SSE pushes rebuild notifications from the server to the browser, and the browser fetches API data to show your auth status, trigger the inline editor, and update UI. Static files for speed, dynamic features where they matter.

Why Bliki?

Install

go install git.mittelab.org/proj/bliki@latest

Verify the installation:

bliki --help

Create a Site

bliki new site ./myblog
cd myblog

This scaffolds the project structure:

myblog/
  bliki.toml      ← configuration
  content/        ← your Markdown files
  theme/          ← templates, CSS, JS

Build & Preview

Build the site:

bliki build

This renders all Markdown files from content/ into public/.

Preview locally:

bliki build --serve

Open http://localhost:3000 in your browser. The server watches for file changes and rebuilds automatically.

To watch and build in one step:

bliki build --watch

You can also skip the --watch flag to serve without auto-rebuild:

bliki build --serve

Add Content

Create a new content file:

bliki new content blog/my-first-post.md

This creates the file at content/blog/my-first-post.md with YAML frontmatter pre-filled:

---
title: "My First Post"
date: 2026-06-02T10:00:00Z
draft: false
layout: "default.tmpl"
---

# My First Post

Hello, world!

Edit the file, save it, and rebuild. Your site updates.

Frontmatter Reference

Every Markdown file in Bliki can include YAML frontmatter between --- delimiters at the top of the file.

Fields

Field Type Required Description
title string Yes Page title
date time Yes Publication date/time (RFC 3339)
description string No Page description / summary
tags []string No List of tags for filtering
draft bool No If true, page is excluded from the build
layout string No Template filename from theme/templates/

Example

---
title: "My Post"
date: 2026-01-01T10:00:00Z
description: "A guide to Bliki frontmatter"
tags: [guide, reference]
draft: false
layout: "default.tmpl"
---

Custom Variables

Any YAML key not listed in the standard fields becomes a custom variable. These are accessible in templates via the get function:

---
title: "My Post"
date: 2026-01-01T10:00:00Z
author: "Jane Doe"
category: "tutorial"
featured: true
---

In your template:

{{ if get . "featured" }}<span>★ Featured</span>{{ end }}

Author: {{ get . "author" }}
Category: {{ get . "category" }}

Custom variables preserve their YAML types:

Markdown Body

Content after the closing --- is rendered as HTML using Goldmark (a CommonMark 0.31.2 compliant Markdown parser):

---
title: "Hello"
date: 2026-01-01T00:00:00Z
---

# Hello World

This is **bold** and this is *italic*.

Theme System

Bliki uses Go's html/template for rendering. Templates live in the theme/templates/ directory and are referenced by name in frontmatter or configuration.

Layouts

Each page specifies a layout in frontmatter:

layout: "default.tmpl"

Layouts define the HTML structure around the rendered content. If no layout is specified in frontmatter, Bliki falls back to default_layout in bliki.toml.

Template Structure

theme/
  templates/
    default.tmpl      ← base layout with {{ define "content" }}
    blog.tmpl         ← overrides "content", adds sidebar
    partials/
      header.tmpl     ← shared nav/header
      footer.tmpl     ← shared footer
      post-meta.tmpl  ← date, tags, author
  css/
    style.css
  js/
    editor.js

All templates are parsed into a single shared template set, so they can reference each other:

{{ template "partials/header.tmpl" . }}
<main>
    {{ content .Current.Content }}
</main>
{{ template "partials/footer.tmpl" . }}

Template Data

Every template receives *site.Site, giving access to:

<title>{{ .Current.Title }}</title>
<nav>
    <a href="/">Home</a>
    {{ range .Pages }}
    <a href="{{ url .FilePath }}">{{ .Title }}</a>
    {{ end }}
</nav>

CSS Customization

Override PicoCSS variables in theme/css/style.css:

:root {
    --pico-primary: #bd3c13;
    --pico-border-radius: 2rem;
}

Everything else is handled by PicoCSS classes — .card, .container, .nav, etc.

Deploy

Bliki generates static HTML — deploy public/ to any web server, CDN, or hosting service. The output directory is self-contained and requires no build step on the hosting side.