Dynamic rendering
The server reads Markdown at startup and serves HTML on the fly. No static generation — pages are built at request time.
Two languages out of the box
Russian and English. default_language in config controls URL prefixes: / for the primary language, /en/ for the rest. Translations are TOML files in the theme with plural-form support (CLDR: one/few/many for Russian).
Shortcodes as plugins
A unified {load:name;params} syntax for shortcodes in page bodies. Handlers are Rust methods of the shortcodes plugin: contacts (contact block) and include (embed another page's body). Page context is passed straight to handlers, and JS/CSS assets are injected automatically.
Plugin system
A single plugin implements several hook categories: Markdown HTML post-processing, render hooks (pre/post around Tera), Tera functions and filters, middleware layers, and shortcodes. Built-in: gallery, related, updated_note, markdown, force_https, shortcodes. Enabled via [plugins] enabled, options from [plugins.{name}].
OAuth without PHP
Google and Yandex directly from the Rust server. Providers are described declaratively (URLs, keys, profile fields) — adding a new provider requires no logic changes. CSRF protection via a dedicated state-token store with constant-time comparison (subtle::ct_eq). JWT sessions (HMAC-SHA256), secure cookie, sid rotation on upgrade.
RSS and Sitemap
Three sitemap modes: index, per-language, unified with hreflang. RSS 2.0. SHA-256 ETags for conditional requests (304 Not Modified).
Hot reload
A file watcher tracks content/ and theme directories (templates/, sass/, i18n/) — the site auto-updates without a rebuild.
Nested pages and navigation
Arbitrary nesting depth, URLs built from the full sub-path. subpage = true hides a page from listings but keeps it accessible by direct URL. Automatic breadcrumbs and a <title> of the form «Section — Page».
Site search
Built-in server-side search: open to everyone when search_public = true, otherwise authenticated-only. POST form with a one-time CSRF token, sort orders (relevance/date/title/lastmod), pagination 10/30/50/all, <mark> snippets and ?hint= word highlighting. Field weights configurable via [params.search_weights].
Complete hiding of hidden pages
Pages with hidden = "true" are excluded everywhere: listings, tags, RSS, sitemap, search, direct access (404). Hidden-section assets are blocked too.
Rate limiting
Sliding window per IP, configurable via [params.rate_limit]: a shared window, a fallback limit, and glob path rules (*, **, ?), longest match wins.
Security and operations
- CSP built from config plus standard security headers; extra hosts via
csp_script_src/csp_img_src/csp_connect_src. - gzip/brotli compression.
- PROXY protocol and X-Forwarded-For — only from
trusted_proxies. - IP-restricted
/debug(htmx updates, Chart.js charts: requests/s, RSS, CPU, p99 per-route, hit-rate) and/health. /metricsin Prometheus format (uptime, CPU, SQLite, optional tokio metrics).
Footer timing
The site version shows the time of the last content update (file mtime). For authenticated users — the full request handling time.
TLS
Four modes: off / self-signed / file / Let's Encrypt (TLS-ALPN-01). cert_watch reloads certificates on the fly without a restart.
Graceful degradation
If SQLite is unavailable the server keeps running (the page-view counter returns ?); the non-blocking logger falls back to synchronous writes.
Quality
A rich test suite (unit tests in src/ + integration HTTP tests + dedicated suites for content/pages/templates). ≥75% line coverage via make coverage-check (llvm-cov) is part of the Definition of Done. cargo clippy -D warnings — zero warnings, cognitive complexity below 25.
Tech stack
| Component | Technology |
|---|---|
| HTTP server | Axum 0.8 + Tokio |
| Templates | Tera 2 |
| Markdown → HTML | pulldown-cmark 0.13 |
| SCSS → CSS | grass 0.13 |
| Configuration | TOML (serde) |
| i18n | Custom system with plural forms |
| OAuth | Google + Yandex (reqwest, HMAC-SHA256 JWT) |
| Database | SQLite (sqlx 0.9) — views, sessions, audit |
| Search | Built-in server-side (scoring + <mark>) |
| Rate limiting | sliding window per IP (glob rules) |
| Security | CSP + security headers |
| Compression | gzip/brotli (tower-http) |
| TLS | file / self-signed / Let's Encrypt (TLS-ALPN-01) + cert_watch |
| Logging | tracing + file (JSON option), rotation, zip archive |
| Monitoring | /metrics (Prometheus), tokio-metrics (optional) |
| Client-side | htmx, Chart.js |
| Tests | unit + integration (axum), llvm-cov ≥75% |
| Docker | dev/prod/runtime compose + zigbuild (glibc 2.17) |
| Deploy | make dist → build.zip, systemd, HAProxy, Phusion Passenger |