-
Notifications
You must be signed in to change notification settings - Fork 301
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
add Context-scoped functions #656
Comments
Wait the |
TBH, I have no idea about any possible internals of 2.0? But seeing the If a Another possibility might be to take a leaf out of Lua's book and extend |
The only part written so far is the parser and the rest might get rewritten from scratch, especially if it uses valuable. It's kind of hard to cover all the bases, so far I was not aware of the mlua approach that seems pretty nice. |
Would it be possible to include this addition? It might be able to tide people over until there is a next major version. (And maybe relieve some pressure there?) And it seems to be the minimally viable solution, anything more sophisticated needs proper lifetimes everywhere. I'd be happy to do any necessary changes/cleanup/etc. |
Can you do a PR so I can review the code easily? |
Implemented a scoped Context for good measure, see at https://github.com/moschroe/tera/tree/feature_context-lifetime. This allows a closure to capture simple references, enabling the use of truly ephemeral data in templates without reference counting, wrappers, etc. |
I came here looking for this feature too, but I'm surprised by the implementation. It sounds like you must call Thank you for your work on this template library btw! |
For @moschroe case, it seems the url mapping is on the request for some reason so doing it once at app init time wouldn't work afaik |
@pjungwir Firstly, if the thing I want to use within a template does not exist when initializing tera, there is logically no way to bind it. As keats already pointed out, with actix-web, creating a URL can depend on the request, so there is no global/static way to do it. Thus, only when I handle a request and want to render the template, the struct I need is available (and neither Secondly, remember in rust a closure is sugar for static code (maybe specialized for generics) and the only dynamic thing: A struct with the captured values. So as long as preparing this struct is cheap (and cloning an |
Thank you both for taking the time to answer. I understand that the request is not available up front. I'm saying just as the existing PR adds a new kind of function, so we could also/alternately add a new kind of function that takes a Context object as a second parameter (besides the HashMap that custom functions already receive). So it's just a different way to pass the context when the function is called, but without using a closure (and also without needing to register the function repeatedly in each request that might use it). It's good to know that building the closures is relatively inexpensive. I still think just passing the Context to custom functions would be even cheaper, and also less complicated for people defining those functions. |
FWIW: My own concrete use case also depends on request-specific data: I'm writing a function that takes a localization key and zero or more extra parameters, and it uses the current user's preferred language to look up the localized message. I can pass the language each time I call the function, but that gets tedious & noisy, so I'd rather have the function look it up implicitly. If Tera passed me the context I wouldn't need to write |
This is annoying me as well in Zola, I'll probably pass the context in some way to functions & filters for V2 |
I use tera in an actix-web project and wanted to expose the
url_for
method ofHttpRequest
to the template.The template engine is initialised globally, and so are its registered functions.
url_for
is specific to the request instance. And the latter is neitherSerialisable
norSend
norSync
.I managed to introduce functions local to a
Context
. I had to create a separate trait that does not requireSend+Sync
(in my use case, theHttpRequest
contains anRc
, which is neither). I had to add plumbing to theCallstack
. TheProcessor
was modified so that a Context-local function will shadow a global one.For all the changes, see: moschroe@c613ad7
An example using these modifications might look like this:
Would this be feasible as a stop-gap solution until 2.0 allows other work-arounds? Shall I open a PR?
The text was updated successfully, but these errors were encountered: