Latte a plaintextové versus „blokové“ filtry
- David Grudl
- Nette Core | 8227
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
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
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
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
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
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
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.