-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Access tera context from functions code #543
Comments
It's something that would be nice but is a breaking change. Probably for the next version. |
A similar issue comes up with URLs in There is a
|
I don't know about |
@Keats If I read that right, you still have to pass the lang argument to the function, right? Here's one way to do what I want right now, with pre-generating the URLs and passing them inside the template as strings. (ResourceMap is part of HttpRequest, so it's accessed through the request) #[get("/show-page")]
pub(crate) async fn show_page(request : HttpRequest, session : Session) -> actix_web::Result<impl Responder> {
let mut context = tera::Context::new();
let delete_url = request.url_for("record", &["123", "delete"])?;
context.insert("delete_url", &delete_url.to_string());
let html = TERA.render("page", &context).map_err(|e| {
actix_web::error::ErrorInternalServerError(e)
})?;
Ok(HttpResponse::Ok().body(html))
} then I can use Ideally, I could use something like this in the template: |
Yes. Passing the context automatically is going to be a feature of Tera 2.0, but it hasn't started yet.
That sounds like this URL resolver doesn't need to be at the request level and it could exist when you're declaring the actix routes right? How would you generate the routes in a test for example? If the URL mapping is available in the actix |
I'm still exploring actix-web, so I may have missed something. If the routes were known ahead, then yeah your solution works fine Here's how the app is started: use once_cell::sync::Lazy;
pub(crate) static TERA : Lazy<Tera> = Lazy::new(|| {
let mut tera = Tera::default();
tera.add_include_dir_templates(&TEMPLATES); // my extension to add files from include_dir!
tera
});
#[actix_web::main]
async fn main() -> std::io::Result<()> {
simple_logging::log_to_stderr(LevelFilter::Debug);
// Ensure the lazy ref is initialized early (to catch template bugs at startup)
let _ = TERA.deref();
let yopa_store: YopaStoreWrapper = init_yopa();
let mut session_key = [0u8; 32];
rand::thread_rng().fill(&mut session_key);
HttpServer::new(move || {
// If I understand this right, the closure runs for every started worker thread.
// Tera could be initialized here for every thread, but we still don't know the URLs
let static_files = StaticFiles::new("/static", included_static_files())
.do_not_resolve_defaults();
// This creates a "Service Factory". The URLs can't be read from it at this point
App::new()
/* Bind shared objects */
.app_data(yopa_store.clone())
/* Routes */
.service(routes::index) // URL is read from the attribute macro by actix procgen (?)
.service(static_files)
.default_service(web::to(|| HttpResponse::NotFound().body("Not found")))
})
.bind("127.0.0.1:8080")?
.run().await
} |
I have a use case for modifying the context during a global function. Is there any willingness to support a function call structure that takes a |
I would say no |
Hi!
I have a situation, where it would be useful to have a global variable in the functions. I faced it when working with translations / localization using fluent.
Basically on the rust side I have something like this:
And then in the template code I have
e.t.c.
It works, but I have to put
lang
argument every time, which is a bit verbose for my taste.The only solution that we have for now is to modify
translate
function in the rust code, so it will capture alang
variable.The problem is that
Function
trait is required to beSend + Sync
.So, we need to use an external variable and the synchronization for this. Synchronization will mean, that we can not render templates on web server in parallel. Because each client needs different value of the global variable. (for example different languages).
Can't we pass reference to Context inside each function? This mean that lambdas that we use in
register_function
in addition to HashMap with arguments also accepts&Context
reference. Then I can know value of "LANG" inside translate implementation. This value will be specific to eachrender()
call and can work in parallel.The text was updated successfully, but these errors were encountered: