Replies: 2 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.
-
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