-
-
Notifications
You must be signed in to change notification settings - Fork 78
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: Render Block fragment #260
Comments
In some sense what you want to accomplish is already supported internally. When a template extends another one, it basically needs to find all the blocks. I did not think too much about the details yet, but it should be doable with the current semantics of the language. I did not think this would require any special code other than maybe rethinking how Today if This would definitely require some minor refactoring, but it should not require you to do anything fancy that the engine doesn't already have to do in one form or another.
I think I would prefer an explicit |
This is really useful with htmx. Thank you for implementing it! |
Note that I changed the interface for block rendering significantly on |
I gave v1.0.0-alpha.2 a try, and my usage of blocks went from: let rendered = template.render_block(block, context)?; To: let rendered = template.eval_to_state(context)?.render_block(block)?; Works for me. I have no strong feelings about the change as a user; it's not a problem for my usage of blocks. |
I have noticed one ergonomic issue with blocks (unrelated to v1.0). Say I have a template like this:
And I attempt to render only let rendered = tmpl.eval_to_state(context!(baz => "baz"))?.render_block("baz_block")?; That blows up with the following error:
Ideally this would succeed, because I only want to render I can raise an issue if you think this is a legitimate problem. |
Currently it works by evaluating the entire template with your context before rendering out block, so things like inheritance work correctly. It might be possible to fix, I'm not sure how important it is to know if an expression will fail during the eval-only stage (if there's some possible side-effects there I'm not aware of, or if it can even be skipped), and just pass that onto the actual render eval. There is also the less ideal temporary solution of using Feel free to make a new issue for it! |
In essence, this feature would allow you to render only a block from a template. This is great in the context of htmx where you typically want to just re-render a small section of html to send down the wire
(See https://htmx.org/essays/template-fragments/ and https://github.com/sponsfreixes/jinja2-fragments).
Example:
If I ran
template.render_block("myblock", &ctx)
, I would getMy current implementation of this feature adds a
render_block
method, but it's quite a bodge since it uses the pre-compiled blocks already part of the template. They are also missing all the necessary block instructions, so things likesuper()
don't work.Before I make a PR with some of the proposed changes below, I have some questions about the design of it:
super()
, compiling block fragments would need to be supported at the compiler level (and/or right above it inSource
). Assuming I just want to render the block with all the necessary instructions, what instructions could sensibly be stripped? EmitRaw seems like an obvious one, but I'm not super familiar with it all.render_block
bodge method, I think it may be a better idea for Source to use some kind of syntax liketemplate.html#block
(suggested by the article) and just have users render normally. This way, it is supported by default out of the box without any additional API on templates, and Source can deal with compiling and caching the block fragments. What do you think?I'd love to hear your thoughts. In any case, thanks for the great library!
The text was updated successfully, but these errors were encountered: