Iedereen die iets of wat op een professionele manier bezig is met het maken van websites, heeft al wel van Smarty gehoord. Smarty is een tool die je toelaat om PHP code volledig te scheiden van de manier waarop de site wordt getoond. Deze blogpost dient echter niet om Smarty toe te lichten, want daar vind je genoeg informatie over op het internet. Wat deze blogpost wel zal doen, is uitleggen hoe je Smarty kan integreren in CodeIgniter, want daarover is bijzonder weinig (goede) informatie te vinden.
Waarom zit het niet standaard in CodeIgniter?
Daar zijn 2 goede redenen voor. De eerste is de meest voor de hand liggende. CodeIgniter heeft namelijk zijn eigen manier om om te gaan met templates. In CodeIgniter termen noemen deze ‘view files’. Telkens wanneer je het volgende doet, roep je dus eigenlijk een template aan.
$this->load->view('home', $data);
Een andere mogelijke reden waarom Smarty niet standaard bij CodeIgniter wordt geleverd is omdat er meerdere mogelijkheden zijn. Smarty is wel de bekendste, maar zeker niet de enige template engine. Een template engine biedt natuurlijk vele voordelen waaronder caching, afscherming van de PHP code voor designers, handige tags, etc.
Waar zetten we Smarty?
De eerste stap is natuurlijk het uploaden van de Smarty bestanden naar je webhost. De beste locatie om deze te plaatsen vind ik persoonlijk de libraries map onder system/application/. Dit enerzijds omdat Smarty een library is die je zal gebruiken en anderszijds omdat ik al mijn eigen uitbreidingen in die map plaats. Zo blijven alle zelfgemaakte bestanden mooi bij elkaar en kan ik beter het overzicht behouden. Mijn system/application/libraries map zie je links op de afbeelding.
Zoals je ziet heb ik de originele naam van de Smarty map behouden. Hierdoor kan ik makkelijk zien welke versie ik heb wanneer er updates uitkomen. Deze naam mag je uiteraard zelf kiezen, maar ik zou de bestanden wel in een map houden, ook weer om het overzicht te behouden.
Noot: wanneer je werkt met meerdere applicaties op één CodeIgniter installatie, kan het handig zijn om deze map in system/libraries te plaatsen. Op die manier hoef je maar één keer Smarty te uploaden in plaats van één keer voor elke applicatie.
De Smarty klasse
Het is uiteraard niet voldoende om gewoon de map te uploaden naar je server. Het Smarty object moet bereikbaar zijn vanuit de CodeIgniter klassen (meestal vanuit een controller). Een klasse toevoegen aan het CodeIgniter framework is helemaal niet moeilijk, eerst moet je de klasse uiteraard schrijven en deze daarna gewoon automatisch inladen met behulp van autoload.php.
Zoals je uit de onderstaande code kan afleiden, heb ik deze klasse de naam ‘S’ gegeven. Ik heb gekozen om ‘S’ als naam te nemen in plaats van ‘MY_Smarty’ om de simpele reden dat ‘S’ korter is dan ‘MY_Smarty’ (en omdat ‘Smarty’ al gereseveerd is door … jawel … Smarty zelf). Wanneer ik nu een template aanroep hoef ik dus niet altijd
$this->my_smarty->display('home');
te gebruiken, maar simpelweg
$this->s->display('home');
wat in de grotere applicaties toch al snel heel wat typwerk minder is. De hardcore Smarty fans zien ook meteen dat ik de extensie .tpl kan weglaten bij het aanroepen van een template. Deze ‘functionaliteit’ is ook voorzien in de S klasse.
Zoals je op de afbeelding van mijn bestandsstructuur al kon zien, heb ik gewoon een bestandje S.php aangemaakt in de system/application/libraries/ map. De inhoud van dit bestand is als volgt:
<?php require_once "Smarty-2.6.22/Smarty.class.php"; class S extends Smarty { function S() { $this->Smarty(); // Het config object van CodeIgniter ophalen $config =& get_config(); // Aan de hand van de config de mappen die Smarty zal gebruiken instellen $this->template_dir = (!empty($config['smarty_template_dir']) ? $config['smarty_template_dir'] : BASEPATH . 'application/views/'); $this->compile_dir = (!empty($config['smarty_compile_dir']) ? $config['compile_dir'] : BASEPATH . 'cache/'); // base_url is een handige functie, die willen we altijd bij ons hebben // In een Smarty template kunnen we dan gewoon {$base_url} gebruiken if (function_exists('base_url')) { $this->assign('base_url', base_url()); } $this->clear_all_cache(); } function display($resource_name) { // .tpl toevoegen indien dit niet in het gevraagde bestand staat if (strpos($resource_name, '.tpl') === false) { $resource_name .= '.tpl'; } // Hier kan je allerlei code toevoegen die moet gebeuren vlak voor het tonen van de pagina // De pagina tonen return parent::display($resource_name); } }
Let op: de compile map die je aangeeft moet schrijfbaar zijn door de webserver. Ik gebruik altijd 777, maar misschien is minder ook al goed. Kan iemand dat duidelijk maken?
De S klasse moet natuurlijk in het CodeIgniter framework worden ingeladen voordat je deze kan gebruiken in een controller. Hiervoor open je gewoon system/application/config/autoload.php en voeg je bij het ‘libraries’ onderdeel de ‘S’ klasse toe als volgt:
$autoload['libraries'] = array('s');
Wat met $smarty.session?
CodeIgniter maakt, zoals je misschien weet, geen gebruik van de globale $_SESSION variabele van PHP. Om gegevens bij te houden, maakt CI gebruik van cookies en/of een database (kan je instellen in het config bestand). Dit brengt echter wel een minpunt met zich mee in dit geval. Smarty kan namelijk de $_SESSION variabele aanspreken met behulp van $smarty.session. Maar aangezien CI hier geen gebruik van maakt, is dit niet mogelijk
Maar voor elk probleem is natuurlijk een oplossing. Ik heb in de display functie van de S klasse een stukje code geschreven dat alle gegevens uit $this->session (de plaats waar CI alle sessiegegevens opslaat) haalt en ze doorgeeft aan Smarty. Dit is makkelijk te doen met een foreach, maar dat laat ik als uitstekende oefening voor thuis.
Een klein voorbeeldje
system/application/controllers/Voorbeeld.php
<?php class Voorbeeld extends Controller { function index() { $tekst = 'hello world...'; $this->s->assign('tekst', $tekst); $this->s->display('voorbeeld'); } }
system/application/views/voorbeeld.tpl
Dit is de doorgegeven tekst:<br /> <br /> {$tekst}


Mooie blogpost !
Wat ik zelf ook nog als functie hebt geschreven in mijn smarty class is een “nabootsing” van de standaard view(“pagename,”datarray”) functie van CI.
Heel dom en waarschijnlijk onhandig voor de meesten ==>
function view($templateName, $data)
{
foreach($data as $dataKey => $dataValue)
{
$this->assign($dataKey,$dataValue);
}
$this->display($templateName);
}
Grtz,
Thomas
Op zich geen slecht idee, die view functie. Zo hoef je niet meteen alle controllers te herschrijven en kan je je eerst focussen op het leren van de Smarty syntax.
In een later stadium zou ik toch eerder de standaard functies van Smarty gebruiken, gewoon al ‘omdat het zo hoort’. Verder is het ook niet zòveel verschil omdat je toch nog altijd $this->s-> ervoor moet typen, dus ik zou gewoon volledig overstappen van in het begin in plaats van in kleine stapjes, maar das natuurlijk jouw keuze
Btw: er volgen zeker nog uitbreidingen op deze display functie, zoals bijvoorbeeld de broncode op 1 lijn doorgeven naar de bezoekers, alle html commentaren eruit gooien, etc.
@Thomas,
Zeker niet dom en onhandig hoor die functie, ze zit trouwens al vaak standaard in verschillende tutorials online enzow.
@Maarten welkom op de blog, hopelijk krijgen we regelmatig iets van je te horen
Waarschijnlijk niet, who cares about die domme CI eh
. Zend Framework will rule the world
fanboyism is a wonderful thing…
@Maarten Tibau kzalt onthoude zelle