Skip to content

feat: support else-if chaining for block helpers - #648

Merged
rexm merged 1 commit into
masterfrom
fix/issue-263
Aug 5, 2026
Merged

feat: support else-if chaining for block helpers#648
rexm merged 1 commit into
masterfrom
fix/issue-263

Conversation

@rexm

@rexm rexm commented Aug 5, 2026

Copy link
Copy Markdown
Member

Summary

  • Adds support for {{else name args}} chaining on block helpers, e.g. {{#if a}}...{{else if b}}...{{else}}...{{/if}}, generalized to any block helper (not just if): {{#StringEqualityBlockHelper @value 'dog'}}...{{else StringEqualityBlockHelper @value 'cat'}}...{{else}}...{{/StringEqualityBlockHelper}}.
  • {{else name args}}...{{/outer}} desugars to a synthetic nested {{#name args}}...{{/name}} block that's closed by the outer block's closing tag rather than requiring its own — and chains recursively to any depth.
  • Existing {{#if}}/{{else if}} flattening logic is untouched (it already handled this case internally); the new path only kicks in for other block helper types, and composes with if's own handling when mixed.
  • README previously had to be corrected (Fix syntax for block helpers #358) to remove a claim that this worked. It didn't — now it does, and the README documents it again with a real example.

Test plan

  • Added tests in IssueTests.cs/ReadmeTests.cs: else-if for if, custom block helper in else-X position, 3-level chaining, mixed else if under a non-conditional block helper, multi-clause else-if-else-if-else, and a plain-{{else}} regression check
  • Full test suite passes (1846/1846)

Fixes #263

🤖 Generated with Claude Code

Generalize the existing {{#if}}/{{else if}} chaining so that any block
helper can be followed by "{{else helperName arg1 arg2 hash=val}}",
which desugars to nesting {{#helperName ...}}...{{/helperName}} inside
the outer else clause - except the nested block shares the outer
block's closing tag instead of requiring its own, and can itself be
followed by further else/else-X clauses.

BlockAccumulatorContext gains a ResolvedClosingName (with an override
hook) so a synthesized nested context can be closed by the outer
block's literal closing tag, and BlockAccumulator recognizes
"{{else name ...}}" and recurses into a nested context for it. The
existing if/unless else-if fast path opts out via
HandlesChainedElseInternally and is otherwise untouched.
@rexm
rexm enabled auto-merge August 5, 2026 04:13
@sonarqubecloud

sonarqubecloud Bot commented Aug 5, 2026

Copy link
Copy Markdown

@rexm
rexm merged commit 95b57df into master Aug 5, 2026
7 checks passed
@rexm
rexm deleted the fix/issue-263 branch August 5, 2026 04:25
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.

Support "else X" for block helpers

1 participant