Prune duplicate documentation

This commit is contained in:
Dirkjan Ochtman 2020-06-30 09:52:09 +02:00
parent 435bb0569c
commit 9f96214cbe
3 changed files with 7 additions and 493 deletions

View File

@ -8,7 +8,7 @@
Askama implements a template rendering engine based on Jinja.
It generates Rust code from your templates at compile time
based on a user-defined `struct` to hold the template's context.
See below for an example, or read [the documentation][docs].
See below for an example, or read [the book][docs].
**"I use Askama for actix's TechEmpower benchmarks."** --
[Nikolay Kim][fafhrd91], creator of actix-web
@ -46,11 +46,7 @@ in a for-profit context, please consider supporting my open source work on
* Opt-out HTML escaping
* Syntax customization
### Limitations
* A limited number of built-in filters have been implemented
[docs]: https://docs.rs/askama
[docs]: https://djc.github.io/askama/
[fafhrd91]: https://github.com/fafhrd91
[mitsuhiko]: http://lucumr.pocoo.org/
[issues]: https://github.com/djc/askama/issues
@ -102,55 +98,3 @@ You should now be able to compile and run this code.
Review the [test cases] for more examples.
[test cases]: https://github.com/djc/askama/tree/master/testing
Debugging and troubleshooting
-----------------------------
You can view the parse tree for a template as well as the generated code by
changing the `template` attribute item list for the template struct:
```rust
#[derive(Template)]
#[template(path = "hello.html", print = "all")]
struct HelloTemplate<'a> { ... }
```
The `print` key can take one of four values:
* `none` (the default value)
* `ast` (print the parse tree)
* `code` (print the generated code)
* `all` (print both parse tree and code)
The resulting output will be printed to `stderr` during the compilation process.
The parse tree looks like this for the example template:
```
[Lit("", "Hello,", " "), Expr(WS(false, false), Var("name")),
Lit("", "!", "\n")]
```
The generated code looks like this:
```rust
impl < 'a > ::askama::Template for HelloTemplate< 'a > {
fn render_into(&self, writer: &mut ::std::fmt::Write) -> ::askama::Result<()> {
write!(
writer,
"Hello, {expr0}!",
expr0 = &::askama::MarkupDisplay::from(&self.name),
)?;
Ok(())
}
fn extension() -> Option<&'static str> {
Some("html")
}
}
impl < 'a > ::std::fmt::Display for HelloTemplate< 'a > {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
::askama::Template::render_into(self, f).map_err(|_| ::std::fmt::Error {})
}
}
```

View File

@ -7,6 +7,9 @@
//! For feature highlights and a quick start, please review the
//! [README](https://github.com/djc/askama/blob/master/README.md).
//!
//! The primary documentation for this crate now lives in
//! [the book](https://djc.github.io/askama/).
//!
//! # Creating Askama templates
//!
//! An Askama template is a `struct` definition which provides the template
@ -55,439 +58,6 @@
//! * `syntax` (as `syntax = "foo"`): set the syntax name for a parser defined
//! in the configuration file. The default syntax , "default", is the one
//! provided by Askama.
//!
//! ## Configuration
//!
//! At compile time, Askama will read optional configuration values from
//! `askama.toml` in the crate root (the directory where `Cargo.toml` can
//! be found). Currently, this covers the directories to search for templates,
//! custom syntax configuration and escaper configuration.
//!
//! This example file demonstrates the default configuration:
//!
//! ```toml
//! [general]
//! # Directories to search for templates, relative to the crate root.
//! dirs = ["templates"]
//! ```
//!
//! Here is an example that defines two custom syntaxes:
//!
//! ```toml
//! [general]
//! default_syntax = "foo"
//!
//! [[syntax]]
//! name = "foo"
//! block_start = "%{"
//! comment_start = "#{"
//! expr_end = "^^"
//!
//! [[syntax]]
//! name = "bar"
//! block_start = "%%"
//! block_end = "%%"
//! comment_start = "%#"
//! expr_start = "%{"
//! ```
//!
//! A syntax block consists of at least the attribute `name` which uniquely
//! names this syntax in the project.
//!
//! The following keys can currently be used to customize template syntax:
//!
//! * `block_start`, defaults to `{%`
//! * `block_end`, defaults to `%}`
//! * `comment_start`, defaults to `{#`
//! * `comment_end`, defaults to `#}`
//! * `expr_start`, defaults to `{{`
//! * `expr_end`, defaults to `}}`
//!
//! Values must be 2 characters long and start delimiters must all start with the same
//! character. If a key is omitted, the value from the default syntax is used.
//!
//! Here is an example of a custom escaper:
//!
//! ```toml
//! [[escaper]]
//! path = "::tex_escape::Tex"
//! extensions = ["tex"]
//! ```
//!
//! An escaper block consists of the attributes `path` and `name`. `path`
//! contains a Rust identifier that must be in scope for templates using this
//! escaper. `extensions` defines a list of file extensions that will trigger
//! the use of that escaper. Extensions are matched in order, starting with the
//! first escaper configured and ending with the default escapers for HTML
//! (extensions `html`, `htm`, `xml`, `j2`, `jinja`, `jinja2`) and plain text
//! (no escaping; `md`, `yml`, `none`, `txt`, and the empty string). Note that
//! this means you can also define other escapers that match different extensions
//! to the same escaper.
//!
//! ## Variables
//!
//! Top-level template variables are defined by the template's context type.
//! You can use a dot (`.`) to access variable's attributes or methods.
//! Reading from variables is subject to the usual borrowing policies.
//! For example, `{{ name }}` will get the ``name`` field from the template
//! context,
//! while `{{ user.name }}` will get the ``name`` field of the ``user``
//! field from the template context.
//!
//! ## Assignments
//!
//! Inside code blocks, you can also declare variables or assign values
//! to variables.
//! Assignments can't be imported by other templates.
//!
//! Assignments use the let tag:
//!
//! ```text
//! {% let name = user.name %}
//! {% let len = name.len() %}
//!
//! {% let val -%}
//! {% if len == 0 -%}
//! {% let val = "foo" -%}
//! {% else -%}
//! {% let val = name -%}
//! {% endif -%}
//! {{ val }}
//! ```
//!
//! ## Filters
//!
//! Values such as those obtained from variables can be post-processed
//! using **filters**.
//! Filters are applied to values using the pipe symbol (`|`) and may
//! have optional extra arguments in parentheses.
//! Filters can be chained, in which case the output from one filter
//! is passed to the next.
//!
//! For example, `{{ "{:?}"|format(name|escape) }}` will escape HTML
//! characters from the value obtained by accessing the `name` field,
//! and print the resulting string as a Rust literal.
//!
//! The built-in filters are documented as part of the
//! [filters module documentation](filters/index.html).
//!
//! To define your own filters, simply have a module named `filters` in
//! scope of the context deriving a `Template` `impl`. Note that in case of
//! name collision, the built in filters take precedence.
//!
//! ## Whitespace control
//!
//! Askama considers all tabs, spaces, newlines and carriage returns to be
//! whitespace. By default, it preserves all whitespace in template code,
//! except that a single trailing newline character is suppressed.
//! However, whitespace before and after expression and block delimiters
//! can be suppressed by writing a minus sign directly following a
//! start delimiter or leading into an end delimiter.
//!
//! Here is an example:
//!
//! ```text
//! {% if foo %}
//! {{- bar -}}
//! {% else if -%}
//! nothing
//! {%- endif %}
//! ```
//!
//! This discards all whitespace inside the if/else block. If a literal
//! (any part of the template not surrounded by `{% %}` or `{{ }}`)
//! includes only whitespace, whitespace suppression on either side will
//! completely suppress that literal content.
//!
//! ## Template inheritance
//!
//! Template inheritance allows you to build a base template with common
//! elements that can be shared by all inheriting templates.
//! A base template defines **blocks** that child templates can override.
//!
//! ### Base template
//!
//! ```text
//! <!DOCTYPE html>
//! <html lang="en">
//! <head>
//! <title>{% block title %}{{ title }} - My Site{% endblock %}</title>
//! {% block head %}{% endblock %}
//! </head>
//! <body>
//! <div id="content">
//! {% block content %}{% endblock %}
//! </div>
//! </body>
//! </html>
//! ```
//!
//! The `block` tags define three blocks that can be filled in by child
//! templates. The base template defines a default version of the block.
//! A base template must define one or more blocks in order to enable
//! inheritance. Blocks can only be specified at the top level of a template
//! or inside other blocks, not inside `if`/`else` branches or in `for`-loop
//! bodies.
//!
//! ### Child template
//!
//! Here's an example child template:
//!
//! ```text
//! {% extends "base.html" %}
//!
//! {% block title %}Index{% endblock %}
//!
//! {% block head %}
//! <style>
//! </style>
//! {% endblock %}
//!
//! {% block content %}
//! <h1>Index</h1>
//! <p>Hello, world!</p>
//! {% endblock %}
//! ```
//!
//! The `extends` tag tells the code generator that this template inherits
//! from another template. It will search for the base template relative to
//! itself before looking relative to the template base directory. It will
//! render the top-level content from the base template, and substitute
//! blocks from the base template with those from the child template. Inside
//! a block in a child template, the `super()` macro can be called to render
//! the parent block's contents.
//!
//! ## HTML escaping
//!
//! Askama by default escapes variables if it thinks it is rendering HTML
//! content. It infers the escaping context from the extension of template
//! filenames, escaping by default if the extension is one of `html`, `htm`,
//! or `xml`. When specifying a template as `source` in an attribute, the
//! `ext` attribute parameter must be used to specify a type. Additionally,
//! you can specify an escape mode explicitly for your template by setting
//! the `escape` attribute parameter value (to `none` or `html`).
//!
//! Askama escapes `<`, `>`, `&`, `"`, `'`, `\` and `/`, according to the
//! [OWASP escaping recommendations][owasp]. Use the `safe` filter to
//! prevent escaping for a single expression, or the `escape` (or `e`)
//! filter to escape a single expression in an unescaped context.
//!
//! [owasp]: https://www.owasp.org/index.php/XSS_(Cross_Site_Scripting)_Prevention_Cheat_Sheet#RULE_.231_-_HTML_Escape_Before_Inserting_Untrusted_Data_into_HTML_Element_Content
//!
//! ## Control structures
//!
//! ### For
//!
//! Loop over each item in an iterator. For example:
//!
//! ```text
//! <h1>Users</h1>
//! <ul>
//! {% for user in users %}
//! <li>{{ user.name|e }}</li>
//! {% endfor %}
//! </ul>
//! ```
//!
//! Inside for-loop blocks, some useful variables are accessible:
//!
//! * *loop.index*: current loop iteration (starting from 1)
//! * *loop.index0*: current loop iteration (starting from 0)
//! * *loop.first*: whether this is the first iteration of the loop
//! * *loop.last*: whether this is the last iteration of the loop
//!
//! ### If
//!
//! The *if* statement is used as you might expect:
//!
//! ```text
//! {% if users.len() == 0 %}
//! No users
//! {% else if users.len() == 1 %}
//! 1 user
//! {% else %}
//! {{ users.len() }} users
//! {% endif %}
//! ```
//!
//! ### Match
//!
//! In order to deal with Rust `enum`s in a type-safe way, templates support
//! match blocks from version 0.6. Here is a simple example showing how to
//! expand an `Option`:
//!
//! ```text
//! {% match item %}
//! {% when Some with ("foo") %}
//! Found literal foo
//! {% when Some with (val) %}
//! Found {{ val }}
//! {% when None %}
//! {% endmatch %}
//! ```
//!
//! That is, a `match` block can optionally contain some whitespace (but
//! no other literal content), followed by a number of `when` blocks
//! and an optional `else` block. Each `when` block must name a list of
//! matches (`(val)`), optionally introduced with a variant name. The
//! `else` block is equivalent to matching on `_` (matching anything).
//!
//! Struct-like enum variants are supported from version 0.8, with the list
//! of matches surrounded by curly braces instead (`{ field }`). New names
//! for the fields can be specified after a colon in the list of matches
//! (`{ field: val }`).
//!
//! ### Include
//!
//! The *include* statement lets you split large or repetitive blocks into
//! separate template files. Included templates get full access to the context
//! in which they're used, including local variables like those from loops:
//!
//! ```text
//! {% for i in iter %}
//! {% include "item.html" %}
//! {% endfor %}
//! ```
//!
//! ```text
//! * Item: {{ i }}
//! ```
//!
//! The path to include must be a string literal, so that it is known at
//! compile time. Askama will try to find the specified template relative
//! to the including template's path before falling back to the absolute
//! template path. Use `include` within the branches of an `if`/`else`
//! block to use includes more dynamically.
//!
//! ## Expressions
//!
//! Askama supports string literals (`"foo"`) and integer literals (`1`).
//! It supports almost all binary operators that Rust supports,
//! including arithmetic, comparison and logic operators.
//! The parser applies the same precedence order as the Rust compiler.
//! Expressions can be grouped using parentheses.
//! The HTML special characters `&`, `<` and `>` will be replaced with their
//! character entities unless the `escape` mode is disabled for a template.
//! Methods can be called on variables that are in scope, including `self`.
//!
//! **Warning**: if the result of an expression (a `{{ }}` block) is
//! equivalent to `self`, this can result in a stack overflow from infinite
//! recursion. This is because the `Display` implementation for that expression
//! will in turn evaluate the expression and yield `self` again.
//!
//! ## Templates in templates
//!
//! Using expressions, it is possible to delegate rendering part of a template to another template.
//! This makes it possible to inject modular template sections into other templates and facilitates
//! testing and reuse.
//!
//! ```rust
//! use askama::Template;
//! #[derive(Template)]
//! #[template(source = "Section 1: {{ s1.render().unwrap() }}", ext = "txt")]
//! struct RenderInPlace<'a> {
//! s1: SectionOne<'a>
//! }
//!
//! #[derive(Template)]
//! #[template(source = "A={{ a }}\nB={{ b }}", ext = "txt")]
//! struct SectionOne<'a> {
//! a: &'a str,
//! b: &'a str,
//! }
//! let t = RenderInPlace { s1: SectionOne { a: "a", b: "b" } };
//! assert_eq!(t.render().unwrap(), "Section 1: A=a\nB=b")
//! ```
//!
//! See the example
//! [render in place](https://github.com/djc/askama/blob/master/testing/tests/render_in_place.rs)
//! using a vector of templates in a for block.
//!
//! ## Comments
//!
//! Askama supports block comments delimited by `{#` and `#}`.
//!
//!
//! ## Recursive Structures
//!
//! Recursive implementations should preferably use a custom iterator and
//! use a plain loop. If that is not doable, call `.render()`
//! directly by using an expression as shown below.
//! Including self does not work, see #105 and #220 .
//!
//! ```rust
//! use askama::Template;
//!
//! #[derive(Template)]
//! #[template(source = r#"
//! //! {% for item in children %}
//! {{ item.render().unwrap() }}
//! {% endfor %}
//! "#, ext = "html", escape = "none")]
//! struct Item<'a> {
//! name: &'a str,
//! children: &'a [Item<'a>],
//! }
//! ```
//!
//! # Optional functionality
//!
//! ## Rocket integration
//!
//! Enabling the `with-rocket` feature appends an implementation of Rocket's
//! `Responder` trait for each template type. This makes it easy to trivially
//! return a value of that type in a Rocket handler. See
//! [the example](https://github.com/djc/askama/blob/master/askama_rocket/tests/basic.rs)
//! from the Askama test suite for more on how to integrate.
//!
//! In case a run-time error occurs during templating, a `500 Internal Server
//! Error` `Status` value will be returned, so that this can be further
//! handled by your error catcher.
//!
//! ## Iron integration
//!
//! Enabling the `with-iron` feature appends an implementation of Iron's
//! `Modifier<Response>` trait for each template type. This makes it easy to
//! trivially return a value of that type in an Iron handler. See
//! [the example](https://github.com/djc/askama/blob/master/askama_iron/tests/basic.rs)
//! from the Askama test suite for more on how to integrate.
//!
//! Note that Askama's generated `Modifier<Response>` implementation currently
//! unwraps any run-time errors from the template. If you have a better
//! suggestion, please [file an issue](https://github.com/djc/askama/issues/new).
//!
//! ## Actix-web integration
//!
//! Enabling the `with-actix-web` feature appends an implementation of Actix-web's
//! `Responder` trait for each template type. This makes it easy to trivially return
//! a value of that type in an Actix-web handler. See
//! [the example](https://github.com/djc/askama/blob/master/askama_actix/tests/basic.rs)
//! from the Askama test suite for more on how to integrate.
//!
//! ## Gotham integration
//!
//! Enabling the `with-gotham` feature appends an implementation of Gotham's
//! `IntoResponse` trait for each template type. This makes it easy to trivially
//! return a value of that type in a Gotham handler. See
//! [the example](https://github.com/djc/askama/blob/master/askama_gotham/tests/basic.rs)
//! from the Askama test suite for more on how to integrate.
//!
//! In case of a run-time error occurring during templating, the response will be of the same
//! signature, with a status code of `500 Internal Server Error`, mime `*/*`, and an empty `Body`.
//! This preserves the response chain if any custom error handling needs to occur.
//!
//! ## Warp integration
//!
//! Enabling the `with-warp` feature appends an implementation of Warp's `Reply`
//! trait for each template type. This makes it simple to return a template from
//! a Warp filter. See [the example](https://github.com/djc/askama/blob/master/askama_warp/tests/warp.rs)
//! from the Askama test suite for more on how to integrate.
//!
//! ## The `json` filter
//!
//! Enabling the `serde-json` filter will enable the use of the `json` filter.
//! This will output formatted JSON for any value that implements the required
//! `Serialize` trait.
#![allow(unused_imports)]
#[macro_use]

View File

@ -8,7 +8,7 @@
Askama implements a template rendering engine based on Jinja.
It generates Rust code from your templates at compile time
based on a user-defined `struct` to hold the template's context.
See below for an example, or read [the documentation][docs].
See below for an example, or read [the book][docs].
**"I use Askama for actix's TechEmpower benchmarks."** --
[Nikolay Kim][fafhrd91], creator of actix-web
@ -46,7 +46,7 @@ in a for-profit context, please consider supporting my open source work on
* Opt-out HTML escaping
* Syntax customization
[docs]: https://docs.rs/askama
[docs]: https://djc.github.io/askama/
[fafhrd91]: https://github.com/fafhrd91
[mitsuhiko]: http://lucumr.pocoo.org/
[issues]: https://github.com/djc/askama/issues