Reign View is a component based HTML templating library for Rust inspired by Vue.js templates.

This library makes using templates as easy as pie. It uses HTML based template syntax that are valid and can be parsed by spec-compliant browsers and HTML parsers [1][2]. It has been developed foremost with ease of use in mind followed by future extensibility, modularization and customization.

This library also provides multiple helpers and feature gates which an user can use to customize, allowing the library to be used directly with or without reign_router.

Please refer to API documentation for more details.

NOTE: Minimum supported Rust version is 1.45.0

Table of contents

Quickstart

  1. Add reign to your code base with default features ommitted and view feature enabled

    toml [dependencies] reign = { version = "*", features = ["view"], default-features = false }

  2. Initiate the templates in your main.rs

    ```rust,ignore use reign::prelude::*;

    // If your templates live under src/views folder views!("src", "views"); ```

  3. Write a template in src/views/pages/about.html

    ```html

    {{ name }} aged {{ age: u8 }}

    ```

  4. Render the template

    ```rust,ignore use reign::prelude::*;

    let (name, age) = ("John", 28);

    // The macro automatically captures all the // variables it needs, builds the view to display // and returns a String // // pages::about is the unique path of the above template render!(pages::about) ```

How it works

There are multiple steps that goes into this templating library.

Building

Let's assume that you have written the template described in the previous section at the respective path.

Now, when you initiate the templating library by writing the following:

```rust,ignore use reign::prelude::*;

views!("src", "views"); ```

The library expands the views! macro to something like the following:

``rust // It will create a module which is always calledviews` mod views {

// Then it will create a module for `pages` subdirectory
pub mod pages {

    // Then it will create a struct for the template file
    pub struct About<'a> {

        // It will add a raw string field for every variable
        // found which does not have a type described
        pub name: &'a str,

        // It will add a typed field for every variable found
        // that was given a type (once in a template is enough)
        pub age: u8,
    }

    use std::fmt::{Display, Formatter, Result};

    // Then it will implement std::fmt::Display for it
    impl Display for About<'_> {
        fn fmt(&self, f: &mut Formatter) -> Result {
            write!(f, "{}{}{}{}{}",
                "<p>\n  ", self.name, "\n  <sub>aged ", self.age, "</sub>\n</p>"
            )
        }
    }
}

} ```

The above expansion is approximate. There might be small changes in the way they were expanded or other hidden things that are for internal use.

You can read more about template syntax below here

Rendering

When the plain view feature is enabled and when you try to render a template like the following:

```rust,ignore use reign::prelude::*;

let (name, age) = ("John", 28);

render!(pages::about); ```

The library expands the render! macro to something like the following:

rust,ignore format!("{}", crate::views::pages::About { name: name.as_ref(), age, });

Which returns the following String:

```html

John aged 28

``` # Template Syntax Before we start talking about the template syntax, let's agree on a few terms for this section so that it will be easier to refer to them later on. An **expression** is a custom subset of all the types of expressions available in Rust language. You can read about them [here](#expressions). A **pattern** is a custom rust pattern syntax where the expressions allowed are the only ones defined in the above paragraph. You can read more about them [here](#patterns). A **field** refers to a field of the struct that is built for the template by the `views!` macro when initiating the template library. All html style tags that are used in the template should be closed either by a self closing syntax or an end tag. The only exception are the tags which are allowed by HTML spec to be self closing by default called **void elements**. ### Text The most basic form of templating is *"interpolation"* using the *"mustache"* syntax (double curly braces). ```html Message: {{ msg }} ``` The mustache tag will be replaced with the value of the `msg` *field*. You can also use an *expression* inside the mustache tags. Any type that has `std::fmt::Display` implemented can be the final result of the *expression* defined by the mustache tags. ```html Word Count: {{ msg.len() }} ``` ### Attributes Interpolation can also be used in values of attributes. ```html md5-657b7fa289296ba2e5a439fd91c75b6c ``` Fortunately, this is possible by using our custom `slot` element in the `button.html`. ```html ``` The `` above will be replaced by the elements we described inside `shared:button` element when it's used. ### Scope When we use a variable inside a component's slot, such as: ```html md5-1b7df684274d3f65844bec983fb6a6ab ``` That slot tries to access this templates fields (i.e. the same `scope`). The slot does not have access to ``'s fields. For example, trying to access `href` would not work: ```html md5-124de5e9ca4ee387be02fc868c0e9540 ``` It would instead create a `href` field on the template itself. ### Fallback To be implemented ### Named Slots There are times when it’s useful to have multiple slots. For example, in a `` component with the following template: ```html md5-7754c517446036afe721e1fe43c67a06 ``` For these cases, the `` element has a special attribute, `name`, which can be used to define additional slots: ```html md5-d1e231d069efedea4d38c1ab454103e9 ``` A `` outlet without `name` implicitly has the name `"default"`. To provide content to named slots, we can use a special attribute on a `