helpery a ternární operátor

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
snake.aas
Člen | 25
+
0
-

Pokud chci použít helper v ternárním operátoru, např. takto

{var $number = 5}
{$number ? $number|number : 'Není k dispozici'}

Tak to nefunguje (ani pokud otočím podmínku a přehodím větve)

Vygenerovaný kód je

echo Nette\Templating\Helpers::escapeHtml($template->number($number ? $number:null , 'Nezadáno'), ENT_NOQUOTES)

namísto

echo Nette\Templating\Helpers::escapeHtml($number ? $template->number($number) : 'Nezadáno'), ENT_NOQUOTES)

is it bug or feature?

edit: upraveno z hotentotštiny

Editoval snake.aas (14. 2. 2013 12:12)

Jan Tvrdík
Nette guru | 2595
+
0
-

@snake.aas: S jistotou prohlašuji, že tohle je feature.

David Matějka
Moderator | 6445
+
0
-

j tohle je urcite feature, ‚Není k dispozici‘ se posle jako parametr helperu. otazkou je, jestli by zde nemela byt moznost to nejak udelat, treba pomoci zavorek?
to chovani totiz je takovy divny, viz:

{$cond? $number|number : 'Není k dispozici'}
{$cond? ($number|number) : 'Není k dispozici'}
{$cond? 'Není k dispozici' : $number|number}
{$cond? 'Není k dispozici' : ($number|number)}

se prelozi jako (bez escapování):

echo $template->number($cond? $number:null , 'Není k dispozici');
echo $template->number($cond? ($number:null) , 'Není k dispozici');
echo $template->number($cond? 'Není k dispozici' : $number);
echo $template->number($cond? 'Není k dispozici' : ($number));

1. a 3. chování je podle mě ok
u 2. a 4. by se podle mě ten helper neměl cpát před závorku, v 2. případě dokonce způsobí parse error

snake.aas
Člen | 25
+
0
-

jo, to jsem si pak uvědomil, že dvojtečka se používá pro parametry helperu a zkoušel jsem i ty závorky, jak naznačuje matej21, jenom zapomněl zmínit.

S 1 a 3 plně souhlasím, ale přijde mi logické použít

{$cond? ($number|number) : 'Není k dispozici'}

jinak se to musí obcházet delší podmínkou, ale třeba mi něco uniká (to samé u 4)

Filip Procházka
Moderator | 4668
+
0
-

Helpery můžeš používat pouze až na konci makra. Imho by to mělo hlásit chybu, že to máš na blbém místě.

Jako hotfix můžeš používat tohle

{$number ? $template->number($number) : 'Není k dispozici'}

helpery se totiž volají pomocí __call nad objektem $template.

llook
Člen | 407
+
0
-

Nette předpokládá, že to před svislítkem je ternární operátor bez třetího operandu a že to za svislítkem je helper s parametrem. Tak se to má správně chovat.

  • $number ? $number : NULL
  • |number:'Není k dispozici'

Možná by se to mohlo zmínit v dokumentaci, že všechny helpery se vždy aplikují na celý obsah makra nebo bloku.

hrach
Člen | 1844
+
0
-
{$cond? ($number|number) : 'Není k dispozici'}

je validni zapis s tenarnim operatorem, kdy uvnitr zavorky probiha bitovy or. Takze tezko vyhazovat nejakou chybu.

$cond = true;
$number = 1;
define('number', 2);
echo $cond? ($number|number) : 'Není k dispozici';
David Matějka
Moderator | 6445
+
0
-

validní zápis to sice v php je, ale latte to špatně přeloží, jak jsem psal výše:

$template->number($cond? ($number:null) , 'Není k dispozici')

a z toho máme Parse Error: syntax error, unexpected ‚:‘

edit:
z Nette\Latte\Parser::parse vyleze takovyhle Nette\Latte\Token:

Nette\Latte\Token (7)
type => "macroTag" (8)
text => "{$cond? ($number|number) : 'Není k dispozici'}" (47)
line => 2
name => "="
value => "$cond? ($number" (15)
modifiers => "|number) : 'Není k dispozici'|escape" (37)
closing => NULL

coz rozhodne v poradku neni :)

Editoval matej21 (14. 2. 2013 13:50)

Milo
Nette Core | 1283
+
0
-

Přepsat Latte parser tak, aby aplikoval helpery kontextově a ne na celé makro je, IMHO, netriviální záležitost. V tomto případě to lze jednoduše vyřešit buď makrem {if/else} anebo vlastním helperem ve stylu {$number|ifNot:$cond:'Není k dispozici'}. Lepší mi přijde makro {if}, helper by měl hodnotu jen formátovat.