Switch documentation to one-sentence-per-line (#368)
This commit is contained in:
parent
daa43549ee
commit
4f14db7415
10 changed files with 64 additions and 149 deletions
|
@ -1,14 +1,11 @@
|
|||
# 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.
|
||||
As with Rust, braces are mandatory and the `@else` clause is optional.
|
||||
|
||||
```rust
|
||||
#[derive(PartialEq)]
|
||||
|
|
|
@ -37,8 +37,7 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
The result will be rendered with HTML syntax –
|
||||
`<br>` not `<br />`.
|
||||
The result will be rendered with HTML syntax – `<br>` not `<br />`.
|
||||
|
||||
## Custom elements and `data` attributes
|
||||
|
||||
|
@ -62,11 +61,9 @@ html! {
|
|||
|
||||
## Non-empty attributes: `title="yay"`
|
||||
|
||||
Add attributes using the syntax:
|
||||
`attr="value"`.
|
||||
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.
|
||||
The values must be quoted: they are parsed as string literals.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -89,10 +86,8 @@ html! {
|
|||
|
||||
## Optional attributes: `title=[Some("value")]`
|
||||
|
||||
Add optional attributes to an element using `attr=[value]` syntax,
|
||||
with *square* brackets.
|
||||
These are only rendered if the value is `Some<T>`,
|
||||
and entirely omitted if the value is `None`.
|
||||
Add optional attributes to an element using `attr=[value]` syntax, with *square* brackets.
|
||||
These are only rendered if the value is `Some<T>`, and entirely omitted if the value is `None`.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -124,20 +119,15 @@ 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::
|
||||
|
@ -147,9 +137,7 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
In Rust 2021,
|
||||
the `#` symbol must be preceded by a space,
|
||||
to avoid conflicts with [reserved syntax]:
|
||||
In Rust 2021, the `#` symbol must be preceded by a space, to avoid conflicts with [reserved syntax]:
|
||||
|
||||
[reserved syntax]: https://doc.rust-lang.org/edition-guide/rust-2021/reserving-syntax.html
|
||||
|
||||
|
@ -166,8 +154,7 @@ html! {
|
|||
```
|
||||
|
||||
The classes and IDs can be quoted.
|
||||
This is useful for names with numbers or symbols
|
||||
which otherwise wouldn't parse:
|
||||
This is useful for names with numbers or symbols which otherwise wouldn't parse:
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -179,9 +166,7 @@ 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::
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
## What is the origin of the name "Maud"?
|
||||
|
||||
Maud is named after a [character] from *My Little Pony: Friendship is Magic*.
|
||||
It does not refer to the [poem] by Alfred Tennyson,
|
||||
though other people have brought that up in the past.
|
||||
It does not refer to the [poem] by Alfred Tennyson, though other people have brought that up in the past.
|
||||
|
||||
Here are some reasons why I chose this name:
|
||||
|
||||
|
@ -12,8 +11,7 @@ Here are some reasons why I chose this name:
|
|||
|
||||
* The library is efficient and austere, like the character;
|
||||
|
||||
* Google used to maintain a site called ["HTML5 Rocks"],
|
||||
and Maud (the character) is a geologist.
|
||||
* Google used to maintain a site called ["HTML5 Rocks"], and Maud (the character) is a geologist.
|
||||
|
||||
[character]: http://mlp.wikia.com/wiki/Maud_Pie
|
||||
[poem]: https://en.wikipedia.org/wiki/Maud_and_other_poems
|
||||
|
@ -24,49 +22,32 @@ Here are some reasons why I chose this name:
|
|||
Good question! In fact, Maud did work this way in the past.
|
||||
|
||||
But it's hard to support buffer reuse in an ergonomic way.
|
||||
The approaches I tried
|
||||
either involved too much boilerplate,
|
||||
or caused mysterious lifetime issues,
|
||||
or both.
|
||||
The approaches I tried either involved too much boilerplate, or caused mysterious lifetime issues, or both.
|
||||
Moreover, Maud's allocation pattern—with small, short-lived buffers—follow the fast path in modern allocators.
|
||||
These reasons are why I changed `html!` to return a `String` in version 0.11.
|
||||
|
||||
That said,
|
||||
Rust has changed a lot since then,
|
||||
and some of those old assumptions
|
||||
might no longer hold today.
|
||||
So this decision could be revisited
|
||||
prior to the 1.0 release.
|
||||
That said, Rust has changed a lot since then, and some of those old assumptions might no longer hold today.
|
||||
So this decision could be revisited prior to the 1.0 release.
|
||||
|
||||
## Why is Maud written as a procedural macro? Can't it use `macro_rules!` instead?
|
||||
|
||||
This is certainly possible, and indeed the [Horrorshow] library works this way.
|
||||
|
||||
I use procedural macros because they are more flexible.
|
||||
There are some syntax constructs in Maud that are hard to parse with `macro_rules!`;
|
||||
better diagnostics are a bonus as well.
|
||||
There are some syntax constructs in Maud that are hard to parse with `macro_rules!`; better diagnostics are a bonus as well.
|
||||
|
||||
[Horrorshow]: https://github.com/Stebalien/horrorshow-rs
|
||||
|
||||
## Maud has had a lot of releases so far. When will it reach 1.0?
|
||||
|
||||
I originally planned to cut a 1.0
|
||||
after implementing stable support.
|
||||
But now that's happened,
|
||||
I've realized that there are a couple design questions
|
||||
that I'd like to resolve
|
||||
before marking that milestone.
|
||||
I originally planned to cut a 1.0 after implementing stable support.
|
||||
But now that's happened, I've realized that there are a couple design questions that I'd like to resolve before marking that milestone.
|
||||
Expect a blog post on this topic Very Soon®.
|
||||
|
||||
## Why doesn't Maud implement [context-aware escaping]?
|
||||
|
||||
I agree that context-aware escaping is very important,
|
||||
especially for the kind of small-scale development
|
||||
that Maud is used for.
|
||||
But it's a complex feature,
|
||||
with security implications,
|
||||
so I want to take the time
|
||||
to get it right.
|
||||
I agree that context-aware escaping is very important, especially for the kind of small-scale development that Maud is used for.
|
||||
But it's a complex feature, with security implications, so I want to take the time to get it right.
|
||||
|
||||
Please follow [#181] for the latest developments!
|
||||
|
||||
|
|
|
@ -2,8 +2,7 @@
|
|||
|
||||
## Add Maud to your project
|
||||
|
||||
Once Rust is set up,
|
||||
create a new project with Cargo:
|
||||
Once Rust is set up, create a new project with Cargo:
|
||||
|
||||
```sh
|
||||
cargo new --bin pony-greeter
|
||||
|
@ -31,15 +30,12 @@ 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>
|
||||
|
@ -49,13 +45,7 @@ Congrats – you've written your first Maud program!
|
|||
|
||||
## Which version of Rust?
|
||||
|
||||
While Maud works well
|
||||
on both stable and [nightly] versions
|
||||
of Rust,
|
||||
the error messages are slightly better
|
||||
on nightly.
|
||||
For this reason,
|
||||
it is recommended to develop using nightly Rust,
|
||||
but test and deploy using stable.
|
||||
While Maud works well on both stable and [nightly] versions of Rust, the error messages are slightly better on nightly.
|
||||
For this reason, it is recommended to develop using nightly Rust, but test and deploy using stable.
|
||||
|
||||
[nightly]: https://doc.rust-lang.org/book/appendix-07-nightly-rust.html
|
||||
|
|
|
@ -16,40 +16,30 @@ 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
|
||||
fast, type-safe, and easy to deploy.
|
||||
It's implemented as a macro, `html!`, which compiles your markup to specialized Rust code.
|
||||
This unique approach makes Maud templates fast, 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.
|
||||
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.
|
||||
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,8 +1,7 @@
|
|||
# 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`.
|
||||
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`.
|
||||
|
|
|
@ -8,8 +8,7 @@ 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.
|
||||
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
|
||||
|
@ -29,15 +28,12 @@ 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.
|
||||
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};
|
||||
|
@ -57,11 +53,9 @@ 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;
|
||||
|
|
|
@ -20,8 +20,7 @@ html! {
|
|||
```
|
||||
|
||||
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.
|
||||
This can be helpful for complex expressions that would be difficult to read otherwise.
|
||||
|
||||
```rust
|
||||
# struct Foo;
|
||||
|
@ -61,8 +60,7 @@ html! {
|
|||
# ;
|
||||
```
|
||||
|
||||
To concatenate multiple values within an attribute,
|
||||
wrap the whole thing in braces.
|
||||
To concatenate multiple values within an attribute, wrap the whole thing in braces.
|
||||
This syntax is useful for building URLs.
|
||||
|
||||
```rust
|
||||
|
@ -95,14 +93,10 @@ html! {
|
|||
### What can be spliced?
|
||||
|
||||
You can splice any value that implements [`Render`][Render].
|
||||
Most primitive types (such as `str` and `i32`) implement this trait,
|
||||
so they should work out of the box.
|
||||
Most primitive types (such as `str` and `i32`) implement this trait, so they should work out of the box.
|
||||
|
||||
To get this behavior for a custom type,
|
||||
you can implement the [`Render`][Render] trait by hand.
|
||||
The [`PreEscaped`][PreEscaped] wrapper type,
|
||||
which outputs its argument without escaping,
|
||||
works this way.
|
||||
To get this behavior for a custom 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
|
||||
|
@ -121,8 +115,7 @@ 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:
|
||||
|
||||
|
|
|
@ -3,8 +3,7 @@
|
|||
## Text
|
||||
|
||||
Literal strings use the same syntax as Rust.
|
||||
Wrap them in double quotes,
|
||||
and use a backslash for escapes.
|
||||
Wrap them in double quotes, and use a backslash for escapes.
|
||||
|
||||
```rust
|
||||
# let _ = maud::
|
||||
|
@ -16,9 +15,7 @@ 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::
|
||||
|
@ -41,11 +38,9 @@ html! {
|
|||
|
||||
## Escaping and `PreEscaped`
|
||||
|
||||
By default,
|
||||
HTML special characters are escaped automatically.
|
||||
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.)
|
||||
(See the section on [splices](splices-toggles.md) to learn more about how this works.)
|
||||
|
||||
```rust
|
||||
use maud::PreEscaped;
|
||||
|
@ -59,9 +54,7 @@ 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,7 +1,6 @@
|
|||
# Web framework integration
|
||||
|
||||
Maud includes support for these web frameworks:
|
||||
[Actix], [Rocket], [Rouille], and [Tide].
|
||||
Maud includes support for these web frameworks: [Actix], [Rocket], [Rouille], and [Tide].
|
||||
|
||||
[Actix]: https://actix.rs/
|
||||
[Rocket]: https://rocket.rs/
|
||||
|
@ -19,8 +18,7 @@ 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};
|
||||
|
@ -49,8 +47,7 @@ async fn main() -> io::Result<()> {
|
|||
|
||||
# Rocket
|
||||
|
||||
Rocket works in a similar way,
|
||||
except using the `rocket` feature:
|
||||
Rocket works in a similar way, except using the `rocket` feature:
|
||||
|
||||
```toml
|
||||
# ...
|
||||
|
@ -59,8 +56,7 @@ 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)]
|
||||
|
@ -84,8 +80,7 @@ fn main() {
|
|||
|
||||
# Rouille
|
||||
|
||||
Unlike with the other frameworks,
|
||||
Rouille doesn't need any extra features at all!
|
||||
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
|
||||
|
@ -118,10 +113,8 @@ maud = { version = "*", features = ["tide"] }
|
|||
# ...
|
||||
```
|
||||
|
||||
This adds an implementation of `From<PreEscaped<String>>`
|
||||
for the `Response` struct.
|
||||
Once provided,
|
||||
callers may return results of `html!` directly as responses:
|
||||
This adds an implementation of `From<PreEscaped<String>>` for the `Response` struct.
|
||||
Once provided, callers may return results of `html!` directly as responses:
|
||||
|
||||
```rust,no_run
|
||||
use maud::html;
|
||||
|
|
Loading…
Add table
Reference in a new issue