# yew-template
This crate allows you to separate your HTML from your Rust code when using [Yew](https://yew.rs).
## Getting Started
### Hello World
```html
<div>
<p>Hello [name]!</p>
</div>
```
```rust
let html = template_html!("templates/hello.html", name="World");
```
The code above will actually compile to the following code:
```rust
let html = html! {
<div>
<p>{"Hello World!"}</p>
</div>
};
```
## Usage
- [Attributes](#attributes)
- [Variables](#variables)
- [Expressions](#expressions)
- [Example: Yew callbacks](#example-with-yew-callbacks)
- [Optional variables](#optional-variables)
### Attributes
```html
<div style=[style]>
<p>Hello [name]!</p>
</div>
```
```rust
let html = template_html!("templates/hello.html", name="World", style="color: red;");
```
### Variables
```rust
let name = "World";
let html = template_html!("templates/hello.html", name);
```
Would compile to:
```rust
let name = "World";
let html = html! {
<div>
<p>{"Hello "}{name}{"!"}</p>
</div>
};
```
When the name of your variable isn't the same as the name in the template, you can use the following syntax:
```rust
let last_name = "World";
let html = template_html!("templates/hello.html", name=last_name);
```
### Expressions
```rust
let name_reversed = String::from("dlroW");
let html = template_html!(
"templates/hello.html",
name = {
let mut name = name_reversed.into_bytes();
name.reverse();
let name = String::from_utf8(name).unwrap();
name
}
);
```
Which will also display `Hello World!` as the output is as follows:
```rust
let name_reversed = String::from("dlroW");
let html = html! {
<div>
<p>
{"Hello "}{{
let mut name = name_reversed.into_bytes();
name.reverse();
let name = String::from_utf8(name).unwrap();
name
}}{"!"}
</p>
</div>
};
```
Note that the brackets around expressions are required for expressions.
### Example with Yew callbacks
```html
<div onclick=[onclick]>
<p>Hello [name]!</p>
</div>
```
```rust
let link = ctx.link();
Let's see how optional elements can be nested.
```html
<div>
<p>Hello [name]!</p>
<div opt>
<h2>Age</h2>
<p>You are [opt_age] years old!</p>
<p opt>And you are born in [opt_birth_city].</p>
</div>
</div>
```
Here, both `opt_age` and `opt_birth_city` are optional. `opt_age` would be displayed even if `opt_birth_city` is `None`. However, if `opt_age` is `None`, `opt_birth_city` will not be displayed regardless of its value.
From the Rust side, there is no usage difference. Note that brackets are required (for now).
```rust
let opt_age: Option<u8> = Some(20);
let opt_birth_city: Option<String> = None;
let html = template_html!("templates/opt.html", name="John", opt_age, opt_birth_city);
```
## Notes
- Litteral values are NOT escaped because they come from your code. Using a litteral value of `value closed by quotes" trailing stuff` will cause problems. This will be fixed in a future version.
- You can use multiple top-level elements in your html template file.
License: MIT