Writing the docs for v3, got to the section on {:elseif ...} and realised that I couldn't quite justify why it's that instead of {:else if ...}.
Should we change it? If so, now would be the time to do it.
Arguments for changing (sound off in the comments and I'll update the bullet point lists):
else if is JavaScriptierArguments against:
elseif is arguably more consistent with other templating languageselseif to highlight the whole word, which @arxpoetica enjoys apparently?<!-- current -->
{#if x > 10}
<p>{x} is greater than 10</p>
{:elseif 5 > x}
<p>{x} is less than 5</p>
{:else}
<p>{x} is between 5 and 10</p>
{/if}
<!-- alternative -->
{#if x > 10}
<p>{x} is greater than 10</p>
{:else if 5 > x}
<p>{x} is less than 5</p>
{:else}
<p>{x} is between 5 and 10</p>
{/if}
In case you have a preference but don't feel like writing an essay about it, I've created a poll: https://www.strawpoll.me/17510302
Perhaps allow for both? PHP for example allows for this
That's the coward's way out 😉 It's always tempting as a maintainer to say 'let the users decide' but it has insidious costs — it means more documentation, creates anxiety about which is the 'right' way, and causes messier codebases if there's disagreement among a team working on the same app. (It also clutters up the Svelte codebase — less important but not nothing.)
As a rule Svelte has always opted for a single canonical right way of doing things wherever possible.
Fair enough, let the vote decide!
Is parsing time a concern? Is "else if" more complicated for parsing, requiring backtracking for example?
I wonder in else if variant what if currently someone using if as a prop? This is unlikely, but still.
update: the condition in :else is not captured so there is no problem.
Is parsing time a concern?
Nah, it's the same either way
Shorter version :elseif as most template engines use it like that.
The VBA developer in me is fine with :elseif, but I think it would be wise to get closer to JS syntax with {:else if ...}. (Of topic: feel similarly about converting {#each ...} into {#for ... of/in ...})
Taking into account that we can have pretty much any expression in the ifblock, I think it's more natural to have the current elseif block more "javascriptier".
Current:
{#if abc.filter(greaterThan(0)).length >= 2 && someTest()}
many!
{:elseif abc.filter(greaterThan(0)).length == 1 && someOtherTest()}
just one
{:else}
none
{/if}
New proposal::
{#if abc.filter(greaterThan(0)).length >= 2 && someTest()}
many!
{:else if abc.filter(greaterThan(0)).length == 1 && someOtherTest()}
just one
{:else}
none
{/if}
The new proposal look better, in my opinion.
Coming after the deadline, but to me the question boils to the meaning of : in {:x y}. I thought like # it preceded a templating language keyword, in which case it's odd to have two words (else if). Alternatively perhaps it means opening some special expression context, in which case else if could make sense.
So in short: is there a doc explaining the semantic meaning of the templating syntax in a generic way? That could be helpful too as a basis for discussing new syntax. As an aside, I often wondered if Svelte would offer a way to extend the syntax via some kind of plugins?
@theefer Think of it more like {#, {: and {/ than #if, :else and /if - they signify 'block opening', 'block continuation' and 'block closing' respectively. They get a brief mention in the new tutorial I'm working on, but I don't think we've covered it in detail anywhere.
Have wondered about plugins. I think it's a little trickier in Svelte than in a traditional string templating language, since the implementation of (say) a try block would be very difficult to do from outside the framework - perhaps prohibitively so
Hey @Rich-Harris. Not trying to completely derail this thread (I guess I am doing it anyway), but one thing that I get mixed up with when writing templates is that the tags are different for open, continuation, and close. I don’t know if anyone else has ever run into this, but the fact that an open tag uses {#, continuation uses {:, and closing uses {/ always mixes me up. As soon as I see the compilation error, it clicks, and it is a quick fix, but I would say I have run into it quite a few times.
Have you ever considered doing something like
{#if abc.filter(greaterThan(0)).length >= 2 && someTest()}
many!
{#else if abc.filter(greaterThan(0)).length == 1 && someOtherTest()}
just one
{#else}
none
{#end}
Or perhaps {#endif} at the end if it needs to match an open tag
It would be one less thing to have to think about when writing templates.
Isn't that similar to writing markup like this?
<div>
<p>some text<endp>
<enddiv>
The / character makes it easier to discern structure without needing to engage the part of your brain responsible for understanding words. I don't have any scientific studies to hand but I'd be confident that varying the punctuation makes templates more readable, and readability is the important thing to optimise for.
Fair enough. I think what ends up confusing me has less to do with the closing / and more to do with the : for continuation expressions. I naturally end up writing {#if something} {#else}, and in that case there is not really any syntactical difference. Using your markup example, you could compare the current syntax to something like this:
<ul>
<:li>item one</li>
<:li>item two</li>
<:li>item three</li>
</ul>
I know it is not exactly the same thing, but the thought process when writing it is similar. Anyway, I am sure you have bigger fish to fry, and this isn’t going to be keeping anyone up at night.
It leaves me a late question, what's reason of prefix # or : in if, each, and else?
I mean, what if is {if, each is {each and else is {else?
I guess we're ok to avoid reserved words in var naming.
Thanks
I mean, what if is {if, each is {each and else is {else?
I guess we're ok to avoid reserved words in var naming.
The code still has to be valid javascript, so you can't use a reserved word like if for an identifier anyway. The prefixes probably aren't strictly necessary from a parsing perspective, but are visual cues that set them apart from e.g. a simple expression like { myVar } in the template.
As for the : prefix on intermediate blocks, I do get tripped up sometimes when writing these and write #else or #then, etc. by accident. It does seem to marginally improve readability though, especially when there are a couple levels of nesting.
Most helpful comment
That's the coward's way out 😉 It's always tempting as a maintainer to say 'let the users decide' but it has insidious costs — it means more documentation, creates anxiety about which is the 'right' way, and causes messier codebases if there's disagreement among a team working on the same app. (It also clutters up the Svelte codebase — less important but not nothing.)
As a rule Svelte has always opted for a single canonical right way of doing things wherever possible.