SMARTY – tvorba vlastních pluginů

28. května 2004

Uživatelské funkce distribuované se SMARTY jsou sice dostatečné, ovšem v mnoha případech nevyhovují zcela našim požadavkům. Často se tak dostaneme do situace, kdy budeme chtít vytvořit funkce vlastní, které budou přesně splňovat všechny naše nároky.

Dříve, než se začneme zabývat samotným vytvářením pluginů, musíme si ujasnit, kam budeme vytvořené soubory ukládat. Už několikrát v předešlých článcích jsme si řekli, že funkce používané v šablonách jsou umístěné v adresáři definovaném proměnou $plugins_dir. Totéž platí i pro námi vytvořené pluginy.

Jednou z možností je tedy ukládat námi vytvořené funkce do jednoho adresáře spolu s ostatními pluginy. Jelikož může proměnná $plugins_dir obsahovat i pole hodnot (adresářů), je výhodnější vytvořit zvláštní adresář určený pouze pro naše výtvory. Nastavení této proměnné by mohlo vypadat následovně:

$smarty->plugins_dir = array(‚plugins‘, ‚my_plugins‘);

Jak pluginy fungují

Pluginy jsou standardní funkce, které mají pevně stanovený název a počet i typ parametrů. Každý plugin musí být uložen v samostatném souboru, jehož název také musí odpovídat názvovým konvencím.

Pokud námi vytvořené pluginy odpovídají všem formálním požadavkům, které si ve stručnosti u jednotlivých typů pluginů popíšeme, lze je použít stejně jako nativní funkce SMARTY, se kterými jsme se již setkali. O samotné načtení souboru s funkcí a její zavolání se postará SMARTY, jakmile při zpracování šablony parserem narazí na její název.

Nyní se zaměříme na jednotlivé typy nejčastěji používaných pluginů. U každého typu si kromě popisu a příkladů uvedeme i názvové konvence, které je nutné v případě vytváření dodržet.

Funkce

Název souboru Funkční prototyp Použití v šabloně
function.jmeno_fce.php
např.: function.kalendar.php
smarty_function_jmeno_fce( pole $params, object &$smarty )
např.: smarty_function_kalendar( $params, &$smarty )
{kalendar rok=2004 mesic=2 den=15}

Nejdříve se krátce zastavíme u parametrů funkce. Prvním parametrem je asociativní pole obsahující názvy atributů a jejich hodnoty tak, jak jsou specifikovány v šabloně. Pokud bychom použili výše uvedený příklad, pak by pole parametrů vypadalo následujícím způsobem:

Array
(
   [rok] => 2004
   [mesic] => 2
   [den] => 15
)

Druhým parametrem je odkazem předaný objekt Smarty, který nám umožňuje využívat ve funkcích všech metod a proměnných třídy Smarty. V případě naší funkce kalendar si ukážeme použití metody trigger_error (více viz závěr tohoto článku).

Jako u ostatních funkcí napsaných v PHP, mohou i námi vytvořené pluginy vracet nějakou hodnotu, která bude vložena na odpovídající místo v šabloně. Takovým pluginem je také náš příklad, který bude podle zadaného data vracet název odpovídajícího dne.

function smarty_function_kalendar( $params, &$smarty )
{
   // vytvorime promenne
   extract($params);
      
   // povinne atributy jsou rok, mesic a den
   if ( empty( $rok ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚rok‘ neni zadan“);
      return;
   }// if
   
   if ( empty( $mesic ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚mesic‘ neni zadan“);
      return;
   }// if
      
   if ( empty( $den ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚den‘ neni zadan“);
      return;
   }// if
   // vratime nazev dne odpovidajci zadanemu datumu
   // hodnota bude vlozena v sablone na místo volani pluginu
   return date( „l“, mktime( 0, 0, 0, $mesic, $den, $rok ) );
}// function

Zejména při vytváření větších projektů se dostaneme do situace, kdy budeme chtít využít již naprogramované pluginy v jiné funkci. Jelikož jsou pluginy vlastně obyčejné funkce, nic nám v tom, kromě jejich složitějšího názvu, nebrání. Také nesmíme zapomenout, že prvním parametrem funkce je asociativní pole, které je nutné pro účel volání vytvořit.

My si tento postup ukážeme na příkladu, kdy plugin kalendar, zavolá plugin presne, který vrací počet sekund od 1. 1. 1970 v závislosti na zadaném datu a času.

// nacteni souboru s pomocnou funkci
require_once( SMARTY_DIR.“my_plugins/function.presne.php“ );
function smarty_function_kalendar( $params, &$smarty )
{
   // vytvorime promenne
   extract($params);
      
   // povinne atributy jsou rok, mesic a den
   if ( empty( $rok ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚rok‘ neni zadan“);
      return;
   }// if
   
   if ( empty( $mesic ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚mesic‘ neni zadan“);
      return;
   }// if
      
   if ( empty( $den ) )
   {
      $smarty->trigger_error(„kalendar: parametr ‚den‘ neni zadan“);
      return;
   }// if
   // zjistime presny cas s vyuzitim pomocne funkce presne
   $presne = smarty_function_presne(
         array( „hodina“ => 15, „minuta“ => 0, „den“ => $den, „mesic“ => $mesic, „rok“ => $rok ), &$smarty );
   
   // vratime nazev dne odpovidajci zadanemu datumu
   return date( „l“, $presne );
}// function

Nejen funkce, ale i ostatní typy pluginů lze podobným způsobem využít. Opět s tím, že je nutné dodržet všechny konvence, které SMARTY zavádí.

Modifikátory

Název souboru Funkční prototyp Použití v šabloně
modifier.jmeno_fce.php
např.: modifier.upper.php
smarty_modifier_jmeno_fce( mixed $string, string $parametr, … )
např.: smarty_modifier_upper( $string, $backward = false )
$promena|upper
$promena|upper:true

Jak jsme si již řekli v samostatném článku o modifikátorech, jsou to funkce zaměřené na dodatečné úpravy jim předaných řetězcových nebo numerických hodnot. Tomuto účelu odpovídá i jejich vnitřní struktura

Modifikátory musí mít vždy návratovou hodnotu (musí být ukončeny příkazem return). V popisu modifikátorů jsme také uváděli, že je možné jim předávat různé parametry (oddělené dvojtečkou), které jejich chování dále upravují.

Na následujícím příkladu je uveden jednoduchý modifikátor, který změní první písmeno ve slově na velké. V případě, že nastavíme jeho jediný parametr na TRUE, pak toto slovo vypíše pozpátku.

function smarty_modifier_upper( $string, $back = false )
{
   // chceme slovo pozpatku
   if ( $back )
      return ucFirst( strRev( $string ) );
   else
      return ucFirst( $string );
}// function

Blokové funkce

Název souboru Funkční prototyp Použití v šabloně
block.jmeno_fce.php
např.: block.change.php
smarty_block_jmeno_fce( pole $params, string $cont, object $smarty )
např.: smarty_block_change( $params, $cont, $smarty )
{change}text…{/change}

Funkce, které ohraničují ucelený blok textu nebo kódu stránky, se nazývají blokové funkce. Z pohledu vytváření vlastních funkcí tohoto typu je nutné pamatovat na podstatný rozdíl, kterým se tyto funkce od ostatních odlišují. Námi naprogramovaná funkce je totiž vždy volána dvakrát.

Jako ostatní funkce i blokové mohou mít své parametry, které jsou zapisovány do počátečního tagu v šabloně. Tyto parametry jsou předány námi naprogramované funkci při prvním volání, které proběhne, jakmile se parser při procházení šablony dostane k názvu funkce. Opět jsou parametry zadané v šabloně předány ve formě asociativního pole, které je prvním parametrem samotné funkce.

Podruhé, tentokrát nejen s parametry, ale i s celým textem, který je v šabloně funkcí ohraničen, je funkce zavolána tehdy, když parser narazí na uzavírací tag blokové funkce, přičemž text je obsažen v druhém parametru blokové funkce.

Následující příklad ukazuje jeden z možných způsobů řešení blokové funkce, která zamění každý výskyt slova „text“ za slovo uvedené v atributu replace.

function smarty_block_change( $params, $content, &$smarty )
{
   // cekame az na druhé zavolani funkce, které bude obsahovat parametr $content
   if ( $content )
   {
      extract( $params );
      
      // kontrola parametru
      if ( empty( $replace ) )
      {
         $smarty->trigger_error( „change: parametr ‚replace‘ je spatne zadan“ );
         return;
      }// if
      
      // vytiskni opraveny text
      echo str_replace( „text“, $replace, $content);
   }// if
}// function

Ostatní funkce

Jak jsme již také uvedli v předchozích článcích, existují další typy funkcí (filtry, kompilační funkce a další), které si můžeme naprogramovat. Jelikož se používají spíše výjimečně, nebudeme zde jejich popis uvádět a omezíme se pouze na odkaz do originální dokumentace SMARTY.

Zdroje

Název souboru Funkční prototyp Použití ve skriptu
resource.jmeno_zdroje.php
např.: resource.db.php
smarty_resource_jmeno _zdroje_typ_funkce
funkční prototypy jsou různé pro jednotlivé typy funkcí (viz. příklady)
$smarty->display( "db:index.tpl" );

Asi nejkomplikovanější z hlediska programování je vytvoření vlastního zdroje. V předchozím článku jsme si řekli, že není nutné ukládat šablony jen do adresáře, ale můžeme použít například databázi. Ovšem pokud budeme chtít využít jiný zdroj našich šablon, tak je nutné naprogramovat některé funkce prostřednictvím nichž bude SMARTY tyto šablony načítat.

Pro ilustraci postupu, jakým vytvoříme vlastní zdroj (nazveme jej db), si propůjčíme příklad z oficiální dokumentace, který nám umožní načíst šablonu uloženou v databázi. Pro účely nového zdroje je nutné naprogramovat čtyři obslužné funkce, které SMARTY pro načítání šablon používá.

První je funkce, která se stará o samotné načtení šablony. První parametr funkce ($src_name) obsahuje název šablony, která je uživatelem požadována. Druhý parametr je předáván odkazem a je určen pro uložení načtené šablony. Posledním parametrem je opět odkaz na objekt Smarty.

function smarty_resource_db_source($tpl_name, &$tpl_source, &$smarty)
{
   // pripojme se do databaze,
   $sql = new SQL;
   // vybereme pozadovanou sablonu
   $sql->query(„select tpl_source
         from my_table
         where tpl_name=’$tpl_name'“);
   
   // ulozime ji do promene $tpl_source
   if ($sql->num_rows) {
      $tpl_source = $sql->record[‚tpl_source‘];
      return true;
   } else {
      return false;
   }
}

Jelikož SMARTY zjišťuje také datum poslední modifikace všech použitých šablon, musíme vytvořit nějakou funkci, která tento údaj zjistí. V našem případě budeme předpokládat, že datum poslední modifikace je uložen ve stejné tabulce jako samotná šablona. Tato funkce má obdobné parametry jako funkce předcházející. Opět si všimněme, že získaný čas je ukládán jako číslo do druhého parametru funkce.

function smarty_resource_db_timestamp($tpl_name, &$tpl_timestamp, &$smarty)
{
   // pripojime se do databaze.
   $sql = new SQL;
   // vybereme pozadovanou hodnotu pomoci SQL prikazu
   $sql->query(„select tpl_timestamp
         from my_table
         where tpl_name=’$tpl_name'“);
   // ulozime hdonotu jako integer do promene $tpl_timestamp
   if ($sql->num_rows) {
      $tpl_timestamp = $sql->record[‚tpl_timestamp‘];
      return true;
   } else {
      return false;
   }
}

Poslední dvě funkce určují, zda jsou šablony a kód PHP načítané prostřednictvím příkazu include_php a insert bezpečné. Obě tyto funkce vrací boolean hodnotu podle toho, zda je požadována šablona (pro niž se používá funkce smarty_resource_db_secure) nebo PHP skript (pro který se používá funkce smarty_resource_db_trusted). V našem příkladě vrací pro všechny soubory obě funkce hodnotu TRUE.

function smarty_resource_db_secure($tpl_name, &$smarty)
{
   // vsechny sablony jsou bezpecne
   return true;
}
function smarty_resource_db_trusted($tpl_name, &$smarty)
{
   // to plati i pro PHP skripty
   return true;
}

Pokud tedy všechny tyto funkce uložíme do jednoho souboru nazvaného resource.db.php, pak můžeme ve svých šablonách použít svůj zdroj tak, jak jsme to uvedli v předchozím článku.

Užitečné tipy

U většiny pluginů je k dispozici jako parametr odkaz na objekt Smarty, který se vyplatí využívat v případě, že kontrolujete obsah povinných a nepovinných atributů jednotlivých funkcí. V takových případech jsou k dispozici metody třídy Smarty, které můžeme použít pro výpis chybového hlášení. Konkrétně se jedná o metodu trigger_error.

Jelikož jsou parametry funkcí zadané v šabloně předávány funkci ve formě asociativního pole, je vhodné použít příkaz extract, který vytvoří z jednotlivých klíčů pole proměnné s odpovídající hodnotou.

Možností, jimiž lze upravit chování vlastních pluginů, je v rámci systému SMARTY opravdu mnoho. Velkou část, například dynamicky registrované pluginy, jsme zde nezmínili, přestože jde o zajímavou schopnost tohoto systému. Více podrobností najdete na odpovídajících stránkách oficiálního manuálu.

Odkazy, zdroje

Starší komentáře ke článku

Pokud máte zájem o starší komentáře k tomuto článku, naleznete je zde.

Předchozí článek nokturno.net
Další článek sigmafotbal.cz
Štítky: Články

Mohlo by vás také zajímat

Nejnovější

Napsat komentář

Vaše e-mailová adresa nebude zveřejněna. Vyžadované informace jsou označeny *