Template parser
Ik ben bezig met het bouwen van een eigen templateparser. Ik heb een begin gemaakt (nog zonder foutafhandeling en dergelijke), maar vraag me nu het volgende af..
Stel ik haal alle nieuwsitems op uit een database en wil deze weergeven in een template. Normaal ken ik een waarde toe aan ik een variabele door gebruik te maken van de functie assign. In dit geval zijn het meerdere waardes(een array). Hoe kan ik deze toekennen/weergeven?
Stel ik haal alle nieuwsitems op uit een database en wil deze weergeven in een template. Normaal ken ik een waarde toe aan ik een variabele door gebruik te maken van de functie assign. In dit geval zijn het meerdere waardes(een array). Hoe kan ik deze toekennen/weergeven?
Code (php)
Code (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
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
// templateparser.class.php
<?php
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function assign($pattern, $recplacement)
{
$this->_content = preg_replace("#\{".$pattern ."\}#si", $replacement, $this->_content);
}
public function display()
{
return $this->_content;
}
}
?>
<?php
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function assign($pattern, $recplacement)
{
$this->_content = preg_replace("#\{".$pattern ."\}#si", $replacement, $this->_content);
}
public function display()
{
return $this->_content;
}
}
?>
Gewijzigd op 20/10/2012 14:52:27 door Roy B
vergeet het woord assign.
je kunt een complete array in je class opslaan of een object (lees andere class)
je kunt een complete array in je class opslaan of een object (lees andere class)
Code (php)
Code (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
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
<?php
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function assign($arr)
{
$this->_content = $arr;
}
public function display()
{
return $this->_content; // dit dan wel even in de view/template splitten
// bijv. als echo $content['title'];
}
}
?>
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function assign($arr)
{
$this->_content = $arr;
}
public function display()
{
return $this->_content; // dit dan wel even in de view/template splitten
// bijv. als echo $content['title'];
}
}
?>
Gewijzigd op 20/10/2012 15:27:02 door Frank Nietbelangrijk
Dat zou inderdaad kunnen. Maar stel ik wil de laatste 5 nieuwsitems weergeven. Hoe kan ik dan bijvoorbeeld de titel van de nieuwsitems weergeven?
een extra variabele aan de class toevoegen en een getfunctie/setfunctie
Code (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
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
<?php
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
private $title;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function getTitle)
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function display()
{
return $this->_content; // dit dan wel even in de view/template splitten
// bijv. als echo $content['title'];
}
}
?>
class Templateparser
{
private $_template;
private $_template_dir = "/templates/";
private $_content;
private $title;
public function __construct($template)
{
$this->_template = $template;
if(file_exists($this->_template_dir.$template))
{
$this->_content = file_get_contents($this->_template_dir.$template);
}
}
public function getTitle)
{
return $this->title;
}
public function setTitle($title)
{
$this->title = $title;
}
public function display()
{
return $this->_content; // dit dan wel even in de view/template splitten
// bijv. als echo $content['title'];
}
}
?>
Gewijzigd op 23/10/2012 13:10:42 door Frank Nietbelangrijk
@Roy: even uit nieuwsgierigheid... hoe ziet zo'n template eigenlijk eruit?
@Ozzie,
Hieronder een voorbeeldje.. In dit geval is {content} een stukje tekst, maar stel dat het nu om een nieuwspagina gaat, dan wil ik i.p.v. {content} de laatste 5 nieuwsberichten weergeven.
Hieronder een voorbeeldje.. In dit geval is {content} een stukje tekst, maar stel dat het nu om een nieuwspagina gaat, dan wil ik i.p.v. {content} de laatste 5 nieuwsberichten weergeven.
Code (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
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
<!DOCTYPE html>
<html>
<head>
<title>{title}</title>
<link href="images/wec5.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="styles/default.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="container">
<div id="header">
{title}
</div>
<ul id="menu">
<li><a class="menuitem active" href="home.html">Home</a></li>
<li><a class="menuitem" href="nieuws.html">Nieuws</a></li>
<li><a class="menuitem" href="portfolio.html">Portfolio</a></li>
<li><a class="menuitem" href="contact.html">Contact</a></li>
</ul>
<div id="content">
{content}
</div>
<div id="footer">
</div>
</div>
</body>
</html>
<html>
<head>
<title>{title}</title>
<link href="images/wec5.ico" rel="shortcut icon" type="image/x-icon"/>
<link href="styles/default.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="container">
<div id="header">
{title}
</div>
<ul id="menu">
<li><a class="menuitem active" href="home.html">Home</a></li>
<li><a class="menuitem" href="nieuws.html">Nieuws</a></li>
<li><a class="menuitem" href="portfolio.html">Portfolio</a></li>
<li><a class="menuitem" href="contact.html">Contact</a></li>
</ul>
<div id="content">
{content}
</div>
<div id="footer">
</div>
</div>
</body>
</html>
Gewijzigd op 23/10/2012 14:49:08 door Roy B
Dan zorg je er toch gewoon voor dat de data die je weg wil schrijven in {content} als vooraf is gegenereerd. Op deze manier maakt het dan niks uit wat voor data je erin zet.
Op dit moment kun je met deze code dus alleen teksten kwijt. Als je de content voordat je het in de variabele $this->_content opslaat door een controller haalt die alles in een view opslaat kan je de view in de variabele $this->_content opslaan. Zo geef je jezelf meer vrijheid met de data die je wegschrijft naar de template.
Op dit moment kun je met deze code dus alleen teksten kwijt. Als je de content voordat je het in de variabele $this->_content opslaat door een controller haalt die alles in een view opslaat kan je de view in de variabele $this->_content opslaan. Zo geef je jezelf meer vrijheid met de data die je wegschrijft naar de template.
Ja, precies.
Je slaat alle content op in een variabele.
Op het allerlaatste moment haal je alles door je parser.
Je kan natuurlijk je class uitbreiden, waardoor dit alles binnen de class wordt verwerkt.
bv. een methode append($pattern, $item)
Je slaat alle content op in een variabele.
Op het allerlaatste moment haal je alles door je parser.
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?php
... // SELECT ... FROM nieuwsitems ...
$content = "";
while ($row = mysql_fetch_assoc($res)) {
$content .= '<div class="nieuwsitem"><h2>' . $row['titel'] ...
}
...
$template->assign("content", $content);
echo $template->display();
?>
... // SELECT ... FROM nieuwsitems ...
$content = "";
while ($row = mysql_fetch_assoc($res)) {
$content .= '<div class="nieuwsitem"><h2>' . $row['titel'] ...
}
...
$template->assign("content", $content);
echo $template->display();
?>
Je kan natuurlijk je class uitbreiden, waardoor dit alles binnen de class wordt verwerkt.
bv. een methode append($pattern, $item)
Is dit eigenlijk gebruikelijk om op deze manier met templates te werken? Wat is het verschil met het gebruiken van variabelen, bijv.
in plaats van
In het 1e geval hoef je alleen de template te includen, en je hoeft niet eerst het bestand in te lezen en dingen te vervangen. Het lijkt mij dat dat beter is voor de performance?
in plaats van
In het 1e geval hoef je alleen de template te includen, en je hoeft niet eerst het bestand in te lezen en dingen te vervangen. Het lijkt mij dat dat beter is voor de performance?
Beide komen voor, ja.
Er zijn verschillende systemen die je als gebruikelijk kan beschouwen.
Tja ... 't is aan de template parser zo intelligent als nodig te zijn.
Wat mij betreft, vind ik dat een template parser een vrij eenvoudig ding is.
Bestand lezen ( file_get_contents() ) en een placeholder vervangen ( str_replace() ). Voor mij is er weinig extra nodig.
Andere scripters steken er dan weer wat meer tijd in en leveren dit pareltje
http://www.phphulp.nl/php/script/data-verwerking/bbcode-parser-v-01/1558/bbcodeparserv01/1143/
Er zijn verschillende systemen die je als gebruikelijk kan beschouwen.
Tja ... 't is aan de template parser zo intelligent als nodig te zijn.
Wat mij betreft, vind ik dat een template parser een vrij eenvoudig ding is.
Bestand lezen ( file_get_contents() ) en een placeholder vervangen ( str_replace() ). Voor mij is er weinig extra nodig.
Andere scripters steken er dan weer wat meer tijd in en leveren dit pareltje
http://www.phphulp.nl/php/script/data-verwerking/bbcode-parser-v-01/1558/bbcodeparserv01/1143/
@Ozzie,
Om antwoord te geven op uw vraag.. Op de tweede manier is de code gescheiden van de html en zodoende de template makkelijker aan te passen of te vervangen.
Om antwoord te geven op uw vraag.. Op de tweede manier is de code gescheiden van de html en zodoende de template makkelijker aan te passen of te vervangen.
Ozzie, lees eens dit topic. Daar discussiëren een aantal voorstanders en een aantal tegenstanders met elkaar: http://www.phphulp.nl/php/forum/topic/template-engine-doen-of-niet-doen/83080/
Gewijzigd op 23/10/2012 16:51:35 door Wouter J
Wat betreft Ozie's voorbeelden ben ik het met Ozzie eens. De eerste is véél sneller zowel met het ontwikkelen van je applicatie als in het gebruik. Echter er is een maar. De tweede is met name geschikt als gebruikers - die niet aan de code mogen komen - zelf hun template mogen maken en/of aanpassen. er dient natuurlijk dan wel een mooie handleiding geschreven te worden over de notatie, de keywords etc. Om dit goed te doen is er een grote investering nodig in tijd. En als je dat dan al gaat doen, ben je niet het wiel opnieuw aan het uitvinden? ik durf eigenlijk al te beweren van wel. Er zal vast wel een mooie PHP library te vinden zijn die dit allemaal voor je regelt.
Frank.
Frank.
Thanks voor jullie antwoorden. De nadelige bijdrage aan de performance zou voor mij een reden zijn om niet voor een template parser te kiezen.
Ozzie, performance hoeft er helemaal niet aan te leiden. Laat ik Twig als voorbeeld nemen. Zodra deze in de productie omgeving zit cached hij bij het allereerste bezoek van de allereerste bezoeker, dus niet per bezoeker, alle pagina's als of het een gewone PHP template was. Zeg maar:
Hierdoor is er geen sprake meer van een template parser in de productie omgeving.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
Twig template
=============
{% for article in articles %}
<h1>{{ article.title }}</h1>
<p>{{ article.intro }}</p>
{% endfor %}
Gecachede template
==================
<?php foreach ($articles as $article) : ?>
<h1><?= $article['title'] ?></h1>
<p><?= $article['intro'] ?></p>
<?php endforeach ?>
=============
{% for article in articles %}
<h1>{{ article.title }}</h1>
<p>{{ article.intro }}</p>
{% endfor %}
Gecachede template
==================
<?php foreach ($articles as $article) : ?>
<h1><?= $article['title'] ?></h1>
<p><?= $article['intro'] ?></p>
<?php endforeach ?>
Hierdoor is er geen sprake meer van een template parser in de productie omgeving.
Ah zo... ik snap wat je bedoelt. Maar ik vind het net zo makkelijk om rechtstreeks de php code te typen :)
Maar voor iemand die niet kan programmeren kan ik me voorstellen dat het handig zou kunnen zijn.
Maar voor iemand die niet kan programmeren kan ik me voorstellen dat het handig zou kunnen zijn.
Ozzie, het heeft nog meer voordelen. Bijv. auto-escaping, template inhertance, het limiteren van wat een webdesigner kan doen, ect.
Ja, maar ik zie voor mezelf (op dit moment) nog niet echt voordelen. Ik zal me er binnenkort nog wat meer in verdiepen en wie weet stel ik m'n mening dan nog bij...
Dank je Wouter.
Kijk eens op http://twig.sensiolabs.org/..
Dit zijn toch hele belangrijke punten. even wat copy-paste:
Documented: Twig is fully documented, with a dedicated online book, and of course a full API documentation.
Secure: When it comes to security, Twig has some unique features:
Automatic output escaping: To be on the safe side, you can enable automatic output escaping globally or for a block of code
Fast: One of the goals of Twig is to be as fast as possible. To achieve the best speed possible, Twig compiles templates down to plain optimized PHP code. The overhead compared to regular PHP code was reduced to the very minimum.
Toevoeging op 23/10/2012 23:53:10:
Vooral de laatste spreekt me wel aan: To achieve the best speed possible, Twig compiles templates down to plain optimized PHP code..
Ga dat maar even zelf maken.
Overigens snap ik Roy ook wel, je hebt een idee en je wil dat uitvoeren. Bovendien is dat goed voor je skills.
Kijk eens op http://twig.sensiolabs.org/..
Dit zijn toch hele belangrijke punten. even wat copy-paste:
Documented: Twig is fully documented, with a dedicated online book, and of course a full API documentation.
Secure: When it comes to security, Twig has some unique features:
Automatic output escaping: To be on the safe side, you can enable automatic output escaping globally or for a block of code
Fast: One of the goals of Twig is to be as fast as possible. To achieve the best speed possible, Twig compiles templates down to plain optimized PHP code. The overhead compared to regular PHP code was reduced to the very minimum.
Toevoeging op 23/10/2012 23:53:10:
Vooral de laatste spreekt me wel aan: To achieve the best speed possible, Twig compiles templates down to plain optimized PHP code..
Ga dat maar even zelf maken.
Overigens snap ik Roy ook wel, je hebt een idee en je wil dat uitvoeren. Bovendien is dat goed voor je skills.
Gewijzigd op 23/10/2012 23:56:16 door Frank Nietbelangrijk
Frank, ook een Symfony gebruiker? :) Ik ben over het algemeen niet zo'n voorstander van het wiel opnieuw uitvinden, maar als leerproces is het inderdaad erg geschikt!
Wouter nee hoor, al wil ik nog wel eens mijn licht er mee opsteken. Ik gebruik Codeigniter. Lekker licht.




