Skip to content
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

Feature: ability to render .html file updates without rebuilding? #425

Open
seenickcode opened this issue Jan 3, 2021 · 12 comments
Open

Comments

@seenickcode
Copy link

I understand that Askama uses compiled templates but maybe is there a way to have a debug mode that renders the template when the page is loaded?

@djc
Copy link
Collaborator

djc commented Jan 3, 2021

There is currently not. Askama is really two things: a parser for a template language to an AST, and a code generator that transpiles the AST to Rust code. I'd be open to some other "backend" for the AST (maybe one that recasts the Askama AST as Tera AST, or some other dynamic template engine), but it's a relatively large undertaking which I probably won't prioritize in the near future unless someone wants to pay for the efforts.

@djc
Copy link
Collaborator

djc commented Jan 3, 2021

What's the use case, BTW? Just the compile time benefits, or actual "dynamic" usage, something else?

Another approach could be to run the Askama-generated Rust code through a JIT compiler or interpreter at run-time, but I'm not aware of any efforts in this direction (other than Miri, but it has a very different use case).

@seenickcode
Copy link
Author

In short, I'm looking for a faster dev workflow, than "update .html file (askama template)", stop server, cargo build, cargo run.

I absolutely love it that templates are compiled and you get the checks that come out of that (something that Go Templates do not have out of the box at least). But OTHO I'm seeking a more convenient way of doing Askama + Rust dev.

(Context: I'm re-writing fluttercrashcourse.com, which is effectively a bespoke ecommerce application written in Vue/Nuxt + Go into Rust + actix-web + Askama. Going excellent thus far btw with Askama, and I'm even brand new to Rust).

@djc
Copy link
Collaborator

djc commented Jan 4, 2021

Fair enough. I'm not even sure the interpreting approach could work short of something that can interpret Rust -- I think it would require "flattening" context types into something easier to use dynamically. So this is definitely a bunch of work.

Another approach that might work is to write templates that also work in Tera, I guess -- we would likely accept patches that would make this kind of thing easier.

@vallentin
Copy link
Collaborator

I'd definitely be up for an interpreter, to be able to dynamically render templates. However, I immediately see two issue.

  1. As soon as you attempt to use e.g. Rust functions, then that becomes and issue and would (sometimes) require rebuilding. In short, if you did {{ f32::sqrt(9.0) }}, then you'd be able to use sqrt as long as the type is f32, as Askama could generate a v-table of function used at compile-time. However, if you then try to do e.g. {{ f32::cbrt(27.0) }}, then cbrt wouldn't be found in the v-table. So what should happen then? Ultimately that would then require a rebuild, so cbrt is included in the v-table.

  2. The second issue is that Askama doesn't know what types fields, variables, constants, etc are. It might be possible to obtain types for the template's fields. However, obtaining types from anything outside the template struct, not to mention function signatures, is going to require some next to impossible introspection.

So as long as a template doesn't use any Rust functions, Then it might be feasible to create interpreter.

@djc
Copy link
Collaborator

djc commented Jan 5, 2021

I don't think it makes much sense to have an interpreter if it can only handle a smallish subset of what the Askama compiler supports.

@itsfarseen
Copy link

Being able to avoid recompilation for changes only in static html content would be really nice.
For example:

<div>
    {% if flag %}
    <div>Foobar</div>
    {% endif %}
<div>

to

<div class="foobar">
    <div>Foobar?</div>
    {% if flag %}
    <div class="foobarbaz">Foobar baz</div>
    {% endif %}
<div>

@cipriancraciun
Copy link
Contributor

In short, I'm looking for a faster dev workflow, than "update .html file (askama template)", stop server, cargo build, cargo run.

@seenickcode If faster development cycle is what you are after, this is how I've solved on my end:

  • (optional) I have a custom script (bash or whatever) that does the cargo build and whatever is required to run the server (always exec my-server-executable at the end to get rid of the bash process);
  • I use watchexec (also available as a cargo plugin) so that when the source code changes (not only templates) it restarts my server (by using the previous mentioned script); (however you can use the cargo plugin in a simple command);
  • (optional) I use catflap to keep any pending HTTP requests (while the code rebuilds and the server restarts) from erroring;
  • I have a custom URL that returns a random token, one generated at the start of the server;
  • I have a custom JS snippet injected in my HTML (when in debug mode) that checks the mentioned URL for a current token; if the observed token changes, it reloads the current page; (the script is available at https://github.com/console9/hyper-static-server/blob/master/sources/reload.js)
  • (optional) in order to improve build times, I keep the templates and the logic in separate lib crates, and have a bin server crate that just combines the two; (this should reduce the rebuild time somewhat;)

The links to watchexec and catflap:

@seenickcode
Copy link
Author

seenickcode commented Aug 4, 2021 via email

@djc
Copy link
Collaborator

djc commented Oct 2, 2023

See also the performance tips in the book: https://djc.github.io/askama/performance.html. Now that we've split the askama_parser crate out of askama_derive, you'd want to do the same thing for askama_parser. Note also that parsing should have gotten a bunch faster with the latest askama_derive 0.12.2 release (mainly from #833).

@djc
Copy link
Collaborator

djc commented Jan 10, 2024

Folks interested in this issue might like @rdbo's dynja, which uses minijinja for the debug profile and Askama for the release profile.

@RafaelKr
Copy link

RafaelKr commented Jan 22, 2024

Maybe this article could be helpful to get real hot reloading implemented (even without restart of the server):
https://robert.kra.hn/posts/hot-reloading-rust/

Edit: I'm not sure if it works when creating new templates, but it could work for editing templates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

6 participants