···11+---
22+title: "Entrypoint"
33+description: "Welcome to the Maudit documentation!"
44+---
55+66+Something
+6-20
website/content/docs/index.md
···11---
22title: "Prologue"
33-description: "You're gonna learn"
43---
5466-## Section 1: Formatting Text
77-88-### Bold and Italic
99-1010-- **Bold Text** makes things stand out.
1111-- _Italic Text_ gives emphasis to words.
1212-- **_Bold and Italic_** combined for maximum emphasis.
1313-1414-### Mixed Formatting
1515-1616-- **This is bold and _italic_** to combine styles.
1717-- _This is italic and **bold**_ as well.
55+Welcome to the Maudit documentation! Maudit (pronounced /mo.di/, meaning _cursed_ in French) is a static site generator.
1861919-## Section 2: Links
77+[Static site generators](https://en.wikipedia.org/wiki/Static_site_generator) are tools that take a collection of files and convert them into a website, once in a build step. This is in contrast to dynamic websites, which are generated on-the-fly by a server. Other similar tools include [Jekyll](https://jekyllrb.com), [Hugo](https://gohugo.io), [Astro](https://astro.build), [Eleventy](https://www.11ty.dev), [Zola](https://www.getzola.org) and [many more](https://jamstack.org/generators/).
2082121-You can include links like this:
99+Maudit aims to be a simple and easy-to-use static site generator, [nothing more](/docs/philosophy/). We hope that you'll find it useful for your projects, and we're excited to see what you'll create with it!
22102323-- [Check out the Markdown Guide](https://www.markdownguide.org/)
1111+### Audience
24122525-## Section 3: Combining All Features
2626-2727-Here’s a sentence that combines everything:
1313+This documentation assumes basic knowledge of web development (e.g. HTML and CSS) and Rust. If you are new to web development, we recommend checking out the [MDN Web Docs](https://developer.mozilla.org/en-US/docs/Web) and for Rust, the [Rust Book](https://doc.rust-lang.org/book/).
28142929-- **_Check out the [Markdown Guide](https://www.markdownguide.org/) for more tips_**.
1515+Having said that, we do try to make the documentation approchable for beginners, and concepts will generally be explained as they are introduced.
+40
website/content/docs/installation.md
···44section: "getting-started"
55---
6677+### Prerequisites
88+99+- [Rust (1.83 or later)](https://www.rust-lang.org)
1010+- A code editor (e.g. Visual Studio Code, RustRover, Helix, etc.)
1111+- A terminal emulator (e.g. Windows Terminal, Terminal.app, Ghostty, etc.)
1212+1313+We recommend using [rustup](https://rustup.rs/) to install Rust. Maudit is intended to be used with the latest stable version of Rust and does not require nightly features.
1414+1515+Once Rust is installed, run the following command to ensure the latest stable version of Rust is being used:
1616+1717+```bash
1818+rustup default stable
1919+```
2020+2121+### Installing Maudit
2222+2323+Maudit provides a CLI tool for interacting with websites created using the library and generating new ones. To install the CLI tool, run the following command:
2424+2525+```bash
2626+cargo install maudit-cli
2727+```
2828+2929+This will install the `maudit` binary in your Cargo bin directory. You can now run `maudit --help` to see the available commands and options.
3030+3131+If you do not wish to use the CLI, or are integrating Maudit into an existing project, follow the instructions in the [manual installation guide](/docs/manual-install).
3232+3333+### Creating a new project
3434+3535+To create a new Maudit project, run the following command:
3636+3737+```bash
3838+maudit init
3939+```
4040+4141+Maudit will then ask you a series of questions to configure your project. Once complete, you can navigate to the project directory and start the development server using `maudit dev`:
4242+4343+```bash
4444+cd my-website
4545+maudit dev
4646+```
+20
website/content/docs/manual-install.md
···11+---
22+title: "Manual installation"
33+description: "While it is recommended to use the CLI tool to create and manage Maudit projects, it is also possible to manually install Maudit like any other Rust library."
44+---
55+66+Create a new Rust project using Cargo, specifying the `--bin` flag to create a binary project:
77+88+```bash
99+cargo new my-website --bin
1010+cd my-website
1111+```
1212+1313+Next, add Maudit as a dependency in your `Cargo.toml` file, or run `cargo add maudit` to do so automatically:
1414+1515+```toml
1616+[dependencies]
1717+maudit = "0.1"
1818+```
1919+2020+Voilà! You can now use Maudit in your project. Check out the rest of the [documentation](/docs) for more information on how to use Maudit, or if you prefer jumping straght into the code, take a look at the [examples](https://github.com/Princesseuh/maudit/tree/main/examples).
+10-2
website/content/docs/philosophy.md
···11---
22title: "Philosophy"
33-description: "What is Maudit?"
33+description: "Maudit follows a few core principles that guide its development and design"
44section: "getting-started"
55---
6677-Maudit is a tool for creating and managing documentation websites. It is designed to be simple, fast, and easy to use. Maudit is built with [Hugo](https://gohugo.io/), a static site generator written in Go.
77+### Maudit is about making static websites
88+99+Many of the so-called modern web frameworks have gained new output modes opposite to their original purpose, for instance Next.js, a SSR-first framework, has `output: "export"` to generate a static website and Astro, SSG-first, has `output: "server"` to do the reverse.
1010+1111+While there is nothing intrinsically wrong with wanting to grow the use cases your software can serve, supporting different output modes comes with a inherent cost, both technological and human.
1212+1313+Supporting certain features in your less used output mode might add technical constraints affecting your main use case, and your attention is forever split between the two universes you intend to support.
1414+1515+**Maudit is about making static websites**. It has no higher goals than that. It won't try to become a server-side rendering framework, a hybrid framework, or anything else.
···11+---
22+title: "Routing"
33+description: "How to create pages and routes in Maudit"
44+section: "core-concepts"
55+---
66+77+### Static Routes
88+99+Maudit uses a simple and intuitive API to define routes and pages. To create a new page, define a struct that implements the `Page` trait, adding the `#[route]` attribute to the struct definition with the path of the route as an argument.
1010+1111+```rust
1212+use maudit::page::prelude::*;
1313+1414+#[route("/hello-world")]
1515+pub struct HelloWorld;
1616+1717+impl Page for HelloWorld {
1818+ fn render(&self, ctx: &PageContext) -> RenderResult {
1919+ RenderResult::Text("Hello, world!".to_string())
2020+ }
2121+}
2222+```
2323+2424+The `Page` trait requires the implementation of a `render` method that returns a `RenderResult`. This method is called when the page is built and should return the content that will be displayed. In most cases, you'll be using a templating library to create HTML content.
2525+2626+Finally, make sure to [register the page](#registering-routes) in the `coronate` function for it to be built.
2727+2828+### Dynamic Routes
2929+3030+Maudit supports creating dynamic routes with parameters. Allowing one to create many pages that share the same structure and logic, but with different content.
3131+3232+For example, one could create a route that matches `/posts/[slug]` and renders a page with the content of the post with the given slug.
3333+3434+To create a dynamic route, export a struct using the `route!` macro and add parameters to the route path using the `[]` syntax. For example, to create a route that matches `/posts/[slug]`, you would write:
3535+3636+```rust
3737+use maudit::route::prelude::*;
3838+3939+#[route("/posts/[slug]")]
4040+pub struct Post;
4141+4242+impl Page for Post {
4343+ fn render(&self, ctx: &PageContext) -> String {
4444+ format!("Hello, {}!", ctx.params.get("slug").unwrap())
4545+ }
4646+}
4747+```
4848+4949+In addition to the `Page` trait, dynamic routes must implement the `DynamicRoute` trait for their struct. This trait requires a `routes` function that returns a list of all the possible values for each parameter in the route's path.
5050+5151+```rust
5252+use maudit::{page::prelude::*, FxHashMap};
5353+5454+#[route("/posts/[slug]")]
5555+pub struct Post;
5656+5757+impl DynamicRoute for Post {
5858+ fn routes(&self, ctx: &DynamicRouteContext) -> Vec<RouteParams> {
5959+ let mut routes = FxHashMap::default();
6060+ routes.insert("slug".to_string(), "hello-world".to_string());
6161+6262+ vec![RouteParams(routes)]
6363+ }
6464+}
6565+6666+impl Page for Post {
6767+ fn render(&self, ctx: &PageContext) -> RenderResult {
6868+ RenderResult::Text(format!("Hello, {}!", ctx.params.get("slug").unwrap()))
6969+ }
7070+}
7171+```
7272+7373+The `RouteParams` type is a [newtype](https://doc.rust-lang.org/rust-by-example/generics/new_types.html) around a `FxHashMap<String, String>`, representing the raw parameters as if they were directly extracted from an URL.
7474+7575+Interacting with HashMaps in Rust can be a bit cumbersome, so Maudit provides the ability to use a custom struct to define your params and easily convert them into `RouteParams` after.
7676+7777+```rust
7878+#[derive(Params)]
7979+pub struct Params {
8080+ pub slug: String,
8181+}
8282+8383+impl DynamicRoute for Post {
8484+ fn routes(&self, ctx: &DynamicRouteContext) -> Vec<RouteParams> {
8585+ let routes = vec![ArticleParams {
8686+ slug: "hello-world".to_string(),
8787+ }];
8888+8989+ RouteParams::from_vec(routes)
9090+ }
9191+}
9292+```
9393+9494+This struct can also be used when defining the `Page` implementation, making it possible to access the parameters in a type-safe way. For more information on how to use the `Params` derive, see the [TODO](TODO) section.
9595+9696+```rust
9797+#[derive(Params)]
9898+pub struct Params {
9999+ pub slug: String,
100100+}
101101+102102+impl Page for Post {
103103+ fn render(&self, ctx: &PageContext) -> RenderResult {
104104+ let params = ctx.params::<Params>();
105105+106106+ RenderResult::Text(format!("Hello, {}!", params.slug))
107107+ }
108108+}
109109+```
110110+111111+Like static routes, dynamic routes must be [registered](#registering-routes) in the `coronate` function in order for them to be built.
112112+113113+### Endpoints
114114+115115+Maudit supports returning other types of content besides HTML, such as JSON or plain text. To do this, simply add a file extension to the route path and return the content in the `render` method.
116116+117117+```rust
118118+use maudit::page::prelude::*;
119119+120120+#[route("/api.json")]
121121+pub struct HelloWorldJson;
122122+123123+impl Page for HelloWorldJson {
124124+ fn render(&self, ctx: &PageContext) -> RenderResult {
125125+ RenderResult::Text(r#"{"message": "Hello, world!"}"#.to_string())
126126+ }
127127+}
128128+```
129129+130130+Dynamic routes can also return different types of content. For example, to return a JSON response with the post's content, you could write:
131131+132132+```rust
133133+use maudit::page::prelude::*;
134134+135135+#[route("/api/[slug].json")]
136136+pub struct PostJson;
137137+138138+#[derive(Params)]
139139+pub struct Params {
140140+ pub slug: String,
141141+}
142142+143143+impl DynamicRoute for PostJson {
144144+ fn routes(&self, ctx: &DynamicRouteContext) -> Vec<RouteParams> {
145145+ let routes = vec![Params { slug: "hello-world".to_string() }];
146146+147147+ RouteParams::from_vec(routes)
148148+ }
149149+}
150150+151151+impl Page for PostJson {
152152+ fn render(&self, ctx: &PageContext) -> RenderResult {
153153+ let params = ctx.params::<Params>();
154154+155155+ RenderResult::Text(format!(r#"{{"message": "Hello, {}!"}}"#, params.slug))
156156+ }
157157+}
158158+```
159159+160160+Endpoints must also be [registered](#registering-routes) in the `coronate` function in order for them to be built.
161161+162162+### Registering Routes
163163+164164+All kinds of routes must be passed to the `coronate` function in [the entrypoint](/docs/entrypoint) in order to be built.
165165+166166+The first argument to the `coronate` function is a `Vec` of all the routes that should be built. This list can be created using the `routes!` macro to make it more concise.
167167+168168+```rust
169169+use pages::Index;
170170+use maudit::{coronate, routes, BuildOptions, BuildOutput};
171171+172172+fn main() -> Result<BuildOutput, Box<dyn std::error::Error>> {
173173+ coronate(
174174+ routes![Index],
175175+ vec![].into(),
176176+ BuildOptions::default()
177177+ )
178178+}
179179+```