### {% %}の利用
テンプレート内での計算などができる
<body class="container"> <h1 class="display-6 my-2">{{title}}</h1> <div class="border border-primary p-3 my-3"> {% set v1 = value * 1.08 %} {% set v2 = value * 1.1 %} <p class="my-2">value: {{ value }}</p> <p class="my-2">value1: {{ v1 }}</p> <p class="my-2">value2: {{ v2 }}</p> </div> </body>
main.rs
#[tokio::main] async fn main() { let app = axum::Router::new() .route("/:value", axum::routing::get(handle_index)); axum::Server::bind(&"192.168.56.10:8000".parse().unwrap()) .serve(app.into_make_service()) .await .unwrap(); } async fn handle_index(axum::extract::Path(value): axum::extract::Path<usize> )-> axum::response::Html<String> { let tera = tera::Tera::new("template/*").unwrap(); let mut context = tera::Context::new(); context.insert("title", "Index page"); context.insert("value", &value); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) }
{% raw %}で生の文を出力する
L HTMLタグはそのまま表示される
<div class="border border-primary p-3 my-3"> {% raw %} {% set v1 = value * 1.08 %} {% set v2 = value * 1.1 %} <p class="my-2">value: {{ value }}</p> <p class="my-2">value1: {{ v1 }}</p> <p class="my-2">value2: {{ v2 }}</p> {% endraw %} </div>
テキストで繋げる
<div class="border border-primary p-3 my-3"> {% set v1 = value * 1.08 %} {% set v2 = value * 1.1 %} <p class="my-2">value: {{ value }}</p> <p class="my-2">value1: {{ value ~ " * 1.08 = " ~ v1 }}</p> <p class="my-2">value2: {{ value ~ " * 1.1 = " ~ v2 }}</p> </div>
### ifを使う
{% if value % 2 == 0 %} <div class="border border-primary p-3 my-3"> <p class="my-2">value: {{ value ~ "は偶数です。" }}</p> </div> {% else %} <div class="border border-primary p-3 my-3"> <p class="my-2">value: {{ value ~ "は奇数です。" }}</p> </div> {% endif %}
更に分岐したい場合
{% if value % 3 == 0 %} <div class="border border-primary p-3 my-3"> <p class="my-2">value: {{ value ~ "はグーです。" }}</p> </div> {% elif value % 3 == 1 %} <div class="border border-primary p-3 my-3"> <p class="my-2">value: {{ value ~ "はチョキです。" }}</p> </div> {% else %} <div class="border border-primary p-3 my-3"> <p class="my-2">value: {{ value ~ "はパーです。" }}</p> </div> {% endif %}
### 繰り返し表示
main.rs
async fn handle_index()-> axum::response::Html<String> { let data = [ Myform {name:"taro".to_string(), mail:"taro@yamada".to_string()}, Myform {name:"hanako".to_string(), mail:"hanako@flower".to_string()}, Myform {name:"sachiko".to_string(), mail:"sachiko@happy".to_string()}, Myform {name:"jiro".to_string(), mail:"jiro@change".to_string()}, ]; let tera = tera::Tera::new("template/*").unwrap(); let mut context = tera::Context::new(); context.insert("title", "Index page"); context.insert("data", &data); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) }
view
<ul class="list-group"> {% for item in data %} <li class="list-group-item"> {{item.name}} <{{item.mail}}> </li> {% endfor %} </ul>
### キー&バリューのコレクション
マップにHashMapインスタンスを代入。このHashMapをテンプレート側で処理する
async fn handle_index()-> axum::response::Html<String> { let mut map = std::collections::HashMap::new(); map.insert("taro", ("taro@yamada", 39)); map.insert("hanako", ("hanako@flower", 28)); map.insert("sachiko", ("sachiko@happy", 17)); let tera = tera::Tera::new("template/*").unwrap(); let mut context = tera::Context::new(); context.insert("title", "Index page"); context.insert("data", &map); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) }
<ul class="list-group"> {% for key, value in data %} <li class="list-group-item"> [{{loop.index}}] {{ key }}({{value.1}}) <{{value.0}}> </li> {% endfor %} </ul>
loop.indexは繰り返し情報がまとめられたオブジェクト
### フィルターの利用
フィルターは、あらかじめRust側で定義した関数を使ってテンプレートの表示を変換する機能
フィルター用の関数は形が決まっている
fn 関数(引数1: &value, 引数2: &HashMap
作成したフィルター関数はTeraのインスタンスに登録する
main.rs
async fn handle_index()-> axum::response::Html<String> { let mut tera = tera::Tera::new("template/*").unwrap(); tera.register_filter("hello", hello_filter); let mut context = tera::Context::new(); context.insert("title", "Index page"); context.insert("name", "山田タロー"); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) } fn hello_filter(value: &tera::Value, _: &std::collections::HashMap<String, tera::Value>) -> tera::Result<tera::Value> { let s = tera::try_get_value!("hello_filter", "value", String, value); Ok(tera::Value::String(format!("こんにちは、{}さん!", s))) }
テンプレート
<div class="alert alert-primary"> <p class="my-2">{{ name | hello}}</p> </div>
### フィルターでオブジェクトを扱う場合
async fn handle_index()-> axum::response::Html<String> { let mut tera = tera::Tera::new("template/*").unwrap(); tera.register_filter("sample", sample_filter); let mut context = tera::Context::new(); context.insert("title", "Index page"); context.insert("id", &1); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) } fn sample_filter(value: &tera::Value, _: &std::collections::HashMap<String, tera::Value>) -> tera::Result<tera::Value> { let data = [ ("taro", "taro@yamada", 39, "male"), ("hanako", "hanako@flower", 28, "female"), ("sachiko", "sachiko@happy", 17, "female"), ("jiro", "jiro@change", 6, "male") ]; let n = tera::try_get_value!("sample_filter", "value", usize, value); let item = data[n]; Ok(tera::Value::String(format!("{}({},{})<{}>", item.0, item.3, item.2, item.1))) }
### フィルターの属性を利用する
async fn handle_index()-> axum::response::Html<String> { let mut tera = tera::Tera::new("template/*").unwrap(); tera.register_filter("calc", calc_filter); let mut context = tera::Context::new(); context.insert("title", "Index page"); let output = tera.render("index.html", &context); axum::response::Html(output.unwrap()) } fn calc_filter(_: &tera::Value, map: &std::collections::HashMap<String, tera::Value>) -> tera::Result<tera::Value> { let price = map.get("price").unwrap().as_f64().unwrap(); let tax = map.get("tax").unwrap().as_f64().unwrap(); let res = price * tax; Ok(tera::Value::String(format!("price:{} * tax:{} = {}", price, tax, res))) }
<div class="alert alert-primary"> <p class="my-2">{{ false | calc(price=1234, tax=1.1) }}</p> </div>