CurlyBracketsFilter a js proměnná $
- paranoiq
- Člen | 392
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 | 8218
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
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
Ve Smarty se to vypnutí jmenuje {literal}{/literal}.
Editoval Honza M. (24. 4. 2009 11:05)
- Honza Kuchař
- Člen | 1662
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
Ja jsem jedine pro…imho je to vyborna ficurka a vyhneme se tim klasickym „zavorko-mezerovym“ chybam.
- David Grudl
- Nette Core | 8218
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 kolemheight
)?
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
Teď mě napadají asi tři způsoby řešení.
- Zrušit vyhazování výjimky. Dokud to výjimky neházelo, nebyl s tím problém.
- Uvnitř {literal}u zavést nějakou alternativní CB syntaxi. Třeba {{{$id}}}.
- 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 | 8218
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.
- Honza Marek
- Člen | 1664
Ta mezera je filozofická… Přece ti šablona nebude diktovat, jaký má být výstup :-D
- muta
- Člen | 21
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
- Wosonj
- Člen | 36
Ž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
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 | 8218
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…
- xzajic
- Člen | 19
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.
- joe
- Člen | 313
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
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
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…
- Honza Marek
- Člen | 1664
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
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
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
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}';
- jasir
- Člen | 746
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
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
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
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 | 8218
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
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
vrtak-cz napsal(a):
Existuje i ne
n:
-ková varianta? Pro nás con:
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
tak pro makro {/syntax}
může být vyjímka… nebo to bude
fungovat tak jak ty píšeš… :-)
- David Grudl
- Nette Core | 8218
{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á.