Imports
/-
Copyright (c) 2026 Jonathan Prieto-Cubides. All rights reserved.
Released under Apache 2.0 license as described in the file LICENSE.
-/
import Lean.Data.JsonSite configuration
The CLI reads leanblog.json when it exists. Keeping the configuration model separate from the
renderer lets a template change its identity and deployment details without editing framework code.
namespace LeanBlogopen LeanA navigation link rendered in the site header.
structure whereThe visible label.
: StringA site-relative URL.
: String
deriving ReprThe user-facing identity and deployment settings for a LeanBlog site.
structure SiteConfig whereThe site and browser title.
title : String := "LeanBlog"The short description shown on the archive.
tagline : String := "A calm home for Lean-aware writing."The default author metadata for the site.
author : String := ""The canonical site URL, when the deployment has one.
siteUrl : String := ""The deployment base path, retained for generated metadata.
basePath : String := "/"The footer text.
: String := "Built with LeanBlog, Verso, Tailwind, and daisyUI."The heading used above the archive entries.
archiveTitle : String := "Recent posts"The visible label for the archive navigation link.
archiveLabel : String := "All posts"The URL prefix used by declaration links.
docsRoot : String := "/api"The output directory name used for copied API documentation.
docsDirectory : String := "api"
The initial color mode: light, dark, or system.
defaultTheme : String := "system"Additional links rendered in the primary navigation.
: Array NavigationItem := #[]
deriving Reprnamespace SiteConfigThe defaults used when no configuration file is present.
def default : SiteConfig := {}private
def stringField
(json : Json)
(key : String)
(fallback : String)
: Except String String
:=
match json.getObjVal? key with
| .error _ => pure fallback
| .ok value => value.getStr?private
def
(json : Json)
: Except String (Array NavigationItem)
:= do
match json.getObjVal? "navigation" with
| .error _ => pure #[]
| .ok value =>
let entries ← value.getArr?
entries.mapM fun entry => do
let label ← entry.getObjValAs? String "label"
let href ← entry.getObjValAs? String "href"
pure {label, href}Decode a site configuration object, using defaults for omitted fields.
def fromJson?
(json : Json)
: Except String SiteConfig
:= do
let _ ← json.getObj?
let title ← stringField json "title" default.title
let tagline ← stringField json "tagline" default.tagline
let author ← stringField json "author" default.author
let siteUrl ← stringField json "siteUrl" default.siteUrl
let basePath ← stringField json "basePath" default.basePath
let footer ← stringField json "footer" default.footer
let archiveTitle ← stringField json "archiveTitle" default.archiveTitle
let archiveLabel ← stringField json "archiveLabel" default.archiveLabel
let docsRoot ← stringField json "docsRoot" default.docsRoot
let docsDirectory ← stringField json "docsDirectory" default.docsDirectory
let defaultTheme ← stringField json "defaultTheme" default.defaultTheme
let navigation ← navigationField json
pure {
title := title
tagline := tagline
author := author
siteUrl := siteUrl
basePath := basePath
footer := footer
archiveTitle := archiveTitle
archiveLabel := archiveLabel
docsRoot := docsRoot
docsDirectory := docsDirectory
defaultTheme := defaultTheme
navigation := navigation
}end SiteConfigend LeanBlog