Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions .github/workflows/pages.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
name: Deploy docs to GitHub Pages

on:
push:
branches: [main]
paths:
- "docs/**"
- ".github/workflows/pages.yml"
workflow_dispatch:

permissions:
contents: read
pages: write
id-token: write

concurrency:
group: pages
cancel-in-progress: false

jobs:
deploy:
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- name: Install mdBook
uses: peaceiris/actions-mdbook@v2
with:
mdbook-version: "latest"

- name: Build docs
run: mdbook build docs

- name: Upload artifact
uses: actions/upload-pages-artifact@v3
with:
path: docs/book

- name: Deploy to GitHub Pages
id: deployment
uses: actions/deploy-pages@v4
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ erl_crash.dump

.claude/

docs/book/
58 changes: 58 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,63 @@ There is no single-test runner flag in gleeunit; to run a specific test module,

GitHub Actions runs on push to main/master and on PRs: deps download, test, format check. Requires OTP 28 and Gleam 1.14.0.

The `pages.yml` workflow builds the mdBook docs and deploys to GitHub Pages on push to `main` when `docs/**` changes (or via manual dispatch).

## Documentation

The user-facing docs live in `docs/` and are built with [mdBook](https://rust-lang.github.io/mdBook/). Domain: `blogat.to` (preserved via `docs/CNAME`). API reference docs are published separately on HexDocs from `///` doc comments.

### Structure

```
docs/
├── book.toml # mdBook config
├── SUMMARY.md # Sidebar / table of contents — every doc page MUST be listed here
├── CNAME # GitHub Pages custom domain (blogat.to)
├── favicon.ico, logo.png, og_preview.jpeg # Static assets, auto-copied by mdBook to book/
├── theme/
│ └── head.hbs # Custom <head> injection: favicon.ico link + Open Graph / Twitter meta tags
├── index.md # Landing page (mapped to "Introduction" in SUMMARY.md)
├── getting-started.md # Getting Started section
├── example.md
├── blog-posts.md # Guides section
├── static-pages.md
├── post-components.md
├── syntax-highlighting.md
├── rss-feeds.md
├── atom-feeds.md
├── sitemap-and-robots.md
├── dev-server.md
├── configuration.md # Reference section
└── error-handling.md
```

mdBook is configured with `src = "."` so doc files live directly under `docs/` (no `src/` subdir). Build output goes to `docs/book/` (gitignored, produced in CI).

mdBook does **not** automatically wire favicons (other than its built-in `theme/favicon.png` / `theme/favicon.svg`) or emit Open Graph / Twitter Card meta tags — those are injected via `docs/theme/head.hbs`, which mdBook appends inside every page's `<head>`. The OG image points at `https://blogat.to/og_preview.jpeg` (absolute URL, required by social-media scrapers); the favicon link uses `{{ path_to_root }}favicon.ico` so it resolves on every page. If you change the site description, OG image, or favicon filename, update `theme/head.hbs` accordingly.

### Adding a new doc page

1. Create the new `.md` file directly under `docs/` (flat layout — do not create subdirectories unless adding a whole new top-level section).
2. Decide which top-level section it belongs to: **Getting Started**, **Guides**, or **Reference**. If none fit, add a new `# Section` heading to `SUMMARY.md`.
3. **Always** register the new file in `docs/SUMMARY.md` under the chosen section as `- [Page title](filename.md)`. A page that is not in `SUMMARY.md` will not appear in the sidebar and is not reachable from navigation.
4. Use ATX headings (`#`, `##`, …), start every page with a single `# Title` heading, and follow Markdown conventions enforced by markdownlint.
5. Internal links to other docs use the `.md` extension, e.g. `[Configuration](configuration.md)` or `[Routing](blog-posts.md#custom-routing-with-route_builder)` for anchors. Do not use bare slugs (Jekyll-style) — mdBook resolves links by filename.
6. Update `docs/index.md`'s documentation table if the new page is a top-level guide users should discover from the landing page.

### Modifying or removing a doc page

- Renaming or moving a file: update `docs/SUMMARY.md`, fix all `[text](old.md)` links across `docs/*.md`, and update the landing page table in `docs/index.md` if listed there.
- Deleting a file: remove its entry from `docs/SUMMARY.md` and the landing page table, then grep `docs/` for stale links.
- Always preserve `docs/CNAME` — it pins the `blogat.to` domain.

### Local preview

```bash
mdbook serve docs --open # Live-reload preview at http://localhost:3000
mdbook build docs # One-shot build to docs/book/
```

## Conventions

- Conventional commits (feat, fix, refactor, perf, doc, test, ci, chore) — changelog generated with git-cliff
Expand All @@ -86,3 +143,4 @@ GitHub Actions runs on push to main/master and on PRs: deps download, test, form
- Module docs use `////` comments; public functions/types get `///` doc comments
- Follow Gleam official conventions: qualified imports only (except types/constructors), snake_case functions, PascalCase types, singular module names
- Libraries must never use `let assert` or `panic` — return `Result` instead
- When adding a doc file under `docs/`, also register it in `docs/SUMMARY.md` under the matching section (see Documentation above)
24 changes: 24 additions & 0 deletions docs/SUMMARY.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Summary

[Introduction](index.md)

# Getting Started

- [Getting started](getting-started.md)
- [Example blog](example.md)

# Guides

- [Blog posts](blog-posts.md)
- [Static pages](static-pages.md)
- [Post components](post-components.md)
- [Syntax highlighting](syntax-highlighting.md)
- [RSS feeds](rss-feeds.md)
- [Atom feeds](atom-feeds.md)
- [Sitemap and robots.txt](sitemap-and-robots.md)
- [Dev server](dev-server.md)

# Reference

- [Configuration](configuration.md)
- [Error handling](error-handling.md)
7 changes: 0 additions & 7 deletions docs/_config.yml

This file was deleted.

1 change: 0 additions & 1 deletion docs/_includes/custom-head.html

This file was deleted.

13 changes: 0 additions & 13 deletions docs/_includes/head.html

This file was deleted.

41 changes: 0 additions & 41 deletions docs/_includes/header.html

This file was deleted.

4 changes: 0 additions & 4 deletions docs/_includes/social.html

This file was deleted.

8 changes: 1 addition & 7 deletions docs/atom-feeds.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,6 @@
---
layout: default
title: Atom feeds
nav_order: 10
---

# Atom feeds

Blogatto generates Atom 1.0 feeds from your blog posts. You can configure multiple feeds with different filters (e.g., one per language) and customize how posts are serialized into feed entries. Atom feeds work alongside [RSS feeds](rss-feeds) — both can be generated from the same build.
Blogatto generates Atom 1.0 feeds from your blog posts. You can configure multiple feeds with different filters (e.g., one per language) and customize how posts are serialized into feed entries. Atom feeds work alongside [RSS feeds](rss-feeds.md) — both can be generated from the same build.

## Basic setup

Expand Down
6 changes: 0 additions & 6 deletions docs/blog-posts.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Blog posts
nav_order: 4
---

# Blog posts

Blogatto discovers blog posts from Markdown or Djot files with YAML frontmatter. This guide covers the supported source formats, directory convention, frontmatter fields, multilingual support, and post assets.
Expand Down
12 changes: 12 additions & 0 deletions docs/book.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
[book]
title = "Blogatto"
description = "A Gleam framework for building static blogs with Lustre, Markdown, and Djot"
authors = ["Christian Visintin"]
language = "en"
src = "."

[output.html]
default-theme = "light"
preferred-dark-theme = "navy"
git-repository-url = "https://github.com/veeso/blogatto"
additional-css = []
24 changes: 9 additions & 15 deletions docs/configuration.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Configuration
nav_order: 5
---

# Configuration

Blogatto uses a builder pattern for configuration. Start with `config.new(site_url)` and pipe through setter functions to configure each feature.
Expand Down Expand Up @@ -68,7 +62,7 @@ For example, `./static/css/style.css` becomes `./dist/css/style.css`.

### `config.post(config, post_config)`

Set the post configuration for blog post rendering (applies to both Markdown and Djot sources). See [Post components](post-components) for component customization and [Blog posts](blog-posts) for routing details.
Set the post configuration for blog post rendering (applies to both Markdown and Djot sources). See [Post components](post-components.md) for component customization and [Blog posts](blog-posts.md) for routing details.

```gleam
import blogatto/config/post
Expand Down Expand Up @@ -101,7 +95,7 @@ let md = post.default()
|> post.options(opts)
```

See [Markdown parsing options](blog-posts#markdown-parsing-options) for details on each option.
See [Markdown parsing options](blog-posts.md#markdown-parsing-options) for details on each option.

#### Syntax highlighting

Expand All @@ -116,7 +110,7 @@ let md = post.default()
|> post.syntax_highlighting(code.default())
```

See [Syntax highlighting](syntax-highlighting) for the full guide on supported languages, styling, and customization.
See [Syntax highlighting](syntax-highlighting.md) for the full guide on supported languages, styling, and customization.

#### Markdown routing options

Expand All @@ -125,7 +119,7 @@ The `PostConfig` controls how blog post URLs are generated. You can use either `
- **`post.route_prefix(config, prefix)`** — set a static URL prefix for all posts (e.g., `"blog"` produces `/blog/{slug}/`)
- **`post.route_builder(config, builder)`** — set a function that receives `PostMetadata` and returns a custom URL path per post

See [Custom routing with `route_builder`](blog-posts#custom-routing-with-route_builder) for examples.
See [Custom routing with `route_builder`](blog-posts.md#custom-routing-with-route_builder) for examples.

### `config.route(config, path, view)`

Expand All @@ -139,23 +133,23 @@ config.new("https://example.com")
|> config.route("/about", about_view)
```

See [Static pages](static-pages) for more on writing view functions.
See [Static pages](static-pages.md) for more on writing view functions.

### `config.rss_feed(config, rss_feed_config)`

Add an RSS feed configuration. Can be called multiple times to generate multiple feeds. See [RSS feeds](rss-feeds).
Add an RSS feed configuration. Can be called multiple times to generate multiple feeds. See [RSS feeds](rss-feeds.md).

### `config.atom_feed(config, atom_feed_config)`

Add an Atom 1.0 feed configuration. Can be called multiple times to generate multiple feeds. See [Atom feeds](atom-feeds).
Add an Atom 1.0 feed configuration. Can be called multiple times to generate multiple feeds. See [Atom feeds](atom-feeds.md).

### `config.sitemap(config, sitemap_config)`

Set the sitemap configuration. See [Sitemap and robots.txt](sitemap-and-robots).
Set the sitemap configuration. See [Sitemap and robots.txt](sitemap-and-robots.md).

### `config.robots(config, robots_config)`

Set the robots.txt configuration. See [Sitemap and robots.txt](sitemap-and-robots).
Set the robots.txt configuration. See [Sitemap and robots.txt](sitemap-and-robots.md).

## Common configurations

Expand Down
6 changes: 0 additions & 6 deletions docs/dev-server.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Dev server
nav_order: 12
---

# Dev server

Blogatto includes a built-in development server that watches your source files for changes, automatically rebuilds the site, and live-reloads the browser. This eliminates the need for Docker or external servers during development.
Expand Down
6 changes: 0 additions & 6 deletions docs/error-handling.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Error handling
nav_order: 13
---

# Error handling

All Blogatto build functions return `Result(Nil, BlogattoError)`. The library never panics — every failure is surfaced as a `Result`.
Expand Down
10 changes: 2 additions & 8 deletions docs/example.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Example blog
nav_order: 3
---

# Example blog

Blogatto ships with a complete working example at [`examples/simple_blog`](https://github.com/veeso/blogatto/tree/main/examples/simple_blog). This page walks through it step by step so you can see how all the pieces fit together.
Expand Down Expand Up @@ -73,7 +67,7 @@ let md_config =
- `path("./blog")` — scan the `blog/` directory for post directories
- `route_prefix("blog")` — output posts under `/blog/{slug}/`
- `template(blog_post_template)` — wrap each post in a custom HTML page layout
- `syntax_highlighting(syntax_config)` — enable build-time syntax highlighting for code blocks (see [Syntax highlighting](syntax-highlighting))
- `syntax_highlighting(syntax_config)` — enable build-time syntax highlighting for code blocks (see [Syntax highlighting](syntax-highlighting.md))
- `pre` and `code` — add CSS classes to code block wrappers for styling

### RSS feed
Expand Down Expand Up @@ -369,4 +363,4 @@ cd examples/simple_blog
gleam run -m simple_blog/dev
```

This starts a local server at `http://127.0.0.1:3000` that watches for file changes, rebuilds the site, and live-reloads the browser. See [Dev server](dev-server) for full documentation.
This starts a local server at `http://127.0.0.1:3000` that watches for file changes, rebuilds the site, and live-reloads the browser. See [Dev server](dev-server.md) for full documentation.
14 changes: 4 additions & 10 deletions docs/getting-started.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,3 @@
---
layout: default
title: Getting started
nav_order: 2
---

# Getting started

This guide walks you through installing Blogatto and building your first static blog.
Expand Down Expand Up @@ -159,7 +153,7 @@ See the [simple_blog example](https://github.com/veeso/blogatto/tree/main/exampl

## Next steps

- [Blog posts](blog-posts) — learn about frontmatter, multilingual support, and post assets
- [Configuration](configuration) — explore all configuration options
- [Syntax highlighting](syntax-highlighting) — enable build-time code block highlighting
- [Static pages](static-pages) — add more pages and use post data in views
- [Blog posts](blog-posts.md) — learn about frontmatter, multilingual support, and post assets
- [Configuration](configuration.md) — explore all configuration options
- [Syntax highlighting](syntax-highlighting.md) — enable build-time code block highlighting
- [Static pages](static-pages.md) — add more pages and use post data in views
Loading