solid/
lib.rs

1mod template_utils;
2
3use actix_files::NamedFile;
4use actix_web::{HttpRequest, HttpResponse};
5use actix_web::http::StatusCode;
6use serde_json::{Value};
7use crate::template_utils::{ TEMPLATES, DEFAULT_TEMPLATE, to_template_name};
8use tera::Context;
9
10
11pub async fn render_views(req: HttpRequest, data: Value) -> HttpResponse {
12    let path = req.path();
13    let mut context = Context::new();
14    for entries in data.as_object().into_iter() {
15        for (key, value) in entries.into_iter() {
16            context.insert(key, value);
17        }
18    }
19    
20
21    #[cfg(debug_assertions)]
22    if path.eq("/__vite_ping") {
23        println!("The vite dev server seems to be down...");
24        return HttpResponse::NotFound().finish();
25    }
26
27    let template_path = to_template_name(req.path());
28    let mut content_result = TEMPLATES.render(template_path, &context);
29
30    println!("{:?}", content_result.as_ref().err());
31    if content_result.is_err() {
32
33        #[cfg(debug_assertions)] {
34            // dev asset serving
35            let asset_path = &format!("./resources{path}");
36            if std::path::PathBuf::from(asset_path).is_file() {            
37                return NamedFile::open(asset_path).unwrap().into_response(&req)
38            }
39
40            let public_path = &format!("./public{path}");
41            if std::path::PathBuf::from(public_path).is_file() {
42                return NamedFile::open(public_path).unwrap().into_response(&req)
43            }
44        }
45
46        #[cfg(not(debug_assertions))] {
47            // production asset serving
48            let static_path = &format!("./public{path}");
49            if std::path::PathBuf::from(static_path).is_file() {
50                return NamedFile::open(static_path).unwrap().into_response(&req);
51            }
52        }
53        content_result = TEMPLATES.render(DEFAULT_TEMPLATE, &context);
54        if content_result.is_err() {
55            // default template doesn't exist -- return 404 not found
56            return HttpResponse::NotFound().finish()
57        }
58    }
59
60    let content = content_result.unwrap();
61
62    template_response(content)
63}
64
65fn template_response(content: String) -> HttpResponse {
66    let mut content = content;
67    #[cfg(debug_assertions)] {
68        let inject: &str = r##"
69        <!-- development mode -->
70        <script type="module" src="http://localhost:3000/@vite/client"></script>
71        "##;
72
73        if content.contains("<body>") {
74            content = content.replace("<body>", &format!("<body>{inject}"));
75        } else {
76            content = format!("{inject}{content}");
77        }
78    }
79
80    HttpResponse::build(StatusCode::OK)
81        .content_type("text/html")
82        .body(content)
83}