#web #web-page #ssr #template #salvo #server-side #tera

simple-ssr-rs

简单的服务器端静态网页渲染器

20 个版本

0.2.2 2024 年 5 月 14 日
0.2.0 2024 年 4 月 7 日
0.1.613 2023 年 11 月 7 日
0.1.610 2023 年 7 月 20 日

#145模板引擎

MIT/Apache

23KB
493

use std::collections::HashMap;

use simple_ssr_rs::{SSRender,ssr_work,Value};

use simple_ssr_rs::salvo::{self,prelude::*};

// Extend router
struct Hello(TeraBuilder);
#[handler]
impl Hello{
  async fn handle(&self, req: &mut Request, _depot: &mut Depot, res: &mut Response){
      //let mut ctx = Context::default();
      // let ctx = self.0.gen_context(req);
      // match self.0.build(ctx.clone()){
      //   Ok((tera,ctx))=>{
      //     let r = tera.render("index.html", &ctx).unwrap_or("".to_owned());
      //     let _ = res.add_header("server", "xfinal", true);
      //     res.render(Text::Html(r));
      //   }
      //   Err(_)=>{
      //     res.render(Text::Plain("Error"));
      //   }
      // }
      res.render(Text::Plain("Hello"));
  }
}

#[handler]
async fn handle404(&self, _req: &Request, _depot: &Depot, res: &mut Response, ctrl: &mut FlowCtrl) {
    if let Some(StatusCode::NOT_FOUND) = res.status_code {
        res.render("Custom 404 Error Page");
        ctrl.skip_rest();
    }
}

fn main() {
   let mut ssr = SSRender::new("0.0.0.0:8080");
   ssr.set_pub_dir_name("assets");  // specify the name of the public assets directory in the current root directory
   ssr.set_tmpl_dir_name("pages");  // specify the name of the template directory in the current root directory
  // ssr.set_meta_info_collector(|req:&Request|->HashMap<String, Value>{}); // get meta data from the current request for the tempalte
   ssr.register_function("println".to_owned(), |v:&HashMap<String, Value>|{  // register a function that can be used in template files
	  let r = v.get("value").ok_or("none")?.as_str().ok_or("none")?;
	  Ok(Value::String(format!("<p>{r}</p><br/>")))
   });
   ssr.set_ctx_generator(|_req:&Request|->HashMap<String, Value>{  // collect infomation from the current request, these objects can be used in the templates
      let mut map = HashMap::new();
      map.insert("info".to_owned(), Value::Bool(true));
      map
   });
   // ssr.set_hook_view_path(Some(|req,path|{ path})); // modify the path before rendering it by view-engine
   //let router = Router::with_path("base");  // root path
   //let router = router.push(Router::with_path("hello").get(Hello(ssr.gen_tera_builder())));
   // ssr_work!(ssr,router);
   // ssr_work!(ssr,None,Catcher::default().hoop(handle404));
   // ssr_work!(ssr,router,Catcher::default().hoop(handle404));
   ssr_work!(ssr);
}

使用内置函数

<!-- 
	/pages/common/abc.html
	<h3>{{context.title}}</h3>
   <div>{{parent.info}}</div>  we can access the variable in the parent scope by using __Parent.info(if any), and so forth, __Parent...__Parent.info 
-->
<!-- the common directory is in the root path `pages`, the following content is in the index.html -->
<div>
	{{ include_file(path="common/abc.html"), context=`{"title":"abc"}` | safe }}
</div>

然后我们可以在浏览器中访问网站: https://127.0.0.1:8080/https://127.0.0.1:8080/index.html。在浏览器中访问静态资源: https://127.0.0.1:8080/assets/filename

有关如何使用模板引擎的更多详细信息,请参阅 Tera 的主页。

依赖项

~24–40MB
~728K SLoC