Skip to content

fix: support else if conditional attributes - #1412

Open
akfaew wants to merge 1 commit into
a-h:mainfrom
akfaew:elseif
Open

fix: support else if conditional attributes#1412
akfaew wants to merge 1 commit into
a-h:mainfrom
akfaew:elseif

Conversation

@akfaew

@akfaew akfaew commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Summary

Adds first-class parser and AST support for else if branches in conditional attributes.

Previously, conditional attributes only modeled if and final else branches, so formatting an attribute-level conditional with else if could serialize poorly as a split else plus nested if. This updates conditional attributes to mirror normal templ if handling more closely.

Changes

  • Add ConditionalElseIfAttribute and ConditionalAttribute.ElseIfs.
  • Parse zero or more } else if ... { ... } conditional attribute branches before an optional final else.
  • Update conditional attribute formatting to emit } else if ... { on one line.
  • Update copy, visitor traversal, and generator handling for conditional attribute else if branches.
  • Add tests for:
    • formatter round-trip with else if
    • multiple else if branches
    • AST shape
    • generator output
    • visitor-based attribute formatting

Testing

go test ./parser/v2 -run 'TestElementFormatting|TestConditionalAttributeElseIfsParseAsBranches'
go test ./generator -run TestWriteConditionalAttributeElseIf
go test ./internal/format -run TestAttributes
go test ./parser/v2 ./parser/v2/visitor ./generator ./cmd/templ/fmtcmd ./internal/format
git diff --check

Copilot AI review requested due to automatic review settings June 15, 2026 04:30

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

Adds support for else if branches in conditional attributes across parsing, AST representation, formatting, visiting, and code generation.

Changes:

  • Extend ConditionalAttribute AST to include ElseIfs branches and implement deep-copy support.
  • Update parser/visitor/generator to traverse and emit else if blocks.
  • Add tests covering parsing, formatting, and generator output for conditional attribute else if branches.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
parser/v2/visitor/visitor.go Ensures else if branches are visited so downstream processing sees all attributes.
parser/v2/types.go Extends the AST with ElseIfs and updates serialization/copy helpers.
parser/v2/elementparser_test.go Adds formatting + parsing tests validating else if branch handling.
parser/v2/conditionalattributeparser.go Implements parsing of else if branches for conditional attributes.
internal/format/attributes_test.go Updates formatting tests to include an ElseIfs branch.
generator/generator_test.go Adds a generator regression test ensuring else if is emitted.
generator/generator.go Updates generation and attribute analysis to include else if branches.

Comment thread parser/v2/types.go
Comment on lines 1054 to 1060
type ConditionalAttribute struct {
Expression Expression
Then []Attribute
ElseIfs []ConditionalElseIfAttribute
Else []Attribute
Range Range
}
Comment on lines +100 to +103
if _, matched, err = openBraceWithOptionalPadding.Parse(pi); err != nil || !matched {
err = parse.Error("attribute else if: unterminated (missing closing '{\n')", pi.PositionAt(start))
return
}
Comment on lines +109 to +117
if r.Then, matched, err = (attributesParser{}).Parse(pi); err != nil || !matched {
err = parse.Error("attribute if: expected attributes in else if block, but none were found", pi.Position())
return
}

if len(r.Then) == 0 {
err = parse.Error("attribute if: invalid content or no attributes were found in the else if block", pi.Position())
return
}
Comment on lines +87 to +97
if _, matched, err = parse.All(parse.OptionalWhitespace, closeBrace, parse.OptionalWhitespace, parse.String("else if")).Parse(pi); err != nil || !matched {
pi.Seek(start)
return
}

// Rewind to the start of the `if` statement.
pi.Seek(pi.Index() - 2)
// Parse the Go if expression.
if r.Expression, err = parseGo("attribute else if", pi, goexpression.If); err != nil {
return
}
Comment on lines +205 to +214
ElseIfs: []parser.ConditionalElseIfAttribute{
{
Then: []parser.Attribute{
&parser.ConstantAttribute{
Key: parser.ConstantAttributeKey{Name: "class"},
Value: "else-if-class",
},
},
},
},
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants