Identical to 0.6.0 apart from the version number. This is the first release of
the rewritten Sherwood published to crates.io: versions 0.6.0–0.8.0 were
already used by the pre-rewrite crate under the same name, and crates.io
version numbers are permanently reserved (yanked or not), so the rewrite skips
to 0.9.0. The pre-rewrite releases (old 0.1.0–0.8.0) are yanked.
Added
- Pluggable content parsers. A
ContentParsertrait turns one file's raw source into aParsed { frontmatter, content_html, excerpt_html }payload; aParserRegistrymaps file extensions to parsers (default()registers the built-inMarkdownParserfor.md/.markdown;empty()starts bare;register(Arc::new(MyParser))adds one, last registration for an extension wins). New public exports:ContentParser,Parsed,ParserError,ParserRegistry,MarkdownParser,markdown_to_html,split_frontmatter, plus the layered error typesFrontmatterErrorandPageError. - Base-path support for subpath hosting (e.g.
https://host/sherwood/).SiteConfig.base_path(viawith_base_pathor--base-pathonbuild/serve, normalized to""or"/prefix") prefixes generated URLs:NavItem.href,Breadcrumb.href, and prev/next hrefs come pre-resolved;PageContext::{base_path, resolve}cover hrefs templates build themselves.page.urlandpages_understay canonical (un-prefixed). Output paths are unaffected. The dev server mounts the site under the base path and redirects/to it, matching production. - Static-asset passthrough: files in the content tree whose extension has no registered parser (images, downloads, extra CSS, …) are now copied verbatim to the mirrored output path (
content/blog/img.png→_site/blog/img.png) instead of being silently dropped from the build. - Duplicate-output detection: two sources that map to the same output file (e.g.
content/about.mdandcontent/about/index.md, both →_site/about/index.html; or a staticabout/index.htmlcolliding with a rendered page) now fail the build withBuildError::DuplicateOutputnaming both sources, instead of one silently overwriting the other. - Dogfooding site:
site/is apublish = falseworkspace member that builds the project's documentation site (https://sherwood.thombruce.com) through the library/run_clipath with its own template and stylesheet, deployed to GitHub Pages on push tomain. Excluded from the published crate. - CI now builds and tests the full feature matrix (default, no-default,
cli-only,default-template-only) plus the site as a smoke test. try_run_cli_from(args, registry, renderer, assets)— liketry_run_clibut parses the given arguments (clapparse_fromconvention, first item is the binary name) instead ofstd::env::args, so tests and embedding binaries can drive the CLI directly.
Changed
- Breaking:
build_sitegains a&ParserRegistrysecond parameter:build_site(&config, ®istry, renderer, progress). Pass&ParserRegistry::default()for the previous markdown-only behaviour. - Breaking:
run_cli/try_run_cligain aParserRegistryfirst parameter so binary authors can register custom parsers:run_cli(ParserRegistry::default(), renderer, assets). - Breaking: the module tree is now private behind a facade —
lib.rsre-exports the public API and internal paths (sherwood::build::…,sherwood::page::…, etc.) are no longer reachable. In particular theservemodule (router,router_with_reload,serve_with_watch) is no longer public; the supported serving entry point is the CLI'sservesubcommand. - Breaking:
SiteConfigis#[non_exhaustive]. Downstream crates construct viaSiteConfig::new()/default()and thewith_content_dir/with_output_dir/with_base_pathbuilder methods instead of struct literals. - Breaking: error types are restructured per module.
BuildError::FrontmatterParse { path, message }is gone; parse failures now arrive asBuildError::Page(PageError::Parse { path, source: ParserError })withFrontmatterErrorat the bottom of the chain, and display transparently (path + line-numbered snippet, no stacked prefixes). - Breaking:
parse_frontmatter(source, path) -> (FrontMatter, String, Option<String>)is replaced bysplit_frontmatter(source) -> Result<(FrontMatter, String), FrontmatterError>. Excerpt extraction (<!-- more -->) moved intoMarkdownParser— it's a markdown concern, not a frontmatter one. Third-party parsers using the---/+++convention callsplit_frontmatterand handle excerpts themselves. - The build walks every file and dispatches by extension through the registry, instead of hardcoding
.md;.markdownfiles are now recognized. - Breaking (behaviour): prev/next links are now scoped to the page's section instead of walking the full site-wide build order. Pages chain among siblings sharing the same URL parent — a blog post's neighbours are other posts under
/blog/, never an unrelated page that happened to sort adjacent. Section indexes (/blog/) and top-level pages chain together in the root sequence. Sites relying on the old continuous site-wide chain will see prev/next end at section boundaries.
Fixed
sherwood servenow watches--assetoverride source files: editing e.g. a custom stylesheet triggers a rebuild and live reload, like content edits. Override bytes are also re-read from disk on every rebuild — previously they were read once at startup, so rebuilds rewrote stale bytes.
Removed
- The root demo
content/directory. The barecargo run -- build/servenow need acontent/dir to exist; use--content-diror thesite/workspace member for a runnable example.
Tests
- Test count: 79 → 118 (including 2 doctests).