Expand description
§rs-web - Static Site Generator
A fast, opinionated static site generator built in Rust with support for:
- Markdown processing with syntax highlighting, external link handling
- Content encryption (full post or partial
:::encryptedblocks) - Link graph with backlinks and visualization (Obsidian-style)
- RSS feed generation with section filtering
- Parallel processing for fast builds
§Quick Start
# Build the site
rs-web build
# Build to custom output directory
rs-web build --output public
# Watch for changes and rebuild incrementally
rs-web build --watch
# Enable debug logging
rs-web --debug build
# Set specific log level (trace, debug, info, warning, error)
rs-web --log-level trace build
# Or use environment variable
RS_WEB_LOG_LEVEL=debug rs-web build§Configuration
Configure via config.lua:
return {
site = {
title = "My Site",
description = "Site description",
base_url = "https://example.com",
author = "Your Name",
},
build = {
output_dir = "dist",
minify_css = true,
},
-- Section configuration with custom sort
sections = {
blog = {
iterate = "files",
sort_by = function(a, b)
-- C-style comparator: return -1, 0, or 1
if a.date < b.date then return -1
elseif a.date > b.date then return 1
else return 0 end
end,
},
},
-- Computed data available in templates as {{ computed.tags }}
computed = {
tags = function(sections) return {...} end,
},
-- Generate dynamic pages
computed_pages = function(sections)
return {{ path = "/tags/array/", template = "tag.html", title = "Array", data = {...} }}
end,
-- Custom Tera filters: {{ value | my_filter }}
filters = {
shout = function(s) return s:upper() .. "!" end,
},
-- Build hooks
hooks = {
before_build = function() print("Starting...") end,
after_build = function() print("Done!") end,
},
}§Configuration Sections
site- Required: title, description, base_url, authorbuild- output_dir, minify_css (default: true)images- quality (default: 85.0), scale_factor (default: 1.0)paths- content, styles, static_files, templates, home, excludesections- Per-section config with iterate (“files”/“directories”) and sort_by functiontemplates- Section -> template file mappingpermalinks- Section -> URL pattern (:year,:month,:slug,:title,:section)encryption- password_command or password (SITE_PASSWORD env takes priority)graph- enabled, template, pathrss- enabled, filename, sections, limittext- enabled, sections, exclude_encrypted, include_home
§Lua Sandbox
By default, file operations are sandboxed to the project directory. To disable (use with caution):
return {
lua = { sandbox = false },
site = { ... },
}§Lua API Functions
read_file(path)- Read file contentswrite_file(path, content)- Write content to filefile_exists(path)- Check if file existslist_files(path, pattern?)- List files matching patternlist_dirs(path)- List subdirectoriesload_json(path)- Load and parse JSON fileenv(name)- Get environment variableprint(...)- Log output to build log
All file operations respect the sandbox setting.
§Root Pages
Markdown files at the content root (besides the home page) are processed as
standalone pages. For example, 404.md becomes 404.html:
---
title: "404 - Page Not Found"
template: "error.html"
---
# Page Not Found
The page you're looking for doesn't exist.Default excluded files (disable with exclude_defaults = false):
- README.md, LICENSE.md, CHANGELOG.md, CONTRIBUTING.md, CODE_OF_CONDUCT.md
- Hidden files (starting with
.)
§Frontmatter
Post frontmatter options (YAML or TOML):
---
title: "Post Title" # Required
description: "Description" # Optional
date: 2024-01-15 # Optional (YAML date or string)
tags: ["tag1", "tag2"] # Optional
draft: false # Optional (default: false, excluded from build)
image: "/static/post.png" # Optional: OG image
template: "custom.html" # Optional: Override template
slug: "custom-slug" # Optional: Override URL slug
permalink: "/custom/url/" # Optional: Full URL override
encrypted: false # Optional: Encrypt entire post
password: "post-secret" # Optional: Post-specific password
---§Partial Encryption
Use :::encrypted blocks for partial content encryption:
Public content here.
:::encrypted
This content is encrypted with the global/post password.
:::
:::encrypted password="custom"
This block has its own password.
:::§Template Variables
§Home Template (home.html)
site- Site config (title, description, base_url, author)page- Page info (title, description, url, image)sections- All sections with posts (sections.blog.posts)content- Rendered markdown content
§Post Template (post.html)
site- Site configpost- Post info (title, url, date, tags, reading_time, etc.)page- Page info for head.html compatibilitycontent- Rendered markdown contentbacklinks- Posts linking to this post (url, title, section)graph- Local graph data (nodes, edges) for visualization
§Graph Template (graph.html)
site- Site configpage- Page infograph- Full graph data (nodes, edges)
§Modules
config- Configuration loading and structurescontent- Content discovery and post/page modelsmarkdown- Markdown processing pipelinetemplates- Tera template renderingencryption- AES-GCM encryption for protected contentlinks- Link graph and backlink generationrss- RSS feed generationtext- Plain text output for curl-friendly accessassets- CSS building and image optimizationbuild- Main build orchestrator