Type-safe, compiled Jinja-like templates for Rust

Overview

Askama

Documentation Latest version Build Status Chat

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 book.

"Pretty exciting. I would love to use this already." -- Armin Ronacher, creator of Jinja

All feedback welcome. Feel free to file bugs, requests for documentation and any other feedback to the issue tracker or tweet me.

Askama was created by and is maintained by Dirkjan Ochtman. If you are in a position to support ongoing maintenance and further development or use it in a for-profit context, please consider supporting my open source work on Patreon.

Feature highlights

  • Construct templates using a familiar, easy-to-use syntax
  • Benefit from the safety provided by Rust's type system
  • Template code is compiled into your crate for optimal performance
  • Optional built-in support for Actix, Gotham, Iron, Rocket, tide, and warp web frameworks
  • Debugging features to assist you in template development
  • Templates must be valid UTF-8 and produce UTF-8 when rendered
  • Works on stable Rust

Supported in templates

  • Template inheritance
  • Loops, if/else statements and include support
  • Macro support
  • Variables (no mutability allowed)
  • Some built-in filters, and the ability to use your own
  • Whitespace suppressing with '-' markers
  • Opt-out HTML escaping
  • Syntax customization

How to get started

First, add the following to your crate's Cargo.toml:

# in section [dependencies]
askama = "0.8"

Now create a directory called templates in your crate root. In it, create a file called hello.html, containing the following:

Hello, {{ name }}!

In any Rust file inside your crate, add the following:

use askama::Template; // bring trait in scope

#[derive(Template)] // this will generate the code...
#[template(path = "hello.html")] // using the template in this path, relative
                                 // to the `templates` dir in the crate root
struct HelloTemplate<'a> { // the name of the struct can be anything
    name: &'a str, // the field name should match the variable name
                   // in your template
}

fn main() {
    let hello = HelloTemplate { name: "world" }; // instantiate your struct
    println!("{}", hello.render().unwrap()); // then render it.
}

You should now be able to compile and run this code.

Review the test cases for more examples.

Comments
  • Fluent integration

    Fluent integration

    Starting the work discussed in #202, not functional in any way yet.

    My current implementation will end up baking the compiled templates into result executables to keep deployment simple, although I think I'll also add in the ability to reload translation files at runtime somehow.

    opened by kazimuth 33
  • askama_axum doesn't seem to work? Trait not satisfied error

    askama_axum doesn't seem to work? Trait not satisfied error

    Hi, One more problem I am facing trying to use askama_axum in the main branch. The Derive macro seem to have a problem adding into_response? I get this error:

    error[E0277]: the trait bound HelloTemplate: askama_axum::Template is not satisfied --> zata-web-app-ssr\src\bin\main.rs:107:10 | 107 | #[derive(Template)] | ^^^^^^^^ the trait askama_axum::Template is not implemented for HelloTemplate

    11 | pub fn into_response<T: Template>(t: &T, ext: &str) -> Response { | ^^^^^^^^ required by this bound in askama_axum::into_response

    Epurated version of my code

    use askama::Template;
    use axum::{
        extract,
        http::StatusCode,
        response::IntoResponse,
        routing::{get, get_service, post},
        AddExtensionLayer, Router,
    };
    
    #[tokio::main]
    async fn main() {
        dotenv().ok();
        let database_url = env::var("DATABASE_URL").expect("DATABASE_URL is not set in .env file");
        let db_pool = PgPool::connect(&database_url).await.unwrap();
       // Set the RUST_LOG, if it hasn't been explicitly defined
        if std::env::var_os("RUST_LOG").is_none() {
            std::env::set_var("RUST_LOG", "zata_web_app=debug")
        }
        tracing_subscriber::fmt::init();
    
        let shared_state = Arc::new(AppState { db: db_pool });
    
        // build our application with some routes
        let app = Router::new()
            .route("/greet/:name", get(greet))       
            .nest(
                "/static",
                get_service(ServeDir::new(concat!(
                    env!("CARGO_MANIFEST_DIR"),
                    "/static"
                )))
            .handle_error(|error: std::io::Error| async move {
                    (
                        StatusCode::INTERNAL_SERVER_ERROR,
                        format!("Unhandled internal error: {}", error),
                    )
                }),
            )
            .layer(AddExtensionLayer::new(shared_state));
    
        // run it
        let addr = SocketAddr::from(([127, 0, 0, 1], 8080));
        tracing::debug!("listening on {}", addr);
        axum::Server::bind(&addr)
            .serve(app.into_make_service())
            .await
            .unwrap();
    }
    
    
    async fn greet(extract::Path(name): extract::Path<String>) -> impl IntoResponse {
        let template = HelloTemplate { name };
        HtmlTemplate(template)
    }
    
    #[derive(Template)]
    #[template(path = "list.html")]
    struct ListTutors {
        tutors: Vec<Tutor>,
    }
    
    #[derive(Template)]
    #[template(path = "index.html")]
    struct HelloTemplate {
        name: String,
    }
    
    
    

    I also tried to do a standalone version of the example in the repo and got the same error.

    opened by SylvainMartel 21
  • Add suppress_whitespace config option and add `config` parameter to the derive macro

    Add suppress_whitespace config option and add `config` parameter to the derive macro

    I recently disovered in jinja (with Flask in python) that we could enable automatic_block_trim, allowing us to remove all the - and also preventing us to forget them. I saw it was missing in this crate so I thought it'd be a good addition.

    So now, about the newly added config parameter in the derive macro: I realized when writing the tests that I couldn't have a specific configuration for a given test, making it quite complex. So the easiest solution was to create this new parameter. If you prefer, I can open a separate PR for it (its implementation is in the second commit). Of course, it's only if both features make sense to you.

    Finally: I didn't find out where to put the documentation for config. Do you have a suggestion?

    In any case: thanks a lot for writing this crate! It's really nice to use.

    opened by GuillaumeGomez 19
  • Trim all but 1 whitespace jinja condition

    Trim all but 1 whitespace jinja condition

    @vallentin suggested here that we could extend the "trim_all_whitespace" feature to be able to trim all whitespace characters but one.

    So currently, we have:

    <div>    {%- if foo -%} blabla {%- endif -%} </div>
    

    Which will remove all whitespace characters before and after (by using -) and we have:

    <div>    {%+ if foo +%} blabla {%+ endif +%} </div>
    

    Which means that the whitespace should be saved (only useful when the "trim all whitespace" feature is enabled).

    The idea would now to add a new character to strip all whitespace characters but one. I propose ~:

    <div>    {%~ if foo %} blabla {% endif %} </div>
    
    opened by GuillaumeGomez 17
  • Use include_bytes macro to avoid the need for a build script

    Use include_bytes macro to avoid the need for a build script

    This PR adds an otherwise unused include_bytes!(...); statement in the generated template code for each template in the context map and for each included template. This allows the compiler to detect file level dependencies without the need for a custom build script.

    I believe I caught all the relevant file dependencies: extends, imports, includes and of course the template itself (if it is backed by a file, which requires some checks).

    This gives more granular file-level dependency information than the build script, although I don't believe that actually gives any practical benefits right now.

    Feedback welcome.

    opened by de-vri-es 17
  • Cannot move out of borrowed content in for loop

    Cannot move out of borrowed content in for loop

    Hi there,

    I am probably not posting this in the right place but I seek help using this library. I am trying to iterate over a list of x509Name's using the following code in my template :

    {% for entry in certificate.subject_name().entries() %}
    
    {% endfor %}
    

    certificate being an instance of X509. I have the following error : cannot move out of borrowed content. I am pretty new to rust, this must be something easy but I have not yet full comprehension of the concept of ownership..

    opened by iammichiel 17
  • Reworked implicit borrowing to be more relaxed

    Reworked implicit borrowing to be more relaxed

    Fixes #376 (can't compare &str with str, while import/include remains the same by design)

    This PR changes SetChain into MapChain, where the value represents an optional variable which the local variable "points to". This improves the generated Rust code, as existing variables are no longer continuously generated for every macro call. This means that variables are no longer continuously borrowed, e.g. making it possible to s == "foo" in a macro.

    No test cases were modified, and this is now a non-breaking change.


    Old Explanation:

    To be able to reuse variables in nested macro calls, I ended up reworking SetChain into MapChain. Such that the each local can have an optional variable (or expression) which it points to. Then I added resolve_var to be able to follow and resolve a chain if variables, e.g. "param" -> "a" -> "b" -> "self.c".

    This avoid that previously when let (..) = (..) would be defined in the local scope, it would either (a) cause values to be moved if non-copyable or (b) force all values to be referenced. This would cause every level of nested macro call, to increase the amount of indirection (i.e. 3 depth macro call == &&&T). This would makeb it harder to use .clone(), but now it does not exceed &T so using .clone() is always possible.

    Given that HashSet<T> internally uses a HashMap<T, ()>, then a SetChain can still be created using, e.g. type SetChain<'a, T> = MapChain<'a, T, ()>. Which implies that they are still identical. I have not changed "SetChain"'s functionality, I've only added get and get_skip as well as resolve_var which I implemented specifically for MapChain<'_, &str, Option<String>>.

    Additionally, now empty let () = (); would be generated more frequently, since variables are forwarded. So these are also culled from the output.

    opened by vallentin 16
  • Add support for `io::Write` render method (i.e. `render_into_bytes` and `render_bytes`)

    Add support for `io::Write` render method (i.e. `render_into_bytes` and `render_bytes`)

    As promissed in https://github.com/djc/askama/issues/163, here is a pul request that does the following:

    • adds a new render_into_bytes that takes a io::Write instance, and adapts it to fmt::Write and calls the plain render_into method;
    • adds a new render_bytes similar to render that returns a Vec<u8> instead of a String;

    The two changes above are trivial, however there is a backward compatibility issue: in order to properly return an io::Error, I had to add the Io enum variant to Error, therefore this will fail in cases where the user hasn't included a _ pattern in the match.

    Additionally, the bulk of the pull request, in order to aid tests, I've done the following:

    • created an assert_render! macro that should replace the usage of assert_eq!(t.render().unwrap(), "expected") with just assert_render!(t, "expected"); the macro calls both render() and render_bytes() to check that the output is correctly generated via both implementations;
    • I've updated all the test cases to use the assert_render! macro described above; (I've left the integration tests alone;)
    • I've updated the benchmarking code to include the render_bytes function; (I've renamed the previous function with the _string suffix, and added a new one with _bytes suffix to be more clear;)

    Regarding benchmarks, it appears that the render_bytes (i.e. Vec<u8>) method is somewhat slower than the render (i.e. String) variant.

    BTW, the assert_render! macro could be used in the future to make sure that for example no write methods are called with an empty string as I've reported in another issue.

    opened by cipriancraciun 16
  • Immutable self and `Iterator::next`

    Immutable self and `Iterator::next`

    How do you process iterator if you need it's values in different places, so you can't let it to be consumed by for? The issue is that Iterator::next needs &mut self and render is only have an immutable one. The only way I found is wrapping the iterator into an interior mutability primitive. Is there another methods dealing with this? Why don't render accept &mut self instead?

    opened by imbolc 15
  • Forced template root dir

    Forced template root dir

    The path is interpreted as relative to the templates dir in the directory where the originating crate's Cargo.toml resides.

    Why? This forces me a 1 way structure, that works bad with my project tree. Please add an option to change the root dir, or better to add multiple ones.

    opened by trsh 15
  • Add support for importing template files with macros

    Add support for importing template files with macros

    This is a try at an implementation of https://github.com/djc/askama/issues/40.

    I've intentionally kept this as limited as possible because I'm not sure what functionality that should be included. Compared to Jinja there's no support for "import as" or "from import", instead all macros are added to the same namespace.

    I first tried to implement this in generator.rs as some combination of the include and macro functionality but I couldn't get that past the borrow checker. The macros need to exist for the full generation and because they contain slices of the imported sources the imports need to be parsed before the generation starts. In the end I put the ownership of the imported sources and nodes in lib.rs in the same way as for the parent template.

    opened by larros 15
  • askama_axum v0.2 error with Template

    askama_axum v0.2 error with Template

    after update askama_axum to 0.2 (ref #756) i get following error and with the propose use statement

    error[E0412]: cannot find type `BoxBody` in crate `askama_axum`
      --> mycrate\src\main.rs:11:10
       |
    11 | #[derive(Template)]
       |          ^^^^^^^^ not found in `askama_axum`
       |
       = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
    help: consider importing this type alias
       |
    1  | use axum::body::BoxBody;
       |
    help: if you import `BoxBody`, refer to it directly
       |
    11 | #[derive(Template)]
    

    code similar to example at https://github.com/djc/askama/blob/main/askama_axum/tests/basic.rs

    error on #[derive(Template)]

    use askama::Template;
    use axum::{
        extract,
        http::StatusCode,
        response::{Html, IntoResponse, Response},
        routing::{get, MethodRouter},
        Router,
    };
    
    #[derive(Template)]
    #[template(path = "hello.html")]
    struct HelloTemplate {
        name: String,
    }
    

    is why cargo upgrade mark update incompatible?

    name        old req compatible latest new req note        
    ====        ======= ========== ====== ======= ====
    anyhow      1.0.68  1.0.68     1.0.68 1.0.68
    askama      0.11.1  0.11.1     0.11.1 0.11.1
    askama_axum 0.1.0   0.1.0      0.2.0  0.1.0   incompatible
    axum        0.6.1   0.6.1      0.6.1  0.6.1
    tokio       1.23.0  1.23.0     1.23.0 1.23.0
    
    opened by bouncydingbat 10
  • Unable to compare integer from a loop (reference)

    Unable to compare integer from a loop (reference)

    This very simple case raises an error at compilation:

    error[E0308]: mismatched types
     --> src\main.rs:3:10
      |
    3 | #[derive(Template)]
      |          ^^^^^^^^ expected `i32`, found `&i32`
      |
      = note: this error originates in the derive macro `Template` (in Nightly builds, run with -Z macro-backtrace for more info)
    
    use askama::Template;
    
    #[derive(Template)]
    #[template(source  = "
    {% for (id, title) in titles %}
        {% if current_id.is_some() && current_id.unwrap() == id %}
            <b>{{ title }}</b>
        {% else %}
            {{ title }}
        {% endif %}
    {% endfor %}
    ", ext = "html")]
    struct MyTemplate {
        titles: Vec<(i32, String)>,
        current_id: Option<i32>,
    }
    
    fn main() {
        let titles = MyTemplate { titles: vec![(1, "AAA".to_string()), (2, "BBB".to_string())], current_id: Some(1) };
        println!("{}", titles.render().unwrap());
    }
    

    The only solution I found is a bit ugly (it seems Askama doesn't support guarded cases):

    {% for (id, title) in titles %}
        {% match current_id %}
            {% when Some with (current_id_value) %}
                {% if current_id_value == id %}
                    <b>{{ title }}</b>
                {% else %}
                    {{ title }}
                {% endif %}
            {% when None %}
                {{ title }}
            {% endmatch %}
    {% endfor %}
    

    I also tried with 'eq(..)' without success.

    opened by Ummon 0
  • Extract parser

    Extract parser

    A rough pass at extracting the parser code from the derive generator. A basic AST provides what's needed for the generator, but much more care would need to be given to the public API.

    A bare-bones AST printer demonstrates a second client. Slight modifications were made to the parser to ensure all structures could be round-tripped.

    Motivations include a personal project to implement an alternate Askama backend, as well as #425 maybe?

    opened by couchand 8
  • [Question] How do you get syntax-highlight of askama templates?

    [Question] How do you get syntax-highlight of askama templates?

    Hi! First of all, thanks for the great work!

    I started using Askama recently and wanted to know how do you deal with syntax-highlight in text editors. I browse the issues and found a IntelliJ-based highlighter. Since Askama has already a parser, I would assume that it would be pretty easy to develop a highlighter for wide consumption. I am thinking of a wasm module perhaps, or a contribution to highlightjs..

    I have never developed a syntax-highlighter, so maybe I do not know what I am talking about, but wanted to know how people deal with this in Askama.

    opened by saona-raimundo 1
  • 0.12 release planning

    0.12 release planning

    @GuillaumeGomez is asking when we can next release. Is there anything still in flight that we should merge first?

    I know there's i18n (#700) which would be nice to move forward, but (a) that feels like it still needs a bunch of work, (b) it's maybe not breaking compat? Looks like we should also merge #632, potentially #668.

    @Kijewski @vallentin any thoughts?

    opened by djc 4
Releases(0.11.0)
  • 0.11.0(Dec 21, 2021)

    After almost 18 months of development, I'm happy to finally announce the 0.11.0 release of Askama, the type-safe, compiled Jinja-like template engine for Rust. Importantly, during this release cycles two new members joined the Askama team (consisting of just @djc at the start of this release): @vallentin and @Kijewski, who both contributed many well-designed improvements to this release. Contributors added integrations for the Axum and Tide web frameworks to our existing set of integrations for Rocket, Actix-Web, Warp and Gotham.

    Perhaps the most visible change in this release is the redefined Template trait which now has a DynTemplate counterpart rather than the SizedTemplate used in the previous release (see #579). That said, the template language itself has grown a number of helpful features (as detailed below), while the code generator can now avoid many compilation issues due to better heuristics. We also improved whitespace handling to be more correct, and made several dependencies optional such that using default-features = false on any of the Askama crates should minimize dependencies if so desired.

    Changes:

    • Use a separate trait for object safety (#579)
    • Allow whitespace in expressions (#327, thanks to @cipriancraciun)
    • Add support for shadowing variables (#411)
    • Change extension values to ignore common Jinja extensions (#458)
    • Disable default features for askama_shared in askama_derive (#344, thanks to @JohnTitor)
    • Disable Askama's default features in integration crates (#409, thanks to @Randati)
    • Upgrade to nom 7 (#530; nom 6 was done in #372)
    • Improve error messages using cuts (#513)
    • Improve error messages using compile_error!() (#373, thanks to @msrd0 for improving this in #374)
    • Allow paths to start with :: (#393)
    • Improve template loop generation (#401)
    • Remove implicit borrowing of literals, calls and more (#423)
    • Pass all-uppercase variables through as constants (#433)
    • Enable no_std support in askama_escape (#436, thanks to @Nemo157)
    • Use raw identifiers for identifiers which collide with Rust keywords (#476, thanks to @SciStarter)
    • Rework implicit borrowing to be more relaxed (#396, thanks to @msrd0 for adding tests in #379)
    • Improve if-statement generation to avoid issues with implicit borrows (#392)

    Bug fixes:

    • Fix whitespace issues in match blocks (#399)
    • Fix path parser to account for single identifier type names (#453)
    • Fix support for raw method identifiers (#548, thanks to @kellytk)
    • Fix code generation for macro calls that store args in variables (#499, thanks to @rfk)
    • Fix loop generation when accessing field (#500)
    • Fix whitespace handling in if-blocks (#394)
    • Fix implicit borrow of expressions (#390)
    • Avoid hanging the build due to template recursion (#539, thanks to @grv07)
    • Avoid parsing non-template attributes (#549)

    Template language:

    • Implement nested tuple destructuring in let and for (#506)
    • Implement struct destructuring in let and for (#509)
    • Add support for loop.cycle() expressions (#517)
    • Add support for for-else blocks (#518)
    • Add support for break and continue blocks (#519)
    • Allow whitespace trimming in raw blocks (#546)
    • Add set alias for let blocks (#402)
    • Add support for parsing nested comments (#408)
    • Fix parsing precedence and associativity (#391, #426)

    Filters:

    • Stop escaping forward slashes (#486, thanks to @alexwennerberg)
    • Fix urlencode filter to be usable for URL segments, add urlencode_path (#384, thanks to @JakubValtar)
    • Add new paragraphbreaks filter (#467, thanks to @mbuscemi)
    • Add format filter that swaps the first two arguments (#345, thanks to @couchand)
    • Add support for optional escaper argument for escape filter (#560)
    • Change info_f64 and into_isize filters to take references (#359, thanks to @yshui)
    • Update book to document all filters (#429, #432)

    Integrations:

    • Removed the Iron integration (#527)
    • Add Tide integration (#347, thanks to @jbr)
    • Add Axum integration (#563, thanks to @malyn)
    • Upgrade Gotham integration to Gotham 0.7 (#557)
    • Upgrade Actix-Web integration to Actix-Web 3 (#356), with support for v4 supported on main thanks to @pashinin, @jaw-sh
    • Upgrade Warp integration to warp 0.3 (#437, thanks to @paolobarbolini)
    • Preliminary support for Rocket 0.5 (#495, thanks to @shritesh and @flo-l; unreleased for now)

    Thanks go to @freddyb, @edg-l, @BafDyce, @xfix, @mkj, @robjtede, @technic, @JakeChampion, @SamJakob, @jplatte, @Restioson for their contributions, too.

    Source code(tar.gz)
    Source code(zip)
  • 0.10.0(Jun 30, 2020)

    After 5 months of development, I'm happy to announce the availability of version 0.10 of Askama, the type-safe, compiled Jinja-like template engine for Rust. The major (breaking) change in this release is that the framework integrations, which were previously included in the main crate behind feature flags, have now been moved into 4 separate crates; a new integration with the warp web framework is also shipped in a separate askama_warp crate. If you use an integration, you should now only depend on the integration crate, which re-exports content from the askama crate as well as any integration symbols. Finally, @cetra3 has created a book which should make navigating the documentation much better.

    Upgrade notes:

    • Move integration code into askama_actix, askama_gotham, askama_iron and askama_rocket crates
    • Update Gotham integration to version 0.4

    Other changes:

    • Move documentation into a new book (#332, thanks to @cetra)
    • Add integration for the warp web framework, as an askama_warp crate (#290, thanks to @aeons)
    • Allow blocks to be nested inside if, for and match blocks (#336)
    • Support for function calls (#304, thanks to @Senzaki)
    • Add urlencode filter (#305, thanks to @jxs)
    • Disable default features in many dependencies to limit the size of the transitive dependency set
    • Fix panic in truncate filter (#296, thanks to @danloh)

    Thanks to @paolobarbolini, @brunobell, @cipriancraciun, @kyrias, @jeromegn, @NilsIrl and @DusterTheFirst for additional improvements.

    Source code(tar.gz)
    Source code(zip)
  • 0.9.0(Feb 24, 2020)

    After 11 months of development, I'm happy to announce the availability of version 0.9 of Askama, the type-safe, compiled Jinja-like template engine for Rust. This has been a long release cycle; mostly I've spent quite a bit of time trying to figure out problems with how to manage Askama's built-in integrations. In the end, 0.9.0 shipped with the integrations problems unsolved, but they were solved shortly thereafter.

    Upgrade notes:

    • Move no-receiver size_hint() method to a separate trait (#270, thanks to @jbg)
    • Upgrade Actix-Web integration to Actix-Web 2.0 (#286, thanks to @DCjanus)
    • Default Actix-Web and Gotham integrations to UTF-8 (#219, thanks to @spease)

    Other changes:

    • Add basic support for {% raw %} blocks (#231, thanks to @fokinpv)
    • Allow referencing self as a variable (fixes #207)
    • Add support for boolean literals (#265, thanks to @davebrent)
    • Add support for character literals (#283, thanks to @siiptuo)
    • Support escaping in string literals (#287, thanks to @siiptuo)
    • Improve interface for askama_escape (#243, thanks to @quadrupleslap)
    • Allow Rust macro calls in more places (#226)
    • Fix a regression in partial inheritance (#224)
    • Improvements to the Actix-Web integration (#223, thanks to @DoumanAsh)
    • Clarify documentation on filter precedence (#230, thanks to @notsimon)
    • Add documentation on how to deal with recursive data types (#235, thanks to @drahnr)
    • Add documentation on nesting Template types (#218, thanks to @victe)
    • Improve documentation for Actix-Web and Gotham integrations (#250, thanks to @bardiharborow)
    • Upgrade to nom 5 and non-macro parser combinators
    • Upgrade to syn/quote/proc_macro2 version 1.0

    Thanks to @kazimuth and @bardiharborow for additional internal improvements.

    Source code(tar.gz)
    Source code(zip)
  • 0.8.0(Feb 20, 2019)

    After 3 months of development, I'm happy to announce the availability of version 0.8 of Askama, the type-safe, compiled Jinja-like template engine for Rust -- all the more so because it has taken me way too long to push out this release due to an exceedingly busy period in my personal life.

    Askama 0.8 is up to 2 times as fast as 0.7.2, thanks to performance improvements contributed by @botika and @yossyJ. For comparisons to other template engines, please look at the template benchmarks repo. The largest feature this time around is the newly added support for pluggable escape engines and formats. By adding just a few lines to the askama.toml configuration file and writing a simple implementation of the Escaper trait, Askama can use custom code for escaping, such as for different formats (LateX or shell) or with even more optimized performance (using SIMD).

    Upgrade notes:

    • The use of build scripts is no longer needed and has been deprecated (#199, thanks to @de-vri-es)
    • Upgraded the Rocket integration to Rocket 0.4
    • Template::extension() is now a static method (#127, thanks to @ubnt-intrepid)
    • Use of the _parent field is now deprecated (thanks to @botika)

    Other changes:

    • Upgraded the Rocket integration to Rocket 0.4
    • Added optional support for Gotham integration (#177, thanks to @rakenodiax)
    • Added an into_response() method for actix-web users (#205, thanks to @ZizhengTai )
    • Add support for tuple destructuring in let and for blocks (#187, thanks to @yossyJ)
    • Added optional yaml filter (#192)
    • Added an indent filter (#131, thanks to @casey)
    • Added isize and f64 filters (#146, thanks to @tizgafa)
    • Added a filesizeformat filter (#161, thanks to @tizgafa)
    • Added support for the loop.last variable (#194, thanks to @yossyJ)
    • Allow matching enum struct variants (#182, thanks to @mcarton)
    • Allow templates to work without importing Template directly (#147, thanks to @ubnt-intrepid)
    • Allow referencing self in expressions (#207)
    • Fixed problems with unescaped expressions (#107 and #132)
    • Fixed off-by-one error in escaping function (#138, thanks to @benjunmun)
    • Send debug output to stderr instead of stdout
    • Document assignment using {% let %} blocks
    Source code(tar.gz)
    Source code(zip)
  • 0.7.2(Oct 8, 2018)

    After two months, I'm happy to announce the 0.7.2 release of Askama, the type-safe, compiled Jinja-like template engine for Rust! Despite the small version number increase (because this release should be fully backwards compatible with earlier 0.7 releases), there's a good amount of feature in this release. Happily, I can say that for the first time, all of the improvements in this release are due to @botika spending a lot of time on improving Askama over the past months, for which I owe them many thanks! Let's dive in:

    • Custom syntax support: in response to a bug reporter who wanted to generate LaTeX with Askama (#121), it is now possible to use custom block delimiters in your Askama templates. Read the documentation for more information on how to define and use custom syntaxes. Thanks to @botika for spending a lot of time on getting this just right.
    • Added a number of built-in filters: abs, capitalize, center and wordcount
    • Fixed support for range-based for-loops (#117) by specializing the code generator
    • Fixed operator precedence issues with loop attributes (like index)
    • Fixed a number of edge cases in macro scope resolution
    Source code(tar.gz)
    Source code(zip)
  • 0.7.1(Jul 23, 2018)

    Some nice new features are now available as part of Askama 0.7.1. The most important one is the ability to search multiple directories for template files. This works by adding an askama.toml file to the crate root and specifying the search directories in there (see the documentation). Now that there is a configuration mechanism, this may unlock other potential features that rely on some way to specify out-of-band configuration.

    This release also adds optional support for actix-web. If you enable the with-actix-web feature, Template derives will include an impl for actix-web's Responder trait, so that you can trivially return template context structs from actix-web handlers.

    • Add support for multiple template directories (thanks to @mashedcode)
    • Add impl for actix-web Responder trait (thanks to @ryanmcgrath)
    • Add linebreaks and linebreaksbr filters (thanks to @Aaronepower)
    • Allow Template users to inspect template extension() (thanks to @ryanmcgrath)
    • derive(Template) is no longer restricted to named field struct types
    Source code(tar.gz)
    Source code(zip)
  • 0.7.0(Jun 25, 2018)

    I'm excited to announce a new release of Askama, the type-safe, compiled Jinja-like template engine for Rust. Among other things, this is what actix-web uses in their TechEmpower benchmarks. Note that this release relies on Rust features first released in 1.26.0.

    The most interesting new feature in this release is an overhauled inheritance model:

    • _parent fields are no longer needed (but still supported for compatibility)
    • Supported for multi-layer inheritance has been implemented
    • Blocks can now be defined inside other blocks
    • The super() macro can be used to call parent blocks from inside a block
    • Removes the need for elaborate imports for inheritance across modules
    • Fixes some issues with extends paths on Windows

    For this release I finally spent some time collecting benchmarks for template engines. The results can be found in this GitHub repository. I was happy to see that Askama performance seems more than competitive compared to popular alternatives.

    Smaller improvements in this release:

    • Add support for Range expressions (a..b; see #95)
    • Add support for Index operation (a[b]; see #95)
    • Allow methods to be called on self
    • Add support for loop.first variable
    • Add a simple truncate filter (see #95)
    • Matching is more robust thanks to match binding modes (fixes #94)
    • askama::Error is now Send + Sync + 'static
    • Renamed lifetime on Rocket integration to prevent conflicts (fixes #88)
    • Upgrades to nom 4, syn 0.14 and quote 0.6

    Thanks to @Smibu and @dathinab for contributing code to this release, and to everyone else who submitted feedback for their support in further improving Askama.

    I recently started a Patreon page. If you are in a position to support ongoing maintenance and further development of Askama or use it in a for-profit context, please consider supporting my work!

    Source code(tar.gz)
    Source code(zip)
  • 0.6.4(Apr 30, 2018)

  • 0.6.3(Apr 30, 2018)

  • 0.6.2(Apr 18, 2018)

    Some great bug reports came in after the 0.6.0 and 0.6.1 releases last week, which I fixed:

    • Fixed problems with using nested filter (or macro) calls in expressions (#78)
    • Add documentation and tests for comments, after an issue with whitespace surrounding comments was found (#79)
    Source code(tar.gz)
    Source code(zip)
  • 0.6.1(Apr 18, 2018)

    This is a quick bugfix release for #73: due to an unsupported way of including syn, Askama had a run-time dependency on proc-macro, which didn't work well in some scenarios. Thanks to @dtolnay for the bug fix.

    Source code(tar.gz)
    Source code(zip)
  • 0.6.0(Apr 12, 2018)

    Finally, another release of Askama, the type-safe compiled Jinja-like Rust templating library. The biggest feature in this release is the support for match blocks, making it possible to do pattern matching in templates. An example is provided in the documentation.

    • Implement basic match functionality (thanks to @anowell)
    • Add support for importing template files with macros (fixes #51, thanks to @larros)
    • Fixed implementation of Rocket Responder which was broken in the 0.5.0 release
    • Infer Content-Type from the file extension for Iron integration (thanks to @hajifkd)
    • Add support for array literals (fixes #59)
    • Add support for tuple indexing (thanks to @larros)
    • Numerous bug fixes

    Thanks to everyone who has contributed to Askama!

    Source code(tar.gz)
    Source code(zip)
  • 0.5.0(Sep 7, 2017)

    Discussing the 0.4.0 release made me think I should quickly make one further change: inferring the escape mode from the template path, or a specified extension if you're using the source attribute. This means escaping is now only on by default for templates with a html, htm, or xml extension. In addition, this release escapes more characters, according to the OWASP recommendations.

    If you spent time making changes for the 0.4.0 upgrade already, sorry about the churn! I believe this minimizes boilerplate and hopefully doesn't introduce too much magic.

    Source code(tar.gz)
    Source code(zip)
  • 0.4.0(Sep 6, 2017)

    Roughly six months after announcing the first public version of Askama, 0.4.0 feels like a large update.

    There are some breaking changes compared to the 0.3.0 series:

    • &, < and > are replaced with HTML character entities by default (see #23)
    • Run-time errors are now returned via custom Error and Result types

    Other noteworthy new features include:

    • Optional integrations for Rocket and Iron (see examples for Rocket and Iron)
    • Support for defining variables, user-defined filters, includes and macros
    • Inheriting templates no longer have to use _parent to refer to fields from the parent context
    • Template implementations now automatically implement Display
    • Better robustness and more explicit error handling through panics at compile time
    • Much faster compilation in some edge cases with nested binary operators

    Special thanks to those who have contributed to this release, in particular @anowell and @defyrlt.

    Please post your feedback or questions as an issue or join the chat!

    Source code(tar.gz)
    Source code(zip)
  • 0.3.4(Aug 6, 2017)

  • 0.3.2(Mar 12, 2017)

    • No longer need to use std; or use askama; in template modules (#17)
    • Add lower, trim and upper filters (#16, #19)
    • Documentation improvements, including an explanation of inheritance pitfalls
    Source code(tar.gz)
    Source code(zip)
  • 0.3.1(Mar 9, 2017)

  • 0.3.0(Mar 9, 2017)

    • Hide askama_derive crate usage inside askama, making it easier to use (#2)
    • Better support for Iterator variants in for loops (#8)
    • Add support for having generic type parameters in template context structs (#11)
    • Fix bugs around loop index attributes (#10)
    • Improve error messages in case of errors (#3, #4)
    Source code(tar.gz)
    Source code(zip)
  • 0.2.1(Mar 9, 2017)

Owner
Dirkjan Ochtman
Dirkjan Ochtman
:pencil: Compile-time HTML templates for Rust

maud Documentation (source) • API reference • Change log Maud is an HTML template engine for Rust. It's implemented as a macro, html!, which compiles

Chris Wong 1.4k Jan 1, 2023
Templates for creating rust projects with a GitHub-managed lifecycle with cargo-generate 🏗️📃

rust-templates Templates for creating rust projects with a GitHub-managed lifecycle with cargo-generate. ??️ ?? What you get: PR build validation usin

Ben Greenier 1 Oct 30, 2021
Quickly create boilerplate projects and templates.

boyl boyl is a command-line tool written in Rust to manage template folders. boyl can copy existing folders (with support for glob-like ignore pattern

Miguel M. 13 Feb 16, 2022
📦 Transpile readable code into DiamondFire templates

Welcome to fudge ?? ?? Transpile readable code into DiamondFire templates Author ?? BumpyBill & DADp Show your support Give a ⭐️ if this project helpe

null 6 Jan 25, 2022
Compiler for Jade-like template language to cito.js-based virtual dom

Marafet A very experimental DSL for creating (mostly) single page applications in HTML. It's mostly a Jade-like (or Haml-like) templating language wit

Paul Colomiets 11 Jun 25, 2020
Hatch new projects like a chick coming out of its egg

?? Cargo Hatch Hatch new projects like a chick coming out of its egg. Cargo hatch is a cargo init/cargo new on steroids, allowing complex templates th

Dominik Nakamura 6 Nov 2, 2022
Rust templating with Handlebars

handlebars-rust Handlebars templating language implemented in Rust and for Rust. Handlebars-rust is the template engine that renders the official Rust

Ning Sun 922 Dec 27, 2022
Yarte stands for Yet Another Rust Template Engine

Should we start to worry? bytes-buf feature can produce SIGILL. avx and sse flags are in almost all cpus of x86 and x86_64 architectures. More details

Juan Aguilar 249 Dec 19, 2022
A macro-based html builder for rust

Horrorshow A macro-based html templating library, compatible with stable rust (currently requires rust >= 1.37). Features This crate will degrade grac

Steven Allen 267 Dec 11, 2022
A template engine for Rust based on Jinja2/Django

Tera Tera is a template engine inspired by Jinja2 and the Django template language. <title>{% block title %}{% endblock title %}</title> <ul> {% for u

Vincent Prouillet 2.5k Jan 1, 2023
Hiccup html templating in rust

Hiccup A Clojure's Hiccup inspired macro. At the moment support for inline code execution is not guaranteed. The main objective of this lib is to prev

Julia Naomi 13 May 28, 2022
A flexible template engine for Rust

Rustache Rustache is a Rust implementation of the Mustache spec. Documentation The different Mustache tags are documented at the mustache(5) man page.

rustache 208 May 10, 2022
A minimalist Rust WebAssembly project template

MiniWASM - A minimalist Rust WebAssembly project template This is a minimal Rust-powered WebAssembly application template. It was designed to showcase

Emil Loer 160 Jul 26, 2022
A template for a Rust-powered static-page Try Online interface

rust-tio-template A template for a Rust-powered static-page Try Online interface What is included This is an example setup that enables all of the fol

null 2 Dec 13, 2021
MiniJinja is a powerful but minimal dependency template engine for Rust

MiniJinja: a powerful template engine for Rust with minimal dependencies MiniJinja is a powerful but minimal dependency template engine for Rust which

Armin Ronacher 686 Jan 5, 2023
A "Hello, world!" template of a Rust binary crate for the ESP-IDF framework.

Rust on ESP-IDF "Hello, World" template A "Hello, world!" template of a Rust binary crate for the ESP-IDF framework. This is the crate you get when ru

Ivan Markov 140 Jan 4, 2023
A fast & simple boilerplate generator, built with Rust. 🦀

Boom ?? A fast & simple boilerplate generator, built with Rust. Installing boom This package is not yet downloadable on Brew or other package managers

Tristan Edwards 4 Apr 20, 2022
A template for creating services in Rust using Axum and Prisma.

A template for creating services in Rust using Axum and Prisma. This uses the super cool Prisma Rust Client.

Aaron Leopold 6 Oct 19, 2022
✨ A perfect template for a binary rust project.

Rust Template A project template for Rust, helping to structure your projects blazingly fast ⚡ . Features ?? Code-ready for binary projects. Add amazi

bwtecode 3 Aug 21, 2022