You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
We have several routes that return partial HTML for the main "content" part of a web page.
We want to wrap this content in a top navbar that shows the currently logged in user's name.
We only want to include this navbar if the "Hx-Request" HTTP header is not set (i.e. if we're doing a full page request instead of a partial HTMX request).
Displaying the username requires fetching the user from the DB.
Current solutions to this problem requires lots of code duplication and mixing of concerns:
We'd have to fetch the user in each route. While we can do this with an extractor it still puts the responsibility of the work on a part of the code that shouldn't care about it.
All our templates need to accept this user object and pass it to some parent template* (e.g. in Askama we'd have some parent template that we would extends with our per-route template).
A better solution would have to put the logic for adding the navbar in one place. It could look something like this:
let app = Router::new().route("/foo",get(...)).route("/bar",get(...)).layer(layout::new());pubasyncfnlayout(user:LoggedInUser,// get the user somehowHxRequest(partial):HxRequest// check if the Hx-Request header is set
response:R// from the route *before* it gets turned into a Response) -> Result<R,E>whereR:HtmlTemplate + Send + Sync// this middleware only works for HtmlTemplateE:Error{// LayoutTemplate expects an argument of type `HtmlTemplate`render(LayoutTemplate{content: response })}
For this to work the middleware needs to receive the concrete return type R from the route, not something that's already converted into a Response. (While working on the response might work in some simple cases it doesn't in general).
I think having a concept of a pre-response middleware is generally useful. Of course it doesn't always apply and has some limitations (e.g. it might be harder to stream some response types).
* This is a problem with templating in general. It's "inside out", having the child having to care about the parent's data needs. In other words, templating composes poorly.
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
-
Imagine the following scenario:
Current solutions to this problem requires lots of code duplication and mixing of concerns:
extends
with our per-route template).A better solution would have to put the logic for adding the navbar in one place. It could look something like this:
For this to work the middleware needs to receive the concrete return type
R
from the route, not something that's already converted into aResponse
. (While working on the response might work in some simple cases it doesn't in general).I think having a concept of a pre-response middleware is generally useful. Of course it doesn't always apply and has some limitations (e.g. it might be harder to stream some response types).
* This is a problem with templating in general. It's "inside out", having the child having to care about the parent's data needs. In other words, templating composes poorly.
Beta Was this translation helpful? Give feedback.
All reactions