-
Rust: actix-rs에서 HTML tera 엔진 렌더링컴퓨터/Rust 2022. 6. 24. 11:24728x90반응형
actix-rs
소개
이 글에선 Python django 처럼
HTML 엔진을 이용해서 코드를 HTML에 inject 해볼 것이다.
최종 결과로는 Vec<Review>를 HTML에 넣어서 다음과 같이 나온다.
코드
Tera 템플릿 엔진을 사용할 것이다.
Cargo.toml
[dependencies] actix-rt = "2" # 웹 서버 열기 actix-http = "3" # 웹 서버 열기 actix-web = "4" # 웹 서버 열기 serde = { version = "1.0", features = ["derive"] } # JSON serde_json = "1.0" # JSON serde_derive = "1.0" # JSON futures = "0.3" # 비동기 support tera = "1.16.0" # 웹 홈페이지 tera template
review.html
reviews에 Rust Vec<Review>가 들어간다.
<main> <section> {% for review in reviews %} <div class="review review-left"> <div class="name">{{ review.writer }}</div> <div class="rating score"> <span class="star"> ★★★★★ <span style="width: {{ review.rate * 10 }}%">★★★★★</span> <input id="star_rate" type="range" value="1" step="1" min="0" max="10" name="rate_param" /> </span> <div class="content">{{ review.review_txt }}</div> </div> </div> {% endfor %} </section> </main>
main.rs
actix.app_data를 이용해서 global하게 사용한다.
use actix_web::middleware::{Compress, Logger, NormalizePath}; use actix_web::{web, App, HttpServer}; use std::sync::Mutex; use tera::{Context, Tera}; #[actix_web::main] async fn main() -> std::io::Result<()> { let tera = web::Data::new(Mutex::new( Tera::new(concat!(env!("CARGO_MANIFEST_DIR"), "/templates/**/*.html")).unwrap(), )); // 테라 global // 서버 실행 HttpServer::new(move || { App::new() .app_data(tera.clone()) // 미들웨어 .wrap(Compress::default()) .wrap(NormalizePath::default()) .wrap(Logger::default()) // 홈페이지 .service(backend::review::review_html) // review get 함수 }) .bind(backend::SERVER)? .run() .await }
review.rs
GET/POST 엔드 포인트 함수에 tera로 렌더링 한다.
html에 원하는 이름에 알맞게 데이터를 넣는다. (De/Serializable 가능해야 함)
use serde::{Deserialize, Serialize}; use tera::{Context, Tera}; #[derive(Debug, Default, Serialize, Deserialize)] pub struct Review { pub writer: String, pub review_txt: String, pub rate: u8, } impl Review { pub fn new() -> Self { Default::default() } } #[get("/review/{food}")] async fn review_html( tera: web::Data<Mutex<Tera>>, food: web::Path<String>, ) -> impl Responder { println!("=> 리뷰 페이지"); let food_name = food.into_inner(); let mut reviews: Vec<Review> = DB에서 메뉴에 맞는 모든 Review 불러오기(food_name.to_string()); reviews.reverse(); // 최신 리뷰순 let mut ctx = Context::new(); ctx.insert("reviews", &reviews); // html에 reviews에 Rust reviews 넘김 // println!("{:?}", ctx); let tera = tera.lock().unwrap(); let rendered = tera.render("review.html", &ctx).unwrap(); // review.html 렌더링 HttpResponse::Ok().content_type("text/html").body(rendered) }
728x90'컴퓨터 > Rust' 카테고리의 다른 글
Windows: 저장된 WIFI 와이파이 비밀번호 보기 (0) 2022.08.10 Rust: Cross compile for Raspberry PI (0) 2022.06.24 Rust fleet (cargo 대체 빌드 툴) (0) 2022.05.04