Altair-Bueno / axum-template

Layers, extractors and template engine wrappers for axum based Web MVC applications
https://crates.io/crates/axum-template
MIT License
78 stars 6 forks source link

Use Tera Context for data instead of struct #34

Closed EraYaN closed 1 year ago

EraYaN commented 1 year ago

Would it be possible to enable RenderHtml to accept the Tera Context instead of a struct? Some handlers might need to return RenderHtml with different templates (and thus different Models) and as far an I can see that won't work.

Altair-Bueno commented 1 year ago

I don't fully understand your question. Could you please provide an example of what you are trying to accomplish?

Some handlers might need to return RenderHtml with different templates (and thus different Models) and as far an I can see that won't work.

fn foo(engine: AppEngine) -> impl IntoResponse {
  // Won't compile because `if` and `else` have incompatible types
  if rand::random() {
    RenderHtml("one", engine, &data1)
  } else {
    RenderHtml("two", engine, &data2)
  }
}
fn foo(engine: AppEngine) -> Response {
  if rand::random() {
    RenderHtml("one", engine, &data1).into_response()
  } else {
    RenderHtml("two", engine, &data2).into_response()
  }
}
EraYaN commented 1 year ago
use tera::Context;

let mut context = Context::new();

context.insert("item", &item);

return RenderHtml("one", engine, &context)

This allows to use RenderHtml calls (in an if for example) in the same handler with different context variables.

Altair-Bueno commented 1 year ago

Context is nothing but a wrapper around serde_json::Value, which implements serializable. You can transform into the inner type by using into_json

However I would suggest you do not use tera::Context but rather serde_json::Value or similar, as it would lock your application to tera and wouldn't allow for an easy engine switch if you later decide so. The idea behind axum-template is to simplify template usage no matter the engine used, similar to spring web and other frameworks, without locking in to certain conventions.

EraYaN commented 1 year ago

Aah I didn't know I could potentially use serde_json::Value, I was just playing with some speedtests and it needed to return a 404 with a different model. But I'll look into adding this crate back in. I'll close this for now.

Altair-Bueno commented 1 year ago

it needed to return a 404 with a different model

In that case you could also return a Result::Err with said error. Result impl IntoResponse

Err((StatusCode::NOT_FOUND,RenderHtml("notfound",engine,data)))