Closed BernhardBaumrock closed 1 year ago
Why not simply use plain if? Like this:
{if $block->images()->count()}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
{/if}
I would probably use skipIf
rather than returnIf
…
@MartinMystikJonas good point, didn't think of that. IMHO it's ugly, so it's partly just a personal preference :) But there are often cases where early exists are a lot cleaner than if/else/and/or...
{returnIf !$block->images()->count()}
{returnIf $block->settings->foo}
{returnIf $block->settings->bar AND $block->title == 'bar'}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
Also it does not add unnecessary indentation etc. It's the same as having n:if
where you could also wrap the tag in {if}...{/if}
but n:if
or n:tag-if
producing much cleaner code!
@dg I would expect skipIf
to be a pair tag that bounds what should be skipped. Maybe stopIf
would be an option? Or maybe breakIf
, even though it's not a loop. returnIf
on the other hand best fits to the nature of a template – that it's a function.
@dakur that's exactly what skipIf should NOT be. As you describe it {skipIf} would just be the opposite of {if} and that's not what I want. I'm talking of a new concept that skips rendering of the whole latte file if a condition is met. So {skipIf} would not have any closing tag by design.
@BernhardBaumrock I know, I understood your proposal. I'm discussing the word to be used and its sense – how it's read and understood in the code.
Word "skip" in my opinion implies that it will be further defined (inside of the tag) what should be skipped, because skipping means that you will continue somewhere further (below), whereas "return"/"break"/"stop" clearly says that the code execution stops and doesn't continue for the rest of the file.
Example – if I see this code:
{returnIf !$block->images()->count()}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
I clearly understand that if condition is not met, whole template ends rendering. While if I see
{skipIf !$block->images()->count()}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
a question arises: "wait, but what should be skipped? where will it continue?"
At least that's my perception of it.
Ah, thx @dakur good point. I think that will also fit better into the principle of latte being very close to plain PHP and not a different language. +1 for returnIf :)
For me it was about reusing existing tag in a new context https://latte.nette.org/en/tags#toc-continueif-skipif-breakif
In that context, skipIf
seems like a solution for a particular problem – being able to continueIf
while preserving the counter. But still, the loop gives a sense of the context – what is being skipped. When the context is whole template file, I think it's not so obvious. I can see more similarity to breakIf
than to skipIf
.
But it's just wording, the point is the functionality of course, words can be changed any later. :-)
@dg What about somehow extend the ifContent macro? To be able hide parents/siblings?
I see it exactly the opposite :-) The term return
doesn't mean anything to me in the context of templates. What to return? On the contrary, it is common to use skip to … ehm … skipping https://phpunit.readthedocs.io/en/9.5/incomplete-and-skipped-tests.html#skipping-tests https://maven.apache.org/plugins-archives/maven-surefire-plugin-2.12.4/examples/skipping-test.html https://github.com/cypress-io/cypress-skip-test etc
@milo it is not about content, but about your conditions
In tests, you skip whole test, you don't say "skip" from the middle of the test. But it's true that Bernhard posted a use-case with skip at the beginning, not in the middle, so I give up. 🙂
I understood it from the beginning as early exit, i.e. ending in header.
Maybe we could also use endIf
.
For me none of skipIf, breakIf or endIf feels right. skipIf and breakIf do belong to loops. And endIf belongs to a preceeding {if}.
If you don't like returnIf
, what about exitIf
?
{exitIf !$block->images()->count()}
{exitIf $block->settings->foo}
{exitIf $block->settings->bar AND $block->title == 'bar'}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
I'm gonna try to do a poll on this. https://twitter.com/nettefw/status/1517165228898848769
exitIf - similar to exit() skipIf - already used in different context endIf - can be confused with {/if} returnIf - IMHO best but not exactly right either
What about terminateIf?
Few quick thoughts:
abortIf breakIf cancelIf discontinueIf haltIf endIf
Dne čt 21. dub 2022 18:19 uživatel Martin Mystik Jonáš < @.***> napsal:
exitIf - similar to exit() skipIf - already used in different context endIf - can be confused with {/if} returnIf - IMHO best but not exactly right either
What about terminateIf?
— Reply to this email directly, view it on GitHub https://github.com/nette/latte/issues/287#issuecomment-1105434831, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABROI46VIQKIK5VDFY77F3VGF5YTANCNFSM5T4DGF7Q . You are receiving this because you are subscribed to this thread.Message ID: @.***>
finishIf
The goal was to reach a consensus :-)
What about the opposite meaning?
{renderIf $block->images()->count()}
<h1>{$block->headline}</h1>
<div n:inner-foreach="$block->images() as $img">
...
</div>
Just to throw in more wrenches, I'll suggest stopIf
. 😁
But seriously, I don't really care about the name. I just wanted to chime in suggesting to avoid tags containing return
or exit
since both are loaded with a different meaning in PHP.
The quitIf
and leaveIf
hasn't come up yet :)
Ok I didn't know back in April, but now I know that my suggested priciple does actually have a name and is called "guard clause". A guard clause is here to reduce complexity and make code more readable, which is exactly why I proposed the feature. Read here: https://deviq.com/design-patterns/guard-clause or see here: https://www.youtube.com/watch?v=EumXak7TyQ0
Well i've always used just php return since 2.4 but now with 2.* it force me to use "return []"
any news on exitIf
@dg ? With some time passed by I think exit
is really the best wording :)
@badpenguin what do you mean? I don't understand. On my end there seems to be no easy way out of a rendered latte file once rendering has started...
I just do <?php return; ?>
@badpenguin we are talking about LATTE files, not PHP files ;) That's exactly what I'm requesting. Make a feature that is extremely easy to do in PHP also available to LATTE.
@dg related to this discussion there's also another request/question:
In the PW forum someone came up with a hacky "includeIF" solution:
{include $foo == 'bar' ? "test.latte" : "blank.latte"}
The problem is that you need to define a second template otherwise latte throws an error.
It would be nice to have something like this:
{include $foo == 'bar' ? 'somefile.latte'}
@BernhardBaumrock I find this more understandable:
{if $foo == 'bar'}{include 'somefile.latte'}{/if}
Hey @dg unfortunately I'm not able to use this new feature :( Any idea what I could be doing wrong?
I tested with {exitIf $page->template != 'releasepage'}
initially but same error.
fixed
Great, thx @dg !
As explained in this forum question I'd need an early exit feature in latte templates: https://forum.nette.org/en/35172-early-exit-in-latte-template-file
This follows the guard clause instead of if/else-nesting, see https://www.youtube.com/watch?v=EumXak7TyQ0 why this can be good for reducing code complexity and making it easier to read and maintain.
I've built a page builder for the ProcessWire CMS that looks like this:
These content blocks consist of a controller file and a view file. The controller file is PHP (eg Gallery.php), the view file is LATTE (eg Gallery.latte).
A simple view file could look like this:
Now what I'd like to do is to only render the view file if certain conditions are met. In this example it would be great to only render the gallery view file if the block has at least one uploaded image.
Without this feature I need to wrap my view markup in an if condition:
Thx for considering :)