Šablonovací systém Bemplate

22.6.2012

Během hledání cesty k "dokonalému webovému kódu" jsem se dostal k zastávce jménem šablonovací systém. Do této doby jsem si maximálně dělal metody Show() v daných objektech, abych je vykreslil. Z hlediska objektivního programování je to sice správně, ale trochu to nabourává MVC systém.

Každý lepší framework obsahuje nějaký šablonovací systém. Než se s ním programovat, tak jsem nejdříve vyzkoušel Smarty a pak nějaké další, ale byl jsem docela zklamaný. Asi nejlépe mi sedlo Latte, které je použito ve frameworku Nette. Hlavně se mi líbilo, že výpis proměnné je už v základu prohnán funkcí htmlspecialchars, což je nejčastější použití. Některé ostatní šablonovací systémy sice disponovaly tuto možnost nastavit, ale z nějakého důvodu pak nešlo tuto vlastnost zakázat, abych mohl vykreslit přímo HTML kód.

Nevím proč, ale ani jsem se nechtěl snažit vyextrahovat Latte z Nette a prostě jsem si naprogramoval vlastní šablonovací systém, který asi nedosahuje kvalit ostatních šablonovacích systémů, ale cca 90% běžné práce zastane a nebo lze nahradit PHPkem.

Hlavní přednosti

  • je to v jednom jediném souboru 9kB velkém (většina je stejně jen komentář :-) )
  • je to rychlé, protože se to cachuje a překládá do PHP souborů
  • v šablonách lze použít běžný PHP kód, takže co neumí přímo bemplate, tak to můžete napsat pomocí PHP
  • jednoduché na naučení, protože to obsahuje pouze 15 příkazů
  • snadno implementovatelné do projektu díky depenency injection

Na to, že to vzniklo během dvou večerů, je to překvapivě účiné. Nápověda je přímo v souboru a použití poznáte z dema. Přesto zde máte výpis základních funkcí:

  • {$promenna}
    vypise $promennou pomoci htmlspecialchars ... misto promenne jde pouzit i funkce
  • {!$promenna}
    vypise $promennou jako html
  • {; php kod }
    spusti php kod
  • {if podminka} ... {/if}                  
    prelozi na if (podminka)
  • {foreach $pole as $hodnota}            
    prelozi na if ($pole) foreach ($pole as $hodnota), lze pouzit i $key=>$hodnota
    • {first} ... {/first}
      Spustí se při prvním průběhu cyklem. 
    • {last} ... {/last}
      Spustí se při posledním průběhu cyklem.
    • {odd} ... {/odd}
      Spustí se při lichém průběhu cyklu.
    • {even} ... {/even}
      Spustí se při sudém průběhu cyklu.
  • {while podminka}
    prelozi na while (podminka)
  • {include "soubor.bpl"}
    includuje sablonu a preda ji vsechny aktivni promenne
  • {include "soubor.bpl", array('typ' => 123,'nazev'=>'sfds')}
    includuje sablonu a prida k ni parametry
  • {* text komentáře *}
    komentář, bude odstraněn
  • {t $promenna}
    prelozi promenou pres translate fci + htmlspecialchars ... dobre pro jazkove mutace ... funkce translate lze predefinovat
  • {t !$promenna}
    prelozi promenou pres translate fci a vypise ako HTML
  • {? $promenna}
    spusti debug($promenna); ... funkce debug lze predefinovat
  • {; phpkod() }
    spusti php kod a nic nevypisuje
  • {define #Nazev-Bloku} ... {/define}
    definice bloku
  • {include #Nazev-Bloku}
    spusti blok a preda vsechny aktivni promenne
  • {include #Nazev-Bloku, array('typ' => 123,'nazev'=>'sfds')}
    spusti blok a prida take dalsi promenne
  • ... případné další příkazy najdete přimo v souboru bemplate.php

Ukázka definice šablony

<h1>{$nazevStranky}</h1>
<div>{!$htmlPopis}</div>
<div class="Aktuality">
{foreach $aktuality as $item}
{include 'aktualita.bpl', array('aktualita' => $item ) }
{/foreach}</div>

Ukázka použití v PHP

require_once 'bemplate.php';

$tpl=new Bemplate();

$tpl->Set('nazevStranky','Moje aktuality');
$tpl->Set('htmlPopis','Tyhle aktuality jsou <b>super</b>');
$tpl->Set('aktuality',array(
    array('nazev'=>'Nazev1',
        'obsah'=>'proste nejaky html <a href="#">text</a>'
    ),
    array('nazev'=>'Nazev2',
        'obsah'=>'proste nejaky html <a href="#">text</a>'
    ),
    array('nazev'=>'Nazev3',
        'obsah'=>'proste nejaky html <a href="#">text</a>'
    )
));

echo $tpl->Render('templates/index.bpl');

Bemplate ke stažení

Stáhnout bemplate

Komentáře

Přidej svůj komentář

Přidání komentáře

5.7.2012 11:22 - Bogan

{t $promenna} se prelozi na echo htmlspecialchars(translate($promenna)), přičemž funkci translate si můžete určit sami v konfiguraci. Jednoduše bych to řešil tak, že bych napsal {$ [$promenna,'cz']} a v translate funkci bych si detekoval, zda to je pole a v tom případě bych věděl, že první index je text k překladu a druhý je jazyk. Ty hranatý závorky je to samé, co array(), ale je to rychlejší zápis (funguje od PHP 5.4)

Nebo můžeš klidně vlézt do kódu bemplate a udělat si vlastni podporu, protože to je fakt jednoduchý, takže za 5 minut by to umělo to, co potřebuješ.

Ale asi to rozšířím na nepovinný zápis {t $promenna,cz}, což je nejkratší zápis a je jasný, co to bude dělat.

Díky za nápad.

3.7.2012 12:30 - zaza

{t $promenna}

Nesedi me tady jedna vec, co kdyz mam vic jazyku a jak to pozna do ktereho to ma prelozit? Musi bejt key pro preklad primo v promenne nebo muzu nekam napsat jen string? Kdyz budu mit vetsi projekt tak prirazovani do promennych (a tedka kdyz budu mit nedejboze dost textu) tak zbytecne mam alokovat pamet promennyma? :-) Ja kvuli tomuto pouzivam SMARTY protoze obsahuje definice svych vlastnich bloku napr. {translate}translate this key{/translate} kde v metode ktera vola tento blok si nacitam ze sessions aktualni jazyk kde si toho prekladam. Nebo {translate lang='cs'}translate this key{/translate}  Jde tohle v tvem enginu taky nejak nastavit?