CurlyBracketsFilter a js proměnná $

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

filtr curly brackets chybně interpretuje js proměnnou $ (použivaná v jQuery) jako začátek php proměnné, pokud se vyskytuje za složenou závorkou

například tohle skončí syntaktickou chybou šablony:

<script type="text/javascript">
$('tr.unit').dblclick(function() {$('#'+this.id).addClass('selected')});
</script>

pokud jde jen o proměnnou $, řeší to oprava CurlyBracketsFilter.php kolem řádky 165 (přidáno elseif):

<?php
if (preg_match('#[a-zA-Z0-9]$#', $key)) {
    $key .= '(?=[^a-zA-Z0-9._-])';
} elseif (preg_match('#\\$$#', $key)) {
    $key .= '(?=[${a-zA-Z_\x7f-\xff])';
}
?>

problém je pokud chci v js použít např. $foo, což je platné jméno proměnné v js i v php

lze to samozřejmě snadno obejít v javascriptu – stačí vložit mezeru za závorku, ale stejně není dobré, aby filtr takovýmhle způsobem sabotoval platný js kód

Editoval paranoiq (29. 1. 2009 16:17)

David Grudl
Nette Core | 8170
+
0
-

Jo, tak by to šlo řešit. Za dolarem musí následovat alfanumerickopodtržítkový znak. Jenže pak jsou tu ještě další kombinace, které způsobí stejný problém: {if, {for, {white… Takže spíš bych to viděl na to používání mezery.

Honza Kuchař
Člen | 1662
+
0
-

Ahoj,
protože toho samozřejmě hodí chybu:

<script type="text/javascript">
 $(".test").animate({height: 500},1000);
</script>

tak mě napadá co kdyby se udělalo něco jako dočasné vypnutí CurlyBracketsFilter (myslím, že se to tady někde už navrhovalo)
Třeba:

{code}
  <script type="text/javascript">
    ...
  </script>
{/code}

nebo:

{cbignore}...{/cbignore}

nebo: (možná by mohlo mást, že by si to někdo mohl zaměnit s komentářem)

{ignore}...{/ignore}

P.S.: Samozřejmě tam můžu dát tu mezeru, ale vypadá to hrozně.

Honza Marek
Člen | 1664
+
0
-

Ve Smarty se to vypnutí jmenuje {literal}{/literal}.

Editoval Honza M. (24. 4. 2009 11:05)

Ola
Člen | 385
+
+1
-

honzakuchar: za { stačí dát mezeru a pojede to

Aha, nevšim sem si toho PS

Editoval Ola (24. 4. 2009 16:26)

Honza Kuchař
Člen | 1662
+
0
-

Fakt je, že v tomto případě je to blbost, ale myslím že by měla být nějaká možnost cb vypnout. Nemyslíte?

Ondřej Brejla
Člen | 746
+
0
-

Ja jsem jedine pro…imho je to vyborna ficurka a vyhneme se tim klasickym „zavorko-mezerovym“ chybam.

timbulko
Člen | 85
+
0
-

Ja to riešim takto:

<?php
echo <<<JS
  <script type="text/javascript">
    $('tr.unit').dblclick(function() {$('#'+this.id).addClass('selected')});
  </script>
JS;
?>
David Grudl
Nette Core | 8170
+
0
-

Podporu pro {literal} klidně mohu přidat, ale nejsem přesvědčen o tom, že je to správný krok.

  • Nette na problém upozorní popisnou výjimkou Unknown CurlyBrackets macro '{height: 500}' in file '...phtml'.
  • tedy o chybě programátor ví okamžitě a ví přesně co hledat
  • a co udělá? Napíše raději do šablony {literal} a {/literal}, nebo jednu mezeru (či uvozovky kolem height)?

Alespoň já bych vždycky volil druhou možnost.

Nebo připadá vám tohle lepší?

<script type="text/javascript">{literal}
 $(".test").animate({height: 500},1000);
{/literal}</script>

V případě jako je tento

<script type="text/javascript">
 $("#" + {$id}).animate({height: 500},1000);
</script>

je použití literalu uplně šílené:

<script type="text/javascript">{literal}
 $("#" + {/literal}{$id}{literal}).animate({height: 500},1000);
{/literal}</script>
Honza Marek
Člen | 1664
+
0
-

Teď mě napadají asi tři způsoby řešení.

  1. Zrušit vyhazování výjimky. Dokud to výjimky neházelo, nebyl s tím problém.
  2. Uvnitř {literal}u zavést nějakou alternativní CB syntaxi. Třeba {{{$id}}}.
  3. Zavést nějakou syntaxi pro znaky { a }. Třeba {{ nebo \{.

Literal bych ale přidal. Dřív nebo později najde někdo pádnější důvod pro jeho použití než to, že mezera po { není hezká.

Editoval Honza M. (25. 4. 2009 10:50)

David Grudl
Nette Core | 8170
+
0
-

ad 1) dokud to neházelo výjimky, byla časovaná bomba. Co kdyby se dnes zavedlo makro {height...} – težko budeš pátrat, proč najednou nějaké skripty nefungují, nebo fungují jinak než mají, teda pokud si toho člověk všimne.

ad 2) to se obávám, že je ještě šílenější řešení ;-)

ad 3) to máš pravdu, ale problém s javascriptem nebo CSS to neřeší. Prostě opět, pokud dojde k chybě, každý by ji měl vyřešit korektní mezerou než přidáním znaku, který skript znečitelní a syntakticky rozbije.

Mě napadají jen dvě rozumné řešení:

  • počítat s tím, že CurlyBrackets tak funguje a občas prostě popravovat nějaké chyby. Lze si vyrobit skriptík, který projede všechny šablony a zobrazí případné výjimky. Nakonec určitým nepsaným měřítkem kvality webové aplikace je to, že skripty a CSS se drží v oddělených souborech a v samotné šabloně je jen nutná část.
  • nebo pro CSS a JavaScript používat syntax {{…}}, která se v daných jazycích nemůže vyskytnout (samozřejmě mimo řetězce a komentáře). Aby neprotestovali všichni, co mají skripty už napsané s {…}, musí být takové chování volitelné. Otázkou je, jestli by to byl krok správným směrem.
arron
Člen | 464
+
0
-

Jenom jedna filozoficka…Je opravdu nezbytne nutne kvuli jedne mezere a tomu, ze se ta mezera urcitemu okruhu programatoru v kodu nelibi, menit chovani Nette???

Honza Marek
Člen | 1664
+
0
-

Ta mezera je filozofická… Přece ti šablona nebude diktovat, jaký má být výstup :-D

muta
Člen | 21
+
0
-

haze mi to i pri css

<style>
#error {padding-left:1em;}

</style>

za } mam mezeru, zatim jsem neprisel nato, jak to obejit, vite nekdo ?

InvalidStateException

Unknown CurlyBrackets macro ‚{padding-left:1em;} ' in file 'C:\wamp\www\!sprava-objednavek\document_root/../app/templates/ShowOrder/orderShowSaved.phtml‘.

pouzivam :
Nette Framework 0.8 (rev. 283 ze dne 19. 4. 2009)

Nette Framework 0.8 pro PHP 5.2

Ola
Člen | 385
+
0
-

Mezeru musíš dát za {

muta
Člen | 21
+
0
-

mas pravdu – uz to jede

díky moc

Wosonj
Člen | 36
+
0
-

Že se k tomu vracím – mít možnost dočasně vypnout curlyBrackets by určitě bylo dobré.

Aneb na tuhle vlastnost jsem právě narazil taky a první co jsem hledal bylo, jak curlyBrackets na nějaký blok vypnout. Hack s mezerou v {} mě sice napadl, ale nepovažuju to za systémové řešení – aneb je to náchylné na to, že to někdo neznalý po mně zase přdělá a pak se bude divit…

romansklenar
Člen | 655
+
0
-

Taky bych řek, je to rozumný kompromis.

David Grudl napsal(a):

Podporu pro {literal} klidně mohu přidat, ale nejsem přesvědčen o tom, že je to správný krok.

Nic se tím podle mě nezkazí. Když půjde dále používat i mezera, ještě si může člověk vybrat. Navíc i lidi zvyklí na Smarty nebudou muset koumat jak toho docílit.

V případě jako je tento je použití literalu uplně šílené:

<script type="text/javascript">{literal}
 $("#" + {/literal}{$id}{literal}).animate({height: 500},1000);
{/literal}</script>

jasně to je už extrém, ale v případech kde je úsek kódu, kde by se na to muselo myslet delší, tak je CB výhodnější vypnout. Navíc tak půjde předejít tomu, že kodér nevědomky shodí aplikaci.

{literal}

<script type="text/javascript">
$(".test").animate({height: 500},1000);
...
...
</script>

<style>
#error {padding-left: 1em}
...
...
</style>
{/literal}
David Grudl
Nette Core | 8170
+
0
-

Nebo je možnost dovolit psát alternativně {makro} i {{makro}}, s tím, že by se uvnitř JavaScriptového kódu podporovala jen zdvojená varianta…

Honza Marek
Člen | 1664
+
0
-

Což samozřejmě není zpětně kompatibilní.

xzajic
Člen | 19
+
0
-

Kluci, taky se přimlouvám pro to nějak to pořešit. Moje situace: Šablona pomocí níž generuji HTML email. CSS má v sobě. Než jsem našel tuhle diskusi, zabralo mi to pár minut. Sám od sebe mě trik s mezerou nenapadl, {literal} by to řešil a hlavně bych to asi někde našel mnohem dřív.

PetrP
Člen | 587
+
0
-

spis by to mělo byt napsané v dokumentaci, na tom místě kde bys pripadne našel literal.

taky by podobně problémy řešilo kdyby se realizovali ty odkazy do dokumentáce z ladenky pri různých častých chybách. jako například unknown macro.

Editoval PetrP (14. 8. 2009 16:08)

crempa
Člen | 198
+
0
-

pro zdvojene zavorky v JS casti davam +
resim dost pripadu kdy jsem nucen prohanet celkem rozmerny JS kod sablonama a vicemene tak prichazim o moznost pouzit pro nej nejaky JS kompresor, protoze se okamzite dostanu na hromadu neznamych maker…

joe
Člen | 313
+
0
-

Ahoj,
tahle diskuze mi zrovna padla včas do oka, hledal jsem naprosto stejný problém. Rozhodl jsem se přepsat jednu aplikaci, kde jsem poprvé a naposled použil Smarty. V šablonách mám i JavaScript, který funguje na jQuery, takže asi chápete můj problém :-) A hledal jsem dlouho něco jako je {literal}
Napište prosím někdo, jak zavést nový „tag“, abych mohl použít následující kód:

{literal}
… tady se zcela ignoruje Curly Brackets …
{/literal}

Nemam rád RE, a tak bych to dával dohromady hrozně dlouho. Díky za rady.

PS: Myslím, že by to uvítalo více lidí, zvlášť těch, kteří přecházejí ze … Smarty.

EDIT: Tak asi pro mě bude lepší to přepsat to do externích souborů, pak s tím snad problém nebude a ještě si k tomu zpřehledním kód, tak budu vědět, kde co mám hledat. Ale určitě bych tam něco takového přidal.

Editoval joe (24. 8. 2009 13:41)

Honza Marek
Člen | 1664
+
0
-

Jako další příklad, kterým bych podpořil vznik literalu uvadím nastavování ColorBoxu:

<script type="text/javascript">
$(function(){
	$("a[rel=colorbox]").colorbox({
		current: "{" + "current} / {" + "total}"
	});
});
</script>

"{" + "current"… už opravdu není moc intuitivní. Normální mezera tam být nemůže, protože je to v řetězci. Navíc vlastně ani nevim, proč mi to s " projde.

kravčo
Člen | 721
+
0
-

Je vôbec žiadúce, aby LatteFilter v reťazcoch výskyty makier nahradzoval? Ak sa nemýlim, generuje vždy text v úvodzovkách:

"{current} / {total}" --> ""15" / "135""

Čo generuje chyby…

Přizpůsobení escapování podle lokálního obsahu.

Honza Marek
Člen | 1664
+
0
-

Právě to {current} a {total} se vůbec nemá nahradit, protože je to značka pro ten ColorBox.

Jakub Šulák
Člen | 222
+
0
-

Myslím, že by bylo vhodné dodělat do Nette {literal}, ale v dokumentaci jej uvést s doporučením nepoužívat jej. Programátor začátečník jej nepoužije a pokročilejší jen v nejzažších případech. Takové goto(); Nette :)

jasir
Člen | 746
+
0
-

Zkusil jsem implementovat literal způsobem, jaký navrhoval nedávno David. Nepovedlo se mi to unobtrusive (nechtělo se mi dědit od LatteMacros ani používat extension methods) – nepřišel jsem na to, jak napsat vnější makro, které si umí šáhnout na filter. To by možná nebylo špatné do frameworku doplnit – třeba tedy přidat čtvtý parametr při volání makra s odkazem na $this.

Implementace:

Do LatteMacros.php do seznamu maker doplnit 2 nová makra:

<?php
'literal' => '%:macroLiteral%',
'/literal' => '%:macroLiteralEnd%',
?>

A přidat dvě obslužné funkce:

<?php
private function macroLiteral() {
	$this->filter->setDelimiters('\\{\{\%(?![\\s\'"{}])', '\\%\}\}');
}
private function macroLiteralEnd() {
	$this->filter->setDelimiters('\\{(?![\\s\'"{}])', '\\}');
}
?>

Použití

<script n:literal>
...tady už nefungují {makra}, ale dá se volat makro přes {{%...%}}
</script>
...tady už fungují.

Dá se použít i psychotické:

{literal}
...
{{%/literal}}

…ale to zmiňuji spíše pro pobavení

Editoval jasir (7. 9. 2009 20:35)

kravčo
Člen | 721
+
0
-

Honza M. napsal(a):

Právě to {current} a {total} se vůbec nemá nahradit, protože je to značka pro ten ColorBox.

To som pochopil, príkladom som chcel načrtnúť ako sa to správa a že to nie je práve najideálnejšie…

Položil som otázku do pléna, nakoľko ak by sa makrá nenahrádzali vnútri reťazcov, padla by (podľa mňa) potreba literal vo frameworku implementovať.

t = {$variable};    --[Latte(js)]-->  t = "value";
t = "{$variable}";  --[Latte(js)]-->  t = "value";
t = '{$variable}';  --[Latte(js)]-->  t = '{$variable}';
nAS
Člen | 277
+
0
-

kravčo napsal(a):

t = {$variable};    --[Latte(js)]-->  t = "value";
t = "{$variable}";  --[Latte(js)]-->  t = "value";
t = '{$variable}';  --[Latte(js)]-->  t = '{$variable}';

To vypadá perfektně, já jsem určitě pro.

jasir
Člen | 746
+
0
-

Kravčo:

Stále to neřeší třeba to výše zmíněné (a podle mě nejčastější).

<script type="text/javascript">
 $(".test").animate({height: 500},1000);
</script>

plus problémy s CSS. Ale ano, asi by to částečně pomohlo. Ale zase už se nám to zesložiťuje:

  • v případě xy doplňuje uvozovky
  • v případě alfabete nedoplňuje uvozovky
  • v jiném tam dej mezeru

Zeptám se – jak často používáte Latte makra v javascriptu nebo css? Já to ještě nepoužil, číli mě jsou tam ta makra spíše na zlost, aby si člověk pořád hlídal, jestli
ta nebo ona konstrukce zrovna nebude vyhodnocena jako makro.

Editoval jasir (7. 9. 2009 23:45)

Honza Marek
Člen | 1664
+
0
-

jasir napsal(a):

<script type="text/javascript">
$(".test").animate({height: 500},1000);
</script>

S timhle jsem nikdy problém neměl. Asi to vždycky odsadim na další řádku.

Zeptám se – jak často používáte Latte makra v javascriptu nebo css? Já to ještě nepoužil, číli mě jsou tam ta makra spíše na zlost, aby si člověk pořád hlídal, jestli
ta nebo ona konstrukce zrovna nebude vyhodnocena jako makro.

Já je potřebuju na nastavení adres v Texyle.

kravčo:

t = "{$variable}";  --[Latte(js)]-->  t = "value";
t = '{$variable}';  --[Latte(js)]-->  t = '{$variable}';

Tohle rozlišovat mi přijde už dost matoucí. Tohle je ideální pro lidi, kteří nikdy neviděli JavaScript :)

crempa
Člen | 198
+
0
-

Zeptám se – jak často používáte Latte makra v javascriptu nebo css? Já to ještě nepoužil, číli mě jsou tam ta makra spíše na zlost, aby si člověk pořád hlídal, jestli

hodne casto, pokud pouzivas nejake rozsahlejsi JS projekty (treba rozhrani pro praci s mapama) tak si neumim predstavit jak se bez maker obejit…

jasir
Člen | 746
+
0
-

Okej, díky za odpovědi, řekl bych tedy, že uživatelé se budou tedy rozdělovat takto:

  • ti, kteří makra v js/css používají často. Takoví si bez problémů ohlídají konflikty s LatteFilter a spokojeně použijí mezeru/odentrování. Pro ty asi {literal} nemá valného smyslu
  • ti, kteří to používají občasně, sem tam nějaký JQuery effekt, sem tam zapsat do kódu CSS. Pro takové je {literal} a možnost „vypnutí konfliktu s LatteFilter“ velmi přínosné.

Editoval jasir (8. 9. 2009 11:34)

David Grudl
Nette Core | 8170
+
0
-

Můžete si to vyzkoušet naostro – ale berte to prosím jako experimentální věc.

<ul n:syntax="python">
{% foreach $people as $person %}
	<li>{{ $person |upper }}</li>
{% /foreach %}
</ul>

<ul n:syntax="asp">
<% foreach $people as $person %>
	<li><% $person |upper %></li>
<% /foreach %>
</ul>

<ul n:syntax="double">
{{foreach $people as $person}}
	<li>{{$person |upper}}</li>
{{/foreach}}
</ul>

<p n:syntax="latte">Default: {$person}</p>

<p n:syntax="off">Default: {$person}</p>
Patrik Votoček
Člen | 2221
+
0
-

Existuje i ne n:-ková varianta? Pro nás co n: moc nemusejí. Tím myslím něco jako:

<ul>{syntax python}
{% foreach $people as $person %}
        <li>{{ $person |upper }}</li>
{% /foreach %}
{/syntax}</ul>

<ul>{syntax asp}
<% foreach $people as $person %>
        <li><% $person |upper %></li>
<% /foreach %>
{/syntax}</ul>

<ul>{syntax double}
{{foreach $people as $person}}
        <li>{{$person |upper}}</li>
{{/foreach}}
{/syntax}</ul>

<p>{syntax latte}Default: {$person}{/syntax}</p>

<p>{syntax off}Default: {$person}{/syntax}</p>
Etch
Člen | 403
+
0
-

vrtak-cz napsal(a):

Existuje i ne n:-ková varianta? Pro nás co n: moc nemusejí. Tím myslím něco jako:

<ul>{syntax python}
{% foreach $people as $person %}
        <li>{{ $person |upper }}</li>
{% /foreach %}
{/syntax}</ul>

<ul>{syntax asp}
<% foreach $people as $person %>
        <li><% $person |upper %></li>
<% /foreach %>
{/syntax}</ul>

<ul>{syntax double}
{{foreach $people as $person}}
        <li>{{$person |upper}}</li>
{{/foreach}}
{/syntax}</ul>

<p>{syntax latte}Default: {$person}{/syntax}</p>

<p>{syntax off}Default: {$person}{/syntax}</p>

No to podle mě takhle úplně dost dobře nejde, protože jakmile přepneš syntaxi tak by si musel v nové syntaxi i ukončovat. Tedy něco jako :

<ul>{syntax python}
{% foreach $people as $person %}
        <li>{% $person |upper %}</li>
{% /foreach %}
{%/syntax%}</ul>

<ul>{syntax asp}
<% foreach $people as $person %>
        <li><% $person |upper %></li>
<% /foreach %>
<%/syntax%></ul>

<ul>{syntax double}
{{foreach $people as $person}}
        <li>{{$person |upper}}</li>
{{/foreach}}
{{/syntax}}</ul>

ale nevím možná že je to nějak ošetřené.

Editoval Etch (9. 9. 2009 6:37)

Patrik Votoček
Člen | 2221
+
0
-

tak pro makro {/syntax} může být vyjímka… nebo to bude fungovat tak jak ty píšeš… :-)

Etch
Člen | 403
+
0
-

vrtak-cz napsal(a):

tak pro makro {/syntax} může být vyjímka… nebo to bude fungovat tak jak ty píšeš… :-)

No v podstatě to funguje tak jak sem psal výše. Jediné co vlastně nejde udělat je

{syntax off}

protože pak už se z toho nedostaneš :)

David Grudl
Nette Core | 8170
+
0
-

{syntax off} je řešené tak, že makro musí začínat zcela naprosto libovolným bajtem mimo rozsah \x00 – \xFF. Takže dá se z toho dostat, jen to chce nějakou širší klávesnici, která takový znak má.

paranoiq
Člen | 392
+
0
-

David Grudl napsal(a):

{syntax off} je řešené tak, že makro musí začínat zcela naprosto libovolným bajtem mimo rozsah \x00 – \xFF. Takže dá se z toho dostat, jen to chce nějakou širší klávesnici, která takový znak má.

koukám, že už jsi přešel na UTF-9, že :P