Replies: 3 comments
-
I think that the internal implementation you outlined in the first proposed design makes the most sense. I think utilizing context makes sense here too, but I don't think that this fact should be exposed to the user, I would recommend an abstraction here: func RenderFragment(ctx context.Context, c Component, w io.Writer, name string) error {
return c.Render(WithFragment(ctx, w, name), io.Discard)
} This way the dev experience is a bit more intuitive: http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
if r.Method == http.MethodPost {
count++
}
c := Page(count)
if r.Method == http.MethodPost && r.Header.Get("HX-Request") == "true" {
templ.RenderFragment(r.Context(), c, w, "count")
return
}
c.Render(r.Context(), w)
}) |
Beta Was this translation helpful? Give feedback.
-
I have another approach. It treats the component (fragment, partial) like an endpoint (/partial/{component-id}, which has its states depending on the HTTP method used. I can return the rendered html by passing data in the template (initial GET state based on URL), or in the endpoint. Example: take a look at how the navigation works in the mobile version for hanariu.dev - there is an animation like in the SPA app (no page reload effect) because it loads the fragment (endpoint) thanks to HTMX. This has three main advantages for me:
For small components and changing only data, HTMX alone + e.g. Alpine js is enough. |
Beta Was this translation helpful? Give feedback.
-
Was about to write an issue myself and I would really like to weigh in on this, because in my opinion, templ and HTMX go together extremely nicely. For a tiny bit of context, I am visually impaired and try to work as little in the actual frontend as possible, so doing as much as I can in the backend (where I can be far removed from JavaScript land...oofh...the memories x)...) is nice. I am currently planning a continuation of an old application that I had written in PHP 5.3 and Yii 1.x - that was software from 2012-ish and then some (that is when I discovered git and actually logged stuff, hence why I know). Now these days, htmx and templ can do what PHP back then never could and something React kinda "can't": It can streamline stuff a lot. With htmx, you are just writing HTML and with Templ, you are just calling Go functions that happen to return HTML. React needs JSX, which needs a truckload of additional software and other stuff. Not to hate on it, by the way - I actually enjoy JSX for what it is and what it can do. But the templ + htmx way just seems easier...nicer, even. One of the most prevalent features of my app back then was creating roleplay characters with detailed showcase pages. But by that point Yii got to render this particular part, it had rendered a menu, a side panel, a footer, some CSS and spliced JavaScript here and there. If something on that character profile changed, the user would have to reload the whole thing. But what if instead it was just tracking some smol stream from the backend that told the user, hey, your character got invited to join this clan/club...I wouldn't want to render any of the other components, and htmx highly discourages it too. So, for demonstration purposes, let's assume this; any tag with a capital letter is "a thing" and not actually HTML. I am a little lazy here, apologies. <!DOCTYPE html>
<html>
<head>
<!-- ... -->
</head>
<body>
<MenuBar/>
<Sidebar>
<UserStatistics/>
<RecentPosts/>
<NewsFeed/>
</Sidebar>
<div id="content"></div>
<Footer>
<Socials/>
<Copyright/>
<ProbablyMoreThatIForgot/>
</Footer>
</body>
</html> Only Currently, there is one approach I have considered doing but... I will probably just not.
This still means that if "Fragment drilling" would go a long way in my opinion. I am not sure what the best way there is but if I could just write something like templ Profile(characterId int) {
@Fragment("profile") {
@Fragment("bio") {}
@Fragment("images") {}
}
@fragment("relations") {
@Fragment("invites") {}
@Fragment("graph") {}
}
} ...and then just do something like Really looking forward if and when this will land because I think htmx and templ can go a long, long way! =) For the time being I'll just render everything and try to if/else my way out of sticky situations ^^" |
Beta Was this translation helpful? Give feedback.
-
In this tweet, Carson highlights the capability of Laravel's template engine to render a specific section of an overall template. https://x.com/htmx_org/status/1833450920438272462
This is interesting for HTMX, because with HTMX, you sometimes only want a part of the HTML stream to be returned to the client.
In templ, this could look like:
At the moment, you'd have to make a separate templ component for that:
And then call it - works well, but have to do some refactoring if you're adding this to existing code.
To write out only the fragment without separating the contents into another templ component, the
context
could be used to trigger the behaviour.In this example, the GET request returns the whole page:
But the HTMX response returns just the "count" fragment.
I don't like how this design doesn't use the
io.Writer
that's passed in, using a writer from the context instead, but it does work.That design is partly because that's all that's possible with the current generated code.
templ's generator currently generates code that creates a buffer from the incoming
io.Writer
, but I'm not sure it should. Maybe this would be better done at the HTTP handler level, and we keep the rendering code really simple.If we didn't wrap it, we could check (within the
Fragment
templ component) to see whether theio.Writer
is actually aFragmentWriter
that only writes the specified fragments and its children, discarding all other writes.Alternatively, the templ
runtime.Buffer
type could have this smartness built in.All of the template is computed, it's simply that only part of the HTML output is returned. I don't think that it's possible (or maybe desirable) to skip computing non-visible parts of the template.
Another design might be even simpler (just pseudocode for now), writing out a comment to start and the fragment.
Then, a custom writer could discard writes that aren't between the expected comments. templ could provide a custom HTTP response writer too: https://gist.github.com/prakashpandey/f8fe3e8f3d446cd3426ac67ac21172f7
I think that implementing some sort of
FragmentWriter
interface in both the templ buffer, and atempl.ResponseWriter
might work.Thoughts? Worth doing?
Beta Was this translation helpful? Give feedback.
All reactions