1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//! Askama implements a type-safe compiler for Jinja-like templates.
//! It lets you write templates in a Jinja-like syntax,
//! which are linked to a `struct` defining the template context.
//! This is done using a custom derive implementation (implemented
//! in [`askama_derive`](https://crates.io/crates/askama_derive)).
//!
//! 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
//! context combined with a UTF-8 encoded text file (or inline source, see
//! below). Askama can be used to generate any kind of text-based format.
//! The template file's extension may be used to provide content type hints.
//!
//! A template consists of **text contents**, which are passed through as-is,
//! **expressions**, which get replaced with content while being rendered, and
//! **tags**, which control the template's logic.
//! The template syntax is very similar to [Jinja](http://jinja.pocoo.org/),
//! as well as Jinja-derivatives like [Twig](http://twig.sensiolabs.org/) or
//! [Tera](https://github.com/Keats/tera).
//!
//! ## The `template()` attribute
//!
//! Askama works by generating one or more trait implementations for any
//! `struct` type decorated with the `#[derive(Template)]` attribute. The
//! code generation process takes some options that can be specified through
//! the `template()` attribute. The following sub-attributes are currently
//! recognized:
//!
//! * `path` (as `path = "foo.html"`): sets the path to the template file. The
//!   path is interpreted as relative to the configured template directories
//!   (by default, this is a `templates` directory next to your `Cargo.toml`).
//!   The file name extension is used to infer an escape mode (see below). In
//!   web framework integrations, the path's extension may also be used to
//!   infer the content type of the resulting response.
//!   Cannot be used together with `source`.
//! * `source` (as `source = "{{ foo }}"`): directly sets the template source.
//!   This can be useful for test cases or short templates. The generated path
//!   is undefined, which generally makes it impossible to refer to this
//!   template from other templates. If `source` is specified, `ext` must also
//!   be specified (see below). Cannot be used together with `path`.
//! * `ext` (as `ext = "txt"`): lets you specify the content type as a file
//!   extension. This is used to infer an escape mode (see below), and some
//!   web framework integrations use it to determine the content type.
//!   Cannot be used together with `path`.
//! * `print` (as `print = "code"`): enable debugging by printing nothing
//!   (`none`), the parsed syntax tree (`ast`), the generated code (`code`)
//!   or `all` for both. The requested data will be printed to stdout at
//!   compile time.
//! * `escape` (as `escape = "none"`): override the template's extension used for
//!   the purpose of determining the escaper for this template. See the section
//!   on configuring custom escapers for more information.
//! * `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.

#![allow(unused_imports)]
#[macro_use]
extern crate askama_derive;
pub use askama_shared as shared;

use std::fs::{self, DirEntry};
use std::io;
use std::path::Path;

pub use askama_escape::{Html, Text};

/// Main `Template` trait; implementations are generally derived
pub trait Template {
    /// Helper method which allocates a new `String` and renders into it
    fn render(&self) -> Result<String> {
        let mut buf = String::with_capacity(self.size_hint());
        self.render_into(&mut buf)?;
        Ok(buf)
    }
    /// Renders the template to the given `writer` buffer
    fn render_into(&self, writer: &mut dyn std::fmt::Write) -> Result<()>;
    /// Helper function to inspect the template's extension
    fn extension(&self) -> Option<&'static str>;
    /// Provides an conservative estimate of the expanded length of the rendered template
    fn size_hint(&self) -> usize;
}

pub trait SizedTemplate {
    /// Helper function to inspect the template's extension
    fn extension() -> Option<&'static str>;
    /// Provides an conservative estimate of the expanded length of the rendered template
    fn size_hint() -> usize;
}

pub use crate::shared::filters;
pub use crate::shared::helpers;
pub use crate::shared::{read_config_file, Error, MarkupDisplay, Result};
pub use askama_derive::*;

pub mod mime {
    #[cfg(all(feature = "mime_guess", feature = "mime"))]
    pub fn extension_to_mime_type(ext: &str) -> mime_guess::Mime {
        let basic_type = mime_guess::from_ext(ext).first_or_octet_stream();
        for (simple, utf_8) in &TEXT_TYPES {
            if &basic_type == simple {
                return utf_8.clone();
            }
        }
        basic_type
    }

    #[cfg(all(feature = "mime_guess", feature = "mime"))]
    const TEXT_TYPES: [(mime_guess::Mime, mime_guess::Mime); 6] = [
        (mime::TEXT_PLAIN, mime::TEXT_PLAIN_UTF_8),
        (mime::TEXT_HTML, mime::TEXT_HTML_UTF_8),
        (mime::TEXT_CSS, mime::TEXT_CSS_UTF_8),
        (mime::TEXT_CSV, mime::TEXT_CSV_UTF_8),
        (
            mime::TEXT_TAB_SEPARATED_VALUES,
            mime::TEXT_TAB_SEPARATED_VALUES_UTF_8,
        ),
        (
            mime::APPLICATION_JAVASCRIPT,
            mime::APPLICATION_JAVASCRIPT_UTF_8,
        ),
    ];
}

/// Old build script helper to rebuild crates if contained templates have changed
///
/// This function is now deprecated and does nothing.
#[deprecated(
    since = "0.8.1",
    note = "file-level dependency tracking is handled automatically without build script"
)]
pub fn rerun_if_templates_changed() {}