Latte a plaintextové versus „blokové“ filtry

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
David Grudl
Nette Core | 8227
+
+2
-

Do Latte jsem chtěl ještě mergnout featuru, která kontroluje, zda se filtry používají ve správném content-type, tj. jestli je vstupem pro filtr to, co se očekává. Problematické je hlavně použití filtrů nad {block} a {include}, protože všechny filtry (s výjimkou striptags, strip a indent) jsou určené pro čistý text (plaintext) a najednou dostávají HTML, což je špatně. Takže třeba upper bude měnit velikost znaků uvnitř tagu, truncate může přeříznout tag nebo entitu napůl atd.

Možností, jak toho docílit, je více, ale bez BC breaku se to neobejde, protože filtry pro čistý text vs pro bloky bude potřeba rozlišit a jediný rozumný způsob je při registraci asi třetím parameterem (uvede se jen u blokových a těch je v praxi minimum).

Při pokusu použít filtr pro čistý text na bloku či include se asi vyhodí varování, které by šlo obejít tím, že by se jako první filtr v modifikátoru uvedl |toText (název není finální – nakonec jsem použil stripHtml), který by vstup převedl na text.

Říkám si, že by to mohlo akceptovat i |striptags, který už se v tomto smyslu často používá, takže by dopad BC breaku byl minimální, ale v takovém případě bych musel striptags upravit tak, aby kromě HTML elementů dekódoval i entity, což je opět BC break. Striptags totiž nedekóduje entity, což nevadí v kombinaci s upper nebo lower, ale může způsobit chybu s truncate, pokud přeřízne entitu uprostřed.

Názory?

Jan Tvrdík
Nette guru | 2595
+
0
-

Mám dost problém pochopit, kde je vlastně ten problém a co se snažíš sdělit. Ty chceš při deklaraci filtru uvést, který contentType to očekává na vstupu? S tím, že pokud by Latte dokázalo automaticky provést konverzi, tak by ji udělalo a pokud by to nešlo, tak by to skončilo chybou? Rozlišení na „blokové“ a „neblokové“ filtry vůbec nechápu.

David Grudl
Nette Core | 8227
+
0
-

Zkusil jsem to napsat trošku lépe, ale v podstatě je to tak, že při přidání filtru musí být uvedeno, že je „blokový“, aby ho bylo možné použít jako {block|filtr} nebo {include|filtr}, na rozdíl od {$var|filtr}.

Otázka je, jak řešit kompatibilitu a vůbec nesprávné použití filtrů.

Buď může při použití plaintextového filtru na bloku (či include) obsah automaticky převést na text a po posledním filtru výsledek zase escapovat dle daného kontextu, nebo může trvat na manuálním převodu a kontrolovat, zda je jako první filtr uveden zmíněný |toText.

V praxi se občas používá filtr |striptags, který zdánlivě převod HTML → text zajišťuje, takže by se místo toText dal akceptovat i on, ale problém je, že striptags neřeší entity, takže by se buď musel upravit (BC break) nebo vypsat noticku, že by měl být nahrazen za toText.

Jan Tvrdík
Nette guru | 2595
+
0
-

Pořád nechápu, proč používáš spojení „blokový filtr“. S nějakou blokovostí to přece vůbec nesouvisí, jde jenom o to, aby filtr dostal na vstupu data ve formátu, který očekává. Makro {block} nemusí vracet HTML a naopak jiná makra nemusí vracet plain-text, nebo ne?

Co takhle, kdybys při registraci filtru mohl uvést i více content-typů a pak bys dostal aktuální content-type jako úplně první parametr před vlastní hodnotou. Tj. třeba filtr truncate by mohl umět korektně zkrátit plain-text i HTML?

David Grudl
Nette Core | 8227
+
0
-

Používám spojení blokový filtr, protože se to týká (především) filtrů použitých nad {block}. Na názvosloví netrvám, navrhni jakékoliv jiné.

Mělo by to fungovat jak píšeš, filtr jako první parametr dostane content type, nejspíš i předaný referencí, aby ho mohl změnit, pokud výstup je v jiném contenttype. Uvádět výčet contenttypes při registraci není dobré, protože registrace by měla být co nejsnazší, ono už i to, že uživatel bude muset uvést třeba TRUE je nešikovné. Lepší bude asi vytvořit pro filtr třídu, zaregistrovala by se jen třída/objekt a nesla by metainformace o filtru.

Milo
Nette Core | 1283
+
+3
-

Přemýšlel jsem nad tím v době, kdy vznikalo safeUrl.

Pro „chytrý“ filtr by mohl fungovat fígl s typehintem, jak pro formulářovou událost. Něco jako:

$filter = function (Latte\FilterContext $context, $value, ...$args) {
	...
};

Nebo to vše zabalit do jednoho objektu:

class FilteredValue
{
	public $contentType;
	public $value;
	public $args;
}
David Grudl
Nette Core | 8227
+
+2
-

To je dobrý nápad, takový filtr by se dal detekovat automaticky a nebyl by potřeba žádný další parametr. Ale argumenty bych do toho nebalil, je praktické je vyjmenovat a pojmenovat.

David Grudl
Nette Core | 8227
+
+3
-
Milo
Nette Core | 1283
+
0
-

Prostě super! Když jsem to dříve zkoušel implementovat, moc daleko jsem se nedostal. A tohle vypadá skvěle!

Felix
Nette Core | 1245
+
+9
-

Nestacim zirat, myslel jsem ze latte bylo dokonale uz predtim. Ale tyhle zmeny ve 2.4, to je zase jinej level. :)

Editoval Felix (15. 5. 2016 13:14)

David Grudl
Nette Core | 8227
+
0
-

Díky :-)