SectionManager – nadpisy vždy ve správné úrovni

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

Ahoj, momentálně si hraju s takovou malinkou věcičkou, kterou jsem si pro moje potřeby napsal. Myslím, že by se mohla hodit i ostatním.

Definice problému: Jistě to znáte, máte presenter, který má pod sebou několik controlů, které se do sebe nějak zanořují. Běžně je v praxi potřeba v rámci šablony jednoho controlu nějak oddělit jednotlivé části (sekce), nejlépe nějakými nadpisy. Když si představíme stránku tak, jak bude vygenerovaná, můžeme chtít například něco takového:

<?php
<h1>Moje úžasná stránka</h1>
  <h2>Sekce A</h2>
  <h2>Sekce B</h2>
    <h3>Sekce C</h3>
    <h3>Sekce D</h3>
  <h2>Sekce E</h2>
?>

Jedna možnost je, že to prostě nakopírujeme do šablon presenteru a controlů. To bude (snad) fungovat dobře do té doby, než se rozhodneme to celé nějak přeuspořádat, třeba sekci C nezanořit, ale dát ji přímo jako samostatnou sekci. Minimálně to pro nás znamená, že musíme daný control přehodit na místo, kde by se měl vykreslovat. Nesmíme ale zapomenout, že v šabloně toho controlu máme špatnou úroveň nadpisů, tu musíme taky změnit.

Asi si říkáte, proč vás tady otravuju něčím, co je jednoduše vyřešené, ale… Představte si, že ten stejný control vykreslujete ve více presenterech a v jiných úrovních zanoření, to už se pak dá těžko nějak ručně vyplnit správná úroveň nadpisu.

Pro tyhle potřeby jsem si vytvořil takovou malinkou třídu, která mi umožňuje automaticky dosazovat nadpisy s jejich správnými úrovněmi. Funguje to tak, že do kódu šablon jsem si přidal dvě makra (párová makra): section a heading. Section mi řeší to zanoření (vlastně si počítá, v jaké úrovni jsem) a heading jen vypíše správný tag. Použití je pak následující:

@layout.phtml:

<?php
{heading}Moje úžasná stránka{/heading}

{section}
  {heading}Sekce A{/heading}
  {widget sectionA}

  {heading}Sekce B{/heading}
  {widget sectionB}

  {heading}Sekce E{/heading}
  {widget sectionE}
{/section}
?>

sectionB.phtml:

<?php
{section}
  {heading}Sekce C{/heading}
  {heading}Sekce D{/heading}
{/section}
?>

Section je samozřejmě možné použít i jako n-atribut, např. <div n:section>…</div>.

Kód té třídy vypadá takto:

<?php
class SectionManager extends Object {
    /**
     * Counters
     *
     * @var integer
     */
    private static $counter = 0;

    public function __construct() {
        throw new LogicException();
    }

    public static function goUp() {
        if (self::$counter !== 5)
            self::$counter++;
    }

    public static function goDown() {
        if (self::$counter !== 0)
            self::$counter--;
    }

    public static function getHeadingLevel() {
        return (self::$counter + 1);
    }

    public static function register() {
        LatteMacros::$defaultMacros['section'] = '<?php SectionManager::goUp(); ?>';
        LatteMacros::$defaultMacros['/section'] = '<?php SectionManager::goDown(); ?>';
        LatteMacros::$defaultMacros['heading'] = '<?php echo "<h" . SectionManager::getHeadingLevel() . ">"; ?>';
        LatteMacros::$defaultMacros['/heading'] = '<?php echo "</h" . SectionManager::getHeadingLevel() . ">"; ?>';
    }
}
?>

Je to zatím ve stádiu použitelného vývoje a oceňuji jakékoliv poznámky ohledně vylepšení funkcionality a kódu jako takového.

EDIT: <h7> není ;)

Editoval Petr Motejlek (6. 5. 2010 15:59)

norbe
Backer | 405
+
0
-

No musím říct, že to je bezva nápad :-)