flatpage

A simple file system based markdown flat page

3 unstable releases

0.2.0 Jan 15, 2024
0.1.1 Jul 1, 2022
0.1.0 Jul 1, 2022

MIT license

22KB
355 lines

License Crates.io Docs.rs

A simple file system based markdown flat page.

Folder structure

Only characters allowed in urls are ASCII, numbers and hyphen with underscore. Urls map to files by simply substituting / to ^ and adding .md extension. I believe it should eliminate all kinds of security issues.

url file name
/ ^.md
/foo/bar-baz ^foo^bar-baz.md

Page format

File could provide title and description in a yaml-based frontmatter, if there's no frontmatter the first line would be considered the title (and cleaned from possible header marker #).

File content title description body html()
# Foo
Bar
"Foo" None "# Foo\nBar" "<h1>Foo</h1>\n<p>Bar</p>\n"
---
description: Bar
---
# Foo
"Foo" Some("Bar") "# Foo" "<h1>Foo</h1>\n"
---
title: Foo
description: Bar
---
"Foo" Some("Bar") "" ""

Reading a page

let root_folder = "./";
if let Some(home) = flatpage::FlatPage::<()>::by_url(root_folder, "/").unwrap() {
    println!("title: {}", home.title);
    println!("description: {:?}", home.description);
    println!("markdown body: {}", home.body);
    println!("html body: {}", home.html());
} else {
    println!("No home page");
}

Extra frontmatter fields

You can define extra statically typed frontmatter fields

#[derive(Debug, serde::Deserialize)]
struct Extra {
    slug: String,
}

let _page = flatpage::FlatPage::<Extra>::by_url("./", "/").unwrap();

Cached metadata

It's a common for a page to have a list of related pages. To avoid reading all the files each time, you can use FlatPageStore to cache pages metadata (titles and descriptions).

let root_folder = "./";
let store = flatpage::FlatPageStore::read_dir(root_folder).unwrap();
if let Some(meta) = store.meta_by_url("/") {
    println!("title: {}", meta.title);
    println!("description: {:?}", meta.description);
} else {
    println!("No home page");
}

Contributing

We appreciate all kinds of contributions, thank you!

Note on README

Most of the readme is automatically copied from the crate documentation by cargo-sync-readme. This way the readme is always in sync with the docs and examples are tested.

So if you find a part of the readme you'd like to change between <!-- cargo-sync-readme start --> and <!-- cargo-sync-readme end --> markers, don't edit README.md directly, but rather change the documentation on top of src/lib.rs and then synchronize the readme with:

cargo sync-readme

(make sure the cargo command is installed):

cargo install cargo-sync-readme

If you have rusty-hook installed the changes will apply automatically on commit.

License

This project is licensed under the MIT license.

Dependencies

~5MB
~100K SLoC