← Back to overview

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».

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.
  • /metrics in Prometheus format (uptime, CPU, SQLite, optional tokio metrics).

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

ComponentTechnology
HTTP serverAxum 0.8 + Tokio
TemplatesTera 2
Markdown → HTMLpulldown-cmark 0.13
SCSS → CSSgrass 0.13
ConfigurationTOML (serde)
i18nCustom system with plural forms
OAuthGoogle + Yandex (reqwest, HMAC-SHA256 JWT)
DatabaseSQLite (sqlx 0.9) — views, sessions, audit
SearchBuilt-in server-side (scoring + <mark>)
Rate limitingsliding window per IP (glob rules)
SecurityCSP + security headers
Compressiongzip/brotli (tower-http)
TLSfile / self-signed / Let's Encrypt (TLS-ALPN-01) + cert_watch
Loggingtracing + file (JSON option), rotation, zip archive
Monitoring/metrics (Prometheus), tokio-metrics (optional)
Client-sidehtmx, Chart.js
Testsunit + integration (axum), llvm-cov ≥75%
Dockerdev/prod/runtime compose + zigbuild (glibc 2.17)
Deploymake dist → build.zip, systemd, HAProxy, Phusion Passenger