DefaultFormRenderer::renderControl() – neuplatnění wrapperu při Html description

- Ondřej Bouda
- Člen | 2
Zdravím vývojáře a rád bych se zeptal, jestli je nějaký (a příp.
jaký) důvod, proč DefaultFormRenderer při renderování
elementu neuplatňuje "control description" wrapper, pokud je
description zadáno jako Html objekt. Konkrétně mířím na tento
kus metody DefaultFormRenderer::renderControl():
$description = $control->getOption('description');
if ($description instanceof Html) {
$description = ' ' . $control->getOption('description');
} elseif (is_string($description)) {
$description = ' ' . $this->getWrapper('control description')->setText($control->translate($description));
} else {
$description = '';
}
Mohla by vzniknout nějaká cesta, jak předat objekt, který by se
vyrenderoval podobně jako se to děje s Html objekty, ale navíc
byl obalen wrapperem jako ostatní, textově zadané descriptions?
Rád bych totiž formuláře rozšířil kromě description vstupních prvků i o nějakou rozšířenou nápovědu k danému prvku (např. v description řeknu, že se zadává datum a čas, v této rozšířené nápovědě bych uvedl, v jakém formátu datum a čas očekávám – nechci zabíjet místo na stránce tím, že bych nápovědu rovnou zobrazil jako description, ale zároveň ji chci nabídnout).
Jako nejelegantnější mi přišlo pro tento účel volat
setOption('description', new HelpDescription('zadejte datum a cas', 'Format zadani je ...')),
kde HelpDescription by dědila po Html a rovnou by
vytvořila např. SPAN element s textovým obsahem ‚zadejte datum a cas‘ a
title atributem ‚Format zadani je …‘ (a případně nějakou CSS třídou
pro zvýraznění, že zde nápověda je). Tím ale přicházím o zabalení
celého elementu do standardního wrapperu. Musel bych tak objektu
HelpDescription předat i renderer, ze kterého by si vysosal,
čím se má ještě obalit, což mi nepřipadá už tak elegantní, protože
pokud se wrapper ve formuláři změní až po definici prvků, tohoto prvku se
to už nedotkne a bude zabalovat stále starým wrapperem (jediné místo, kde
vysosat wrapper, je totiž konstruktor třídy HelpDescription –
nemůže si vzít jen referenci a wrapper vyhodnotit líně až při
renderování, protože DefaultFormRenderer rozpoznává jen Html
objekty a ty mají render() metodu finální a jako obsah
akceptují jen hotové řetězce nebo jiné Html objekty, takže
nemůžu změnit vykreslování description objektu, aby si vzalo z formuláře
wrapper až při vykreslení – musí být už vyrenderovaný předem –
rovnou při definici vstupního prvku – a pak když se wrapper změní,
tohoto prvku se to už nedotkne).
Alternativou je použít vlastní renderer – podědit po
DefaultFormRendereru a zkopírovat tělo metody
renderControl s pouze drobnou změnou – rozpoznávání
HelpDescription objektů, které by se standardně obalily jako
ostatní, textově zadané description. To je ale o hubu – když se změní
implementace renderControl, může se to rozbít.
Nebylo by na to nějaké koncepční řešení? Třeba obalovat i
Html description wrapperem? Nebo rozšířit
DefaultFormRenderer o detekci i jiných renderovatelných
objektů, které by se tak mohly renderovat líně?