Rozbudowa TemplateEngine – dodanie metody renderTemplate, która będzie renderować prawdziwy template engine. Zaczynamy!
Tworzymy plik sth2.php:
<h1>{{ $site_name }}</h1>
<p> Hello {{ $name }}</p>
Ok, tworzymy metodę renderTemplate:
class TemplateEngine
{
//(...)
public function renderTemplate(string $template, array $data = []){
extract($data, EXTR_SKIP);
extract($this->globalTemplateData, EXTR_SKIP);
$content = file_get_contents($this->resolve($template));
var_dump($content);
}
//(...)
}
$template = new TemplateEngine(__DIR__);
$template->addGlobal('site_name', 'MyApp');
echo $template->renderTemplate('sth2.php', ['name' => 'John']);
Na razie zaciągnęliśmy zawartość pliku – teraz spróbujmy poddać go wyrażeniu regularnemu:
class TemplateEngine
{
//(...)
public function renderTemplate(string $template, array $data = []){
extract($data, EXTR_SKIP);
extract($this->globalTemplateData, EXTR_SKIP);
$content = file_get_contents($this->resolve($template));
var_dump($content);
$pattern = '/\{\{\s*(\$.*?)\s*\}\}/';
preg_match($pattern, $content, $matches);
print_r($matches);
}
}
Teraz musimy jeszcze zamienić wyrażenie regularne na co trzeba:
class TemplateEngine
{
//(...)
public function renderTemplate(string $template, array $data = []){
extract($data, EXTR_SKIP);
extract($this->globalTemplateData, EXTR_SKIP);
$content = file_get_contents($this->resolve($template));
$pattern = '/\{\{\s*(\$.*?)\s*\}\}/';
$content = preg_replace($pattern, "<?=$1; ?>", $content);
var_dump($content);
}
}
Możemy zrobić var_dump, ale niewiele zobaczymy – z jednej strony PHP zostanie przeparsowany, z drugiej zmienne te nie istnieją w danym kontekście. Musimy jeszcze sth2.php nieco zmienić:
<?php ?>
<h1>{{ $site_name }}</h1>
<p> Hello {{ $name }}</p>
Ok, nie musimy – ale chciałem pokazać, co za chwilę zrobi funkcja eval:
class TemplateEngine
{
//(...)
public function renderTemplate(string $template, array $data = []){
extract($data, EXTR_SKIP);
extract($this->globalTemplateData, EXTR_SKIP);
$content = file_get_contents($this->resolve($template));
$pattern = '/\{\{\s*(\$.*?)\s*\}\}/';
$content = preg_replace($pattern, "<?=$1; ?>", $content);
eval( '?>' . $content );
}
//(...)
}
Eval jak działa to domyślnie otwiera tag <?php i nie patrzy na nic. Trzeba więc ten domyślny „domknąć”. A w plikach templatki używać normalnie, według potrzeb.
Ten zbędny zawsze zostanie domknięty. Teraz możemy wypróbować nasz engine:
<?php
class TemplateEngine
{
//(...)
}
$template = new TemplateEngine(__DIR__);
$template->addGlobal('site_name', 'MyApp');
echo $template->renderTemplate('sth2.php', ['name' => 'John']);
Engine będziemy rozbudowywać.