Vlastní makro pro label – rozlišení párového a nepárového zápisu

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
sKopheK
Člen | 207
+
0
-

(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í.