a-h / templ

A language for writing HTML user interfaces in Go.
https://templ.guide/
MIT License
8.39k stars 277 forks source link

feature: add templ.HasChildren function #975

Open epicbytes opened 3 weeks ago

epicbytes commented 3 weeks ago

Some components should have a default display if no child is passed, but the problem is that when callinggetChildren(ctx). But I get NopComponent. This is unacceptable because there is a nil check in the same function. I can't compare and understand whether there are child components or not.

Please add the HasChildren(ctx) function to the release, which will give an understanding.

So, i want to do like this one:

if children == nil {
    <input { *ic.Attributes... }/>
} else {
    { children... }
}
a-h commented 3 weeks ago

Good idea.

I propose a design like this:

func Children(ctx context.Context) (ok bool, c templ.Component) {
    _, v := getContext(ctx)
    if v.children == nil {
        return false, NopComponent
    }
    return true, *v.children
}  

So you could use it as:

if children, ok := templ.Children(ctx); ok {
  @children
} else {
  <div>No children</div>
}

This wouldn't replace the { children... } syntax, but { children...} is already redundant, since you can do @templ.GetChildren(ctx) to get the same result. It would be possible to update templ to replace { children...} with a @templ.GetChildren(ctx) statement if we wanted to slim down, but it's out of scope for this.

To implement this, we'd need some generator tests to ensure that if, if / else behaviour works OK, and that you get a NopComponent instead of nil if there are no children to prevent accidental panics where the ok value is ignored or used incorrectly. We'd also need some unit tests for the runtime function.

Happy to take a PR for this if someone else wants to implement, also happy to hear comments on the proposal, including naming the function something else.

epicbytes commented 3 weeks ago

Acceptable, it looks like due to the early calculation of child components it would be logical to use a flag whether the child components were initially passed or not, because the order of the call would then matter.

a-h commented 2 weeks ago

I'm not sure I completely follow. Are you suggesting a different API?

We have an experimental package at https://github.com/templ-go/x - that might be a good place for a proof-of-concept design.