Switch documentation to semantic line breaks (#259)
mdformat will preserve semantic line breaks, so we may as well commit to using them. cc #231
This commit is contained in:
parent
eaf552d417
commit
75b6801f47
10 changed files with 155 additions and 48 deletions
13
README.md
13
README.md
|
@ -3,11 +3,18 @@
|
|||
[](https://crates.io/crates/maud)
|
||||
[](https://docs.rs/maud/)
|
||||
|
||||
[Documentation][book] ([source][booksrc]) • [API reference][apiref] • [Change log][changelog]
|
||||
[Documentation][book] ([source][booksrc]) •
|
||||
[API reference][apiref] •
|
||||
[Change log][changelog]
|
||||
|
||||
Maud is an HTML template engine for Rust. It's implemented as a macro, `html!`, which compiles your markup to specialized Rust code. This unique approach makes Maud templates blazing fast, super type-safe, and easy to deploy.
|
||||
Maud is an HTML template engine for Rust.
|
||||
It's implemented as a macro, `html!`,
|
||||
which compiles your markup to specialized Rust code.
|
||||
This unique approach makes Maud templates
|
||||
blazing fast, super type-safe, and easy to deploy.
|
||||
|
||||
For more info on Maud, see the [official book][book].
|
||||
For more info on Maud,
|
||||
see the [official book][book].
|
||||
|
||||
[book]: https://maud.lambda.xyz/
|
||||
[booksrc]: https://github.com/lambda-fairy/maud/tree/master/docs
|
||||
|
|
|
@ -1,10 +1,14 @@
|
|||
# Control structures
|
||||
|
||||
Maud provides various control structures for adding dynamic elements to your templates.
|
||||
Maud provides various control structures
|
||||
for adding dynamic elements to your templates.
|
||||
|
||||
## Branching with `@if` and `@else`
|
||||
|
||||
Use `@if` and `@else` to branch on a boolean expression. As with Rust, braces are mandatory and the `@else` clause is optional.
|
||||
Use `@if` and `@else` to branch on a boolean expression.
|
||||
As with Rust,
|
||||
braces are mandatory
|
||||
and the `@else` clause is optional.
|
||||
|
||||
```rust
|
||||
#[derive(PartialEq)]
|
||||
|
@ -69,7 +73,8 @@ html! {
|
|||
|
||||
## Declaring variables with `@let`
|
||||
|
||||
Declare a new variable within a template using `@let`. This can be useful when working with values in a for loop.
|
||||
Declare a new variable within a template using `@let`.
|
||||
This can be useful when working with values in a for loop.
|
||||
|
||||
```rust
|
||||
let names = ["Applejack", "Rarity", "Fluttershy"];
|
||||
|
|
|
@ -16,7 +16,10 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
Before version 0.18, Maud allowed the curly braces to be omitted. This syntax was [removed][#137] and now causes an error instead.
|
||||
Before version 0.18,
|
||||
Maud allowed the curly braces to be omitted.
|
||||
This syntax was [removed][#137]
|
||||
and now causes an error instead.
|
||||
|
||||
[#137]: https://github.com/lambda-fairy/maud/pull/137
|
||||
|
||||
|
@ -41,15 +44,20 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
The result will be rendered with HTML syntax – `<br>` not `<br />`.
|
||||
The result will be rendered with HTML syntax –
|
||||
`<br>` not `<br />`.
|
||||
|
||||
Maud also supports ending a void element with a slash: `br /`. This syntax is [deprecated][#96] and should not be used in new code.
|
||||
Maud also supports ending a void element with a slash:
|
||||
`br /`.
|
||||
This syntax is [deprecated][#96]
|
||||
and should not be used in new code.
|
||||
|
||||
[#96]: https://github.com/lambda-fairy/maud/pull/96
|
||||
|
||||
## Custom elements and `data` attributes
|
||||
|
||||
Maud also supports elements and attributes with hyphens in them. This includes [custom elements], [data attributes], and [ARIA annotations].
|
||||
Maud also supports elements and attributes with hyphens in them.
|
||||
This includes [custom elements], [data attributes], and [ARIA annotations].
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -68,7 +76,11 @@ html! {
|
|||
|
||||
## Non-empty attributes: `title="yay"`
|
||||
|
||||
Add attributes using the syntax: `attr="value"`. You can attach any number of attributes to an element. The values must be quoted: they are parsed as string literals.
|
||||
Add attributes using the syntax:
|
||||
`attr="value"`.
|
||||
You can attach any number of attributes to an element.
|
||||
The values must be quoted:
|
||||
they are parsed as string literals.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -105,13 +117,20 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
Before version 0.22.2, Maud required a `?` suffix on empty attributes: `checked?`. This is no longer necessary ([#238]), but still supported for backward compatibility.
|
||||
Before version 0.22.2,
|
||||
Maud required a `?` suffix on empty attributes:
|
||||
`checked?`.
|
||||
This is no longer necessary ([#238]),
|
||||
but still supported for backward compatibility.
|
||||
|
||||
[#238]: https://github.com/lambda-fairy/maud/pull/238
|
||||
|
||||
## Classes and IDs: `.foo` `#bar`
|
||||
|
||||
Add classes and IDs to an element using `.foo` and `#bar` syntax. You can chain multiple classes and IDs together, and mix and match them with other attributes:
|
||||
Add classes and IDs to an element
|
||||
using `.foo` and `#bar` syntax.
|
||||
You can chain multiple classes and IDs together,
|
||||
and mix and match them with other attributes:
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -121,7 +140,9 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
The classes and IDs can be quoted. This is useful for names with numbers or symbols which otherwise wouldn't parse:
|
||||
The classes and IDs can be quoted.
|
||||
This is useful for names with numbers or symbols
|
||||
which otherwise wouldn't parse:
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -133,7 +154,9 @@ html! {
|
|||
|
||||
## Implicit `div` elements
|
||||
|
||||
If the element name is omitted, but there is a class or ID, then it is assumed to be a `div`.
|
||||
If the element name is omitted,
|
||||
but there is a class or ID,
|
||||
then it is assumed to be a `div`.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
|
|
@ -31,11 +31,15 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
`html!` takes a single argument: a template using Maud's custom syntax. This call expands to an expression of type [`Markup`][Markup], which can then be converted to a `String` using `.into_string()`.
|
||||
`html!` takes a single argument:
|
||||
a template using Maud's custom syntax.
|
||||
This call expands to an expression of type [`Markup`][Markup],
|
||||
which can then be converted to a `String` using `.into_string()`.
|
||||
|
||||
[Markup]: https://docs.rs/maud/*/maud/type.Markup.html
|
||||
|
||||
Run this program with `cargo run`, and you should get the following:
|
||||
Run this program with `cargo run`,
|
||||
and you should get the following:
|
||||
|
||||
```html
|
||||
<p>Hi, Lyra!</p>
|
||||
|
|
|
@ -15,25 +15,41 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
Maud is an HTML [template engine] for Rust. It's implemented as a macro, `html!`, which compiles your markup to specialized Rust code. This unique approach makes Maud templates blazing fast, super type-safe, and easy to deploy.
|
||||
Maud is an HTML [template engine] for Rust.
|
||||
It's implemented as a macro, `html!`,
|
||||
which compiles your markup to specialized Rust code.
|
||||
This unique approach makes Maud templates
|
||||
blazing fast, super type-safe, and easy to deploy.
|
||||
|
||||
[template engine]: https://www.simple-is-better.org/template/
|
||||
|
||||
## Tight integration with Rust
|
||||
|
||||
Since Maud is a Rust macro, it can borrow most of its features from the host language. Pattern matching and `for` loops work as they do in Rust. There is no need to derive JSON conversions, as your templates can work with Rust values directly.
|
||||
Since Maud is a Rust macro,
|
||||
it can borrow most of its features from the host language.
|
||||
Pattern matching and `for` loops work as they do in Rust.
|
||||
There is no need to derive JSON conversions,
|
||||
as your templates can work with Rust values directly.
|
||||
|
||||
## Type safety
|
||||
|
||||
Your templates are checked by the compiler, just like the code around them. Any typos will be caught at compile time, not after your app has already started.
|
||||
Your templates are checked by the compiler,
|
||||
just like the code around them.
|
||||
Any typos will be caught at compile time,
|
||||
not after your app has already started.
|
||||
|
||||
## Minimal runtime
|
||||
|
||||
Since most of the work happens at compile time, the runtime footprint is small. The Maud runtime library, including integration with the [Rocket] and [Actix] web frameworks, is around 100 SLoC.
|
||||
Since most of the work happens at compile time,
|
||||
the runtime footprint is small.
|
||||
The Maud runtime library,
|
||||
including integration with the [Rocket] and [Actix] web frameworks,
|
||||
is around 100 SLoC.
|
||||
|
||||
[Rocket]: https://rocket.rs/
|
||||
[Actix]: https://actix.rs/
|
||||
|
||||
## Simple deployment
|
||||
|
||||
There is no need to track separate template files, since all relevant code is linked into the final executable.
|
||||
There is no need to track separate template files,
|
||||
since all relevant code is linked into the final executable.
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
# Partials
|
||||
|
||||
Maud does not have a built-in concept of partials or sub-templates. Instead, you can compose your markup with any function that returns `Markup`.
|
||||
Maud does not have a built-in concept of partials or sub-templates.
|
||||
Instead,
|
||||
you can compose your markup with any function that returns `Markup`.
|
||||
|
||||
The following example defines a `header` and `footer` function.
|
||||
These functions are combined to form the final `page`.
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
# The `Render` trait
|
||||
|
||||
By default, a [`(splice)`](splices-toggles.md) is rendered using the [`std::fmt::Display`][Display] trait, with any HTML special characters escaped automatically.
|
||||
By default,
|
||||
a [`(splice)`](splices-toggles.md) is rendered using the [`std::fmt::Display`][Display] trait,
|
||||
with any HTML special characters escaped automatically.
|
||||
|
||||
To change this behavior, implement the [`Render`][Render] trait for your type. Then, when a value of this type is used in a template, Maud will call your custom code instead.
|
||||
To change this behavior,
|
||||
implement the [`Render`][Render] trait for your type.
|
||||
Then, when a value of this type is used in a template,
|
||||
Maud will call your custom code instead.
|
||||
|
||||
Below are some examples of using `Render`. Feel free to use these snippets in your own project!
|
||||
Below are some examples of using `Render`.
|
||||
Feel free to use these snippets in your own project!
|
||||
|
||||
## Example: a shorthand for including CSS stylesheets
|
||||
|
||||
When writing a web page, it can be annoying to write `link rel="stylesheet"` over and over again. This example provides a shorthand for linking to CSS stylesheets.
|
||||
When writing a web page,
|
||||
it can be annoying to write `link rel="stylesheet"` over and over again.
|
||||
This example provides a shorthand for linking to CSS stylesheets.
|
||||
|
||||
```rust
|
||||
use maud::{html, Markup, Render};
|
||||
|
@ -27,9 +35,15 @@ impl Render for Css {
|
|||
|
||||
## Example: a wrapper that calls `std::fmt::Debug`
|
||||
|
||||
When debugging an application, it can be useful to see its internal state. But these internal data types often don't implement `Display`. This wrapper lets us use the [`Debug`][Debug] trait instead.
|
||||
When debugging an application,
|
||||
it can be useful to see its internal state.
|
||||
But these internal data types often don't implement `Display`.
|
||||
This wrapper lets us use the [`Debug`][Debug] trait instead.
|
||||
|
||||
To avoid extra allocation, we override the `.render_to()` method instead of `.render()`. This doesn't do any escaping by default, so we wrap the output in an `Escaper` as well.
|
||||
To avoid extra allocation,
|
||||
we override the `.render_to()` method instead of `.render()`.
|
||||
This doesn't do any escaping by default,
|
||||
so we wrap the output in an `Escaper` as well.
|
||||
|
||||
```rust
|
||||
use maud::{Escaper, html, Render};
|
||||
|
@ -49,9 +63,11 @@ impl<T: fmt::Debug> Render for Debug<T> {
|
|||
|
||||
## Example: rendering Markdown using `pulldown-cmark` and `ammonia`
|
||||
|
||||
[`pulldown-cmark`][pulldown-cmark] is a popular library for converting Markdown to HTML.
|
||||
[`pulldown-cmark`][pulldown-cmark] is a popular library
|
||||
for converting Markdown to HTML.
|
||||
|
||||
We also use the [`ammonia`][ammonia] library, which sanitizes the resulting markup.
|
||||
We also use the [`ammonia`][ammonia] library,
|
||||
which sanitizes the resulting markup.
|
||||
|
||||
```rust
|
||||
use ammonia;
|
||||
|
|
|
@ -2,7 +2,8 @@
|
|||
|
||||
## Splices: `(foo)`
|
||||
|
||||
Use `(foo)` syntax to insert the value of `foo` at runtime. Any HTML special characters are escaped by default.
|
||||
Use `(foo)` syntax to insert the value of `foo` at runtime.
|
||||
Any HTML special characters are escaped by default.
|
||||
|
||||
```rust
|
||||
let best_pony = "Pinkie Pie";
|
||||
|
@ -18,7 +19,9 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
Arbitrary Rust code can be included in a splice by using a [block](https://doc.rust-lang.org/reference.html#block-expressions). This can be helpful for complex expressions that would be difficult to read otherwise.
|
||||
Arbitrary Rust code can be included in a splice by using a [block].
|
||||
This can be helpful for complex expressions
|
||||
that would be difficult to read otherwise.
|
||||
|
||||
```rust
|
||||
# struct Foo;
|
||||
|
@ -41,6 +44,8 @@ html! {
|
|||
# }
|
||||
```
|
||||
|
||||
[block]: https://doc.rust-lang.org/reference.html#block-expressions
|
||||
|
||||
### Splices in attributes
|
||||
|
||||
Splices work in attributes as well.
|
||||
|
@ -56,7 +61,9 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
To concatenate multiple values within an attribute, wrap the whole thing in braces. This syntax is useful for building URLs.
|
||||
To concatenate multiple values within an attribute,
|
||||
wrap the whole thing in braces.
|
||||
This syntax is useful for building URLs.
|
||||
|
||||
```rust
|
||||
const GITHUB: &'static str = "https://github.com";
|
||||
|
@ -87,9 +94,16 @@ html! {
|
|||
|
||||
### What can be spliced?
|
||||
|
||||
You can splice any value that implements [`std::fmt::Display`][Display]. Most primitive types (such as `str` and `i32`) implement this trait, so they should work out of the box.
|
||||
You can splice any value that implements [`std::fmt::Display`][Display].
|
||||
Most primitive types (such as `str` and `i32`) implement this trait,
|
||||
so they should work out of the box.
|
||||
|
||||
To change this behavior for some type, you can implement the [`Render`][Render] trait by hand. The [`PreEscaped`][PreEscaped] wrapper type, which outputs its argument without escaping, works this way. See the [traits](render-trait.md) section for details.
|
||||
To change this behavior for some type,
|
||||
you can implement the [`Render`][Render] trait by hand.
|
||||
The [`PreEscaped`][PreEscaped] wrapper type,
|
||||
which outputs its argument without escaping,
|
||||
works this way.
|
||||
See the [traits](render-trait.md) section for details.
|
||||
|
||||
```rust
|
||||
use maud::PreEscaped;
|
||||
|
@ -108,7 +122,8 @@ html! {
|
|||
|
||||
## Toggles: `[foo]`
|
||||
|
||||
Use `[foo]` syntax to show or hide something based on a boolean expression `foo`.
|
||||
Use `[foo]` syntax to show or hide something
|
||||
based on a boolean expression `foo`.
|
||||
|
||||
This works on empty attributes:
|
||||
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
|
||||
## Text
|
||||
|
||||
Literal strings use the same syntax as Rust. Wrap them in double quotes, and use a backslash for escapes.
|
||||
Literal strings use the same syntax as Rust.
|
||||
Wrap them in double quotes,
|
||||
and use a backslash for escapes.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -14,7 +16,9 @@ html! {
|
|||
|
||||
## Raw strings
|
||||
|
||||
If the string is long, or contains many special characters, then it may be worth using [raw strings] instead:
|
||||
If the string is long,
|
||||
or contains many special characters,
|
||||
then it may be worth using [raw strings] instead:
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -37,7 +41,11 @@ html! {
|
|||
|
||||
## Escaping and `PreEscaped`
|
||||
|
||||
By default, HTML special characters are escaped automatically. Wrap the string in `(PreEscaped())` to disable this escaping. (See the section on [splices](splices-toggles.md) to learn more about how this works.)
|
||||
By default,
|
||||
HTML special characters are escaped automatically.
|
||||
Wrap the string in `(PreEscaped())` to disable this escaping.
|
||||
(See the section on [splices](splices-toggles.md) to
|
||||
learn more about how this works.)
|
||||
|
||||
```rust
|
||||
use maud::PreEscaped;
|
||||
|
@ -51,7 +59,9 @@ html! {
|
|||
|
||||
## The `DOCTYPE` constant
|
||||
|
||||
If you want to add a `<!DOCTYPE html>` declaration to your page, you may use the `maud::DOCTYPE` constant instead of writing it out by hand:
|
||||
If you want to add a `<!DOCTYPE html>` declaration to your page,
|
||||
you may use the `maud::DOCTYPE` constant
|
||||
instead of writing it out by hand:
|
||||
|
||||
```rust
|
||||
use maud::DOCTYPE;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
# Web framework integration
|
||||
|
||||
Maud includes support for these web frameworks: [Actix], [Iron], [Rocket], and [Rouille].
|
||||
Maud includes support for these web frameworks:
|
||||
[Actix], [Iron], [Rocket], and [Rouille].
|
||||
|
||||
[Actix]: https://actix.rs/
|
||||
[Iron]: http://ironframework.io
|
||||
|
@ -18,7 +19,8 @@ maud = { version = "*", features = ["actix-web"] }
|
|||
# ...
|
||||
```
|
||||
|
||||
Actix request handlers can use a `Markup` that implements the `actix_web::Responder` trait.
|
||||
Actix request handlers can use a `Markup`
|
||||
that implements the `actix_web::Responder` trait.
|
||||
|
||||
```rust,no_run
|
||||
use actix_web::{get, App, HttpServer, Result as AwResult};
|
||||
|
@ -56,7 +58,9 @@ maud = { version = "*", features = ["iron"] }
|
|||
# ...
|
||||
```
|
||||
|
||||
With this feature enabled, you can then build a `Response` from a `Markup` object directly. Here's an example application using Iron and Maud:
|
||||
With this feature enabled,
|
||||
you can then build a `Response` from a `Markup` object directly.
|
||||
Here's an example application using Iron and Maud:
|
||||
|
||||
```rust,no_run
|
||||
use iron::prelude::*;
|
||||
|
@ -76,11 +80,13 @@ fn main() {
|
|||
}
|
||||
```
|
||||
|
||||
`Markup` will set the content type of the response automatically, so you don't need to add it yourself.
|
||||
`Markup` will set the content type of the response automatically,
|
||||
so you don't need to add it yourself.
|
||||
|
||||
# Rocket
|
||||
|
||||
Rocket works in a similar way, except using the `rocket` feature:
|
||||
Rocket works in a similar way,
|
||||
except using the `rocket` feature:
|
||||
|
||||
```toml
|
||||
# ...
|
||||
|
@ -89,7 +95,8 @@ maud = { version = "*", features = ["rocket"] }
|
|||
# ...
|
||||
```
|
||||
|
||||
This adds a `Responder` implementation for the `Markup` type, so you can return the result directly:
|
||||
This adds a `Responder` implementation for the `Markup` type,
|
||||
so you can return the result directly:
|
||||
|
||||
```rust,no_run
|
||||
#![feature(decl_macro)]
|
||||
|
@ -113,7 +120,9 @@ fn main() {
|
|||
|
||||
# Rouille
|
||||
|
||||
Unlike with the other frameworks, Rouille doesn't need any extra features at all! Calling `Response::html` on the rendered `Markup` will Just Work®.
|
||||
Unlike with the other frameworks,
|
||||
Rouille doesn't need any extra features at all!
|
||||
Calling `Response::html` on the rendered `Markup` will Just Work®.
|
||||
|
||||
```rust,no_run
|
||||
use maud::html;
|
||||
|
|
Loading…
Add table
Reference in a new issue