Vlastní makro pro label – rozlišení párového a nepárového zápisu
- sKopheK
- Člen | 207
(Nette 2.1dev)
Ahoj,
při vypisování formulářových prvků po jednom se u povinných prvků k <label>u nepřidává class „required“, proto jsem si napsal vlastní makro pro výpis <label>u. Narazil jsem však na problém, že se nedá rozlišit, zda je v šabloně napsáno {label x}text{/label} nebo {label x /}, tzn. kdy má makro vypisat i text labelu a kdy ne, jak je tomu standardně u vestavěného makra. Při pátrání v kódu Nette\Latte\Compiler se v metodě processMacroTag u tokenu ještě ví, jak bylo přesně makro v šabloně zapsáno, do metody openMacro a dál se to už v žádném parametru nedostane (nebo jsem něco přehlédl?).
Přikládám kód pro vlastní vykreslení labelu. Navázané je všechno v pořádku.
use Nette\Latte\MacroNode,
Nette\Latte\PhpWriter;
class CustomFormMacros extends \Nette\Latte\Macros\MacroSet
{
public static function install(\Nette\Latte\Compiler $compiler)
{
$set = new static($compiler);
$set->addMacro('label', callback($set, 'macroLabelRequiredStart'), callback($set, 'macroLabelRequiredEnd'), NULL);
}
public function macroLabelRequiredStart(MacroNode $node, PhpWriter $writer)
{
$cmd = '
$_input = is_object(%node.word) ? %node.word : $_form[%node.word];
if ($_label = $_input->getLabel())
{
$attributes = %node.array;
$css_class = isset($_input->getLabelPrototype()->class) ? (array)$_input->getLabelPrototype()->class : array();
if ($_input->required)
{
$css_class[] = "required";
}
if ($_input->hasErrors())
{
$css_class[] = "error";
}
if (count($css_class) > 0)
{
$attributes += array("class" => join(" ", $css_class));
}
echo $_label->addAttributes($attributes)->startTag();
';
if ($node->isEmpty = (substr($node->args, -1) === '/'))
{
$cmd .= 'echo $_label->getText();';
}
$cmd .= '}';
return $writer->write($cmd);
}
public function macroLabelRequiredEnd(MacroNode $node, PhpWriter $writer)
{
return $writer->write('?></label><?php');
}
}
Podmínku
if ($node->isEmpty = (substr($node->args, -1) === '/'))
jsem našel v některém ze starých vláken ohledně vlastních maker, nyní je však zbytečná, protože v property args nic není. Jediné řešení, se kterým jsem přišel, je vypisovat text labelu vždy, což však není úplně ideální.