[PHP] Eigen Template Engine en tables/forms

Pagina: 1
Acties:
  • 103 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik vraag me nu al een hele tijd af wat de beste manier is om in een eigen template engine met tabellen om te gaan. Is het het beste om een soort van loop tag te maken die door een array variabele heenloopt en rijen aan de tabel toevoegd of is het beter om 1 table tag te maken die een tabel-object invoegd. Dit tabel object wordt dan in het in de tabel weer te geven object aangemaakt en door de template engine vertaald in html

Ook met formulieren twijfel ik, is een formulier object het beste of een template met een formulier dat wordt uitgebreid met een array met initiele waardes etc.

Mijn vraag is eigenlijk hoe anderen dit hebben opgelost?

[ Voor 9% gewijzigd door Verwijderd op 24-03-2006 09:52 ]


Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

php IS een template engine... Waarom een template engine met logica over een über template engine met logica heen plakken?

Voer gewoon je 'template engine' lappen standaard html, en style deze met css. Dat scheelt overhead, onnodige code en je maakt het jezelf heel wat makkelijker :)

Mijn eigen template engine vervangt eigenlijk alleen variabelen die tussen { } staan in een lap tekst door andere variabelen, meer hoeft het niet te doen:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
<?


class templateengine
{
    var $template, $templateValues, $availableValues;
    function __construct($filename='')
    {   
        $this->template = $filename;
        $this->availableValues = array();
        $this->templateValues = array();

    }

    function __set($key, $val)
    {
        $this->availableValues[$key] = $val;
    }

    function __get($key)
    {
        if (array_key_exists($key, $this->availableValues))
        {
            return ($this->availagbleValues[$key]);
        }
        return false;
    }

    function feedValues($input)
    {
        foreach ($input as $key=>$val)
        {
            $this->availableValues[$key] = $val;
        }
    }

    function loadTemplate($template)
    {
        $this->template = $template;
    }

    function grabValues($input)
    {
        preg_match_all('!\{(.*)\}!Uis', $input, $output);
        return($output);
    }


    // php4 fallback. php5 werkt met __get en __set
    function feedValue($key, $val)
    {
        $this->availableValues[$key] = $val;
    }

    function run()
    {
        $tpl = file_get_contents($this->template);
        $this->templateValues = $this->grabValues($tpl);
        for ($i=0; $i<sizeof($this->templateValues[1]); $i++)
        {
            $tpl = str_replace($this->templateValues[0][$i], stripslashes($this->availableValues[$this->templateValues[1][$i]]), $tpl);
        }
        return ($tpl);  
    }
}

//usage:
$tpl = new templateEngine('./includes/template.inc.php');
$tpl->title = $title;
$tpl->body = '<b>kwaak</b>';
$tpl->footer = $footer;
die($tpl->run());

[ Voor 14% gewijzigd door SchizoDuckie op 24-03-2006 09:59 ]

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Dat is niet eens zoveel anders als hoe ik het doe, maar de vraag blijft hoe je dan om gaat met objecten waarvan de properties in een tabel moeten worden weergegevens of via een form moeten worden aangepast...

Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 16-09 16:02

JHS

Splitting the thaum.

In mijn ogen de makkelijkste manier:
PHP:
1
2
3
4
5
6
7
8
<table>
<? foreach($items as $item) { ?>
  <tr>
    <td><?=$item['title']?></td>
    <td><?=$item['content']?></td>
  </tr>
<? } ?>
</table>
En als je dat per sé in de vorm van een non-PHP template-taal zou willen doen zou ik in de vorm van templatecode iets maken wat zichzelf vertaalt naar het bovenstaande. Je kan dat generiek doen:
code:
1
2
3
4
5
6
7
8
<table>
{loop items}
  <tr>
    <td>{title}</td>
    <td>{content}</td>
  </tr>
{end}
</table>
Maar dan zie ik de meerwaarde niet zo. Je zou het ook specifieker kunnen doen, maar dan moet je heel veel template tags gaan aanmaken, en bovendien wordt het dan moeilijker om custom html in te mixen.

DM!


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Maar een table klasse maken die wordt gebruikt door objecten om hun gegevens in weer te geven en vervolgens door de template engine wordt ingevoegd in {table1} of iets dergelijks is geen goed idee? De manier waarop een table wordt weergegeven kan dan altijd nog via css worden geregeld...

Acties:
  • 0 Henk 'm!

  • JHS
  • Registratie: Augustus 2003
  • Laatst online: 16-09 16:02

JHS

Splitting the thaum.

Dat is inderdaad de manier waarop ik het altijd deed/doe. Ik creeërde een DomDocument object welke ik door PHP om liet zetten naar HTML. Ik vind het persoonlijk een geweldige manier van werken, maar het betekend wel dat je erg goed moet nadenken over waar je die objecten aan laat maken en hoe je ze toevoegd. Daarnaast moet je goed nadenken over standaard classes die repetente functionaliteit overnemen.

Ik had een BaseDomObject class, een MainDom object, een DomNode object en bijvoorbeeld een DomTable class die de DomNode extende. Mijn Binder creeërde dan het MainDomObject, en in de View voegde ik daar dan nodes aan toe.

edit:
Relevante php.net pagina's:
DOM Functions
DOMImplementation
DOMImplentation ->createDocument()
DOMDocument->createElement()
DOMDocument->saveHTML()

[ Voor 31% gewijzigd door JHS op 24-03-2006 11:33 ]

DM!


Acties:
  • 0 Henk 'm!

  • ReverendBizarre
  • Registratie: December 2001
  • Laatst online: 24-03-2021
Ik ben niet zo'n voorstander van complexe templating methodes en van het encapsuleren van HTML elementen (tables, forms, etc.) in objecten. Ik zie er het voordeel niet zo van. Het is een enorm gedoe en uiteindelijk schiet je er niet zo gek veel mee op. Ik hou het graag zo flexibel mogelijk zowel vanaf de kant van de business logic als de presentatie door ze gewoon compleet gescheiden te houden maar op een simpele manier. In de business logic maak je een Template object aan die je een template file mee geeft en je vult het met data, en de template file zoekt maar lekker zelf uit hoe die data uiteindelijk in de pagina verwerkt wordt. Ik zie echt totaal het nut er niet van om je eigen loop structuren te gaan schrijven als PHP dat zelf net zo goed (of beter want PHP is gewoon sneller) kan.

Het doel van het gebruiken van een template systeem zou moeten zijn om je business logic en je presentatie laag te scheiden. Niet om je HTML en je PHP te scheiden.

Dit heb ik toevallig een paar dagen terug geschreven voor een intranet wat ik aan het ontwikkelen ben voor mijn stage:

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
    class Template
    {
        private $templateFile;
        private $templateVarArray = array();
        
        
        function __construct($filename)
        {
            $this->setTemplateFile($filename);
        }
        
        
        public function setTemplateFile($filename)
        {
            if (!file_exists($filename))
            {
                //throw exception
            }
            $this->templateFile = $filename;
        }


        public function setTemplateData($dataArray)
        {
            $this->templateVarArray = $dataArray;
        }

        
        public function clearTemplateData()
        {
            unset($this->templateVarArray);
        }
        
        
        public function setVar($varname, $data)
        {
            $this->templateVarArray[$varname] = $data;
        }


        public function unsetVar($varname)
        {
            unset($this->templateVarArray[$varname]);
        }
        
        
        public function writeHTML()
        {
            $TEMPLATE_VARS = &$this->templateVarArray;
            require($this->templateFile);
        }
        
        
        public function writeHTMLToString()
        {
            ob_start();
            $this->writeHTML();
            return ob_get_clean();
        }
    }


Voorbeeld template:
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<body>

   blabla

   <table border=1>
<?php
    foreach($TEMPLATE_VARS['testvars'] as $testvar)
    {
        echo '<tr><td>' . $testvar['id'] . '</td><td>' . $testvar['name'] . '</td></tr>';
    }
?>
    </table>

   blabla

</body>
</html>


Gebruik:
PHP:
1
2
3
4
5
6
7
8
9
        // ... db query ofzo waar $rows uitkomt ...

    $template = new Template('./templates/test.template');
    $template->setVar('testvars', $rows);
 
        // ... code waar template verder gevuld kan worden met vanalles ...

        // einde van business logic, render HTML
    $template->writeHTML();


Op deze manier kan je ook templates nesten als je dat wilt (dus een template in een template hangen, of de string output van een template in een andere template hangen).

Acties:
  • 0 Henk 'm!

  • NLChris
  • Registratie: Juli 2004
  • Laatst online: 20-09 11:41
Ik vind dit een erg mooie simpele oplossing:

http://www.massassi.com/php/articles/template_engines/

Acties:
  • 0 Henk 'm!

  • DexterDee
  • Registratie: November 2004
  • Laatst online: 13:59

DexterDee

I doubt, therefore I might be

Ik lees zo de discussie in dit topic en ervaar een algehele neiging naar het niet gebruiken van een template framework. Het staat mij natuurlijk vrij om het daarmee niet eens te zijn. Voordat ik mijn argumentatie en voorbeelden op tafel gooi wil ik eerst zeggen dat het mijn persoonlijk mening is en dat ik volledig op de hoogte ben van de wellus-nietus discussie omtrend dit onderwerp :)

Ik ben werkzaam bij een bedrijf dat grote en kleine PHP projecten doet. Soms 2 weken werk, maar het kan ook wel eens 8 maanden duren. Omdat we een multi-disciplinaire software development afdeling zijn, doe ik meer dan PHP alleen. Een van onze best practices is het werken volgens het MVC model. Dit model zoals velen weten scheidt de business logica van de weergave en je datasource. Om een 3-tier benadering te krijgen in onze PHP projecten hebben we strategisch gekozen voor smarty (http://smarty.php.net). Na tientallen projecten met smarty als template framework ben ik overtuigd van de helderheid en snelheid in gebruik. Mijn ervaring is dat zowel piepkleine als megagrote projecten baat hebben bij het volgen van dit framework om code van de weergave te scheiden. Door de beperkte maar zeer krachtige set aan placeholders kan voorgrondlogica erg makkelijk aangebracht worden, terwijl de echte business logica in de PHP blijft.

Een praktijkvoorbeeldje hoe in smarty een dynamische tabel opgebouwd wordt: (gesimplificeerd)
HTML:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<table width="100%" cellpadding="0" cellspacing="0" class="normal">
    <tr>
        {* DISPLAY HEADER *}
        <th class="left" width="55%"0%">Name</th>
        <th class="left" width="35%">Approver(s)</th>
        <th class="left" width="5%"%">Edit</th>
        <th class="both" width="5%">Remove</th>
    </tr>   
{foreach name=level item=column from=$level_data}
    <tr class="sep">
        <td>{$column.organization}</td>
        <td>{$column.approvers}</td>
        <td><a href="name.php?id={$column.id}&mode=edit"></a></td>
        <td><a href="name.php?level={$current_level}&delete_level={$column.id}&mode=delete"</a></td>
    </tr>
{foreachelse}
    <tr>
        <td colspan="4">There are no sublevels for the current level</td>
    </tr>
{/foreach}
</table>
Dit is de code om de benodigde tabel data op te halen: (ezSQL framework btw)
PHP:
1
2
$level_data = $db->get_row("SELECT * FROM levels WHERE id={$level_id}", ARRAY_A);
$smarty->assign('level_data', $level_data);
In bovenstaand voorbeeld is het genoeg om in PHP met een simpele smarty assign de variabele $level_data te vullen met een associative array. De uitzonderingssituatie indien de array leeg mocht zijn is ook erg makkelijk te bewerkstelligen.

Het grote pluspunt van bovenstaande constructie is dat met een beetje oefening en handigheid, deze even snel te maken is dan een "reguliere" constructie. Het is echter in mijn ogen veel beter leesbaar en dus ook beter onderhoudbaar.

De reden dat ik smarty als template engine gebruik is omdat het uiterst krachtig is en toch simpel is opgezet. Ik ben er nog niks in tegengekomen dat ik niet makkelijk voor elkaar kreeg. De meerwaarde is juist om op een hele simpele manier bepaalde repeterende stukken code op te lossen. Voorbeeldje is de set van HTML form elementen. Met een placeholder kan ik gemakkelijk van een PHP array een dropdown combo, radio of checkboxes maken.
HTML:
1
2
3
<select name=user>
{html_options values=$id output=$names selected="5"}
</select>
Zal worden gerendered als:
HTML:
1
2
3
4
5
6
7
<select name=user>
<option label="bob" value="1">bob</option>
<option label="jim" value="2">jim</option>
<option label="joe" value="3">joe</option>
<option label="jerry" value="4">jerry</option>
<option label="fred" value="5" selected="selected">fred</option>
</select>
Er zijn maar weinig template engines die dit in huis hebben. Als je er eenmaal mee gewend bent is de kans groot dat je niks anders meer wilt :)

Smarty heeft ook de eigenschap dat het alle onbekende tags rechtsreeks doorgeeft aan de HTML, zodat je bij afwijkende HTML nog steeds consistent gebruik kunt maken van smarty.

Met templates in templates kun je heel makkelijk modulaire stukken maken als headers en footers, zonder daar in je PHP code rekening mee te houden.

Check ook de crash course van smarty: http://smarty.php.net/crashcourse.php
Die legt de basis functionaliteit op een heldere manier uit en laat snel zien wat de meerwaarde is van dit framework.

Klik hier om mij een DM te sturen • 3245 WP op ZW

Pagina: 1