/ src / initializers / view_engine.rs
view_engine.rs
 1  use async_trait::async_trait;
 2  use axum::{Extension, Router as AxumRouter};
 3  use fluent_templates::{ArcLoader, FluentLoader};
 4  use loco_rs::{
 5      app::{AppContext, Initializer},
 6      controller::views::{engines, ViewEngine},
 7      Error, Result,
 8  };
 9  use tracing::info;
10  
11  const I18N_DIR: &str = "assets/i18n";
12  const I18N_SHARED: &str = "assets/i18n/shared.ftl";
13  #[allow(clippy::module_name_repetitions)]
14  pub struct ViewEngineInitializer;
15  
16  #[async_trait]
17  impl Initializer for ViewEngineInitializer {
18      fn name(&self) -> String {
19          "view-engine".to_string()
20      }
21  
22      async fn after_routes(&self, router: AxumRouter, _ctx: &AppContext) -> Result<AxumRouter> {
23          #[allow(unused_mut)]
24          let mut tera_engine = engines::TeraView::build()?;
25          if std::path::Path::new(I18N_DIR).exists() {
26              let arc = ArcLoader::builder(&I18N_DIR, unic_langid::langid!("en-US"))
27                  .shared_resources(Some(&[I18N_SHARED.into()]))
28                  .customize(|bundle| bundle.set_use_isolating(false))
29                  .build()
30                  .map_err(|e| Error::string(&e.to_string()))?;
31              #[cfg(debug_assertions)]
32              tera_engine
33                  .tera
34                  .lock()
35                  .expect("lock")
36                  .engine.register_function("t", FluentLoader::new(arc));
37  
38              #[cfg(not(debug_assertions))]
39              tera_engine
40                  .tera
41                  .register_function("t", FluentLoader::new(arc));
42              info!("locales loaded");
43          }
44  
45          Ok(router.layer(Extension(ViewEngine::from(tera_engine))))
46      }
47  }