This commit is contained in:
2025-05-22 08:18:06 +00:00
parent f3a71e8d12
commit 497e6a0bdf
11 changed files with 320 additions and 32 deletions

View File

@ -4,16 +4,14 @@ namespace Blog\Template;
use Exception;
class Twig {
private $blocks = [];
private $viewsPath;
private $debugMode;
private array $blocks = [];
private string $viewsPath;
public function __construct($viewsPath, $debugMode = false) {
public function __construct($viewsPath) {
$this->viewsPath = rtrim($viewsPath, '/') . '/';
$this->debugMode = $debugMode;
}
public function render($file, $data = []) {
public function render($file, $data = []): string {
try {
$code = $this->includeFiles($file);
$code = $this->compileCode($code);
@ -23,13 +21,11 @@ class Twig {
eval('?>' . $code);
return ob_get_clean();
} catch(Exception $e) {
if($this->debugMode)
echo "Error rendering template: " . $e->getMessage();
throw $e;
throw new Expection("Error rendering template: " . $e->getMessage());
}
}
private function compileCode($code) {
private function compileCode($code): string {
$code = $this->compileBlock($code);
$code = $this->compileYield($code);
$code = $this->compileEchos($code);
@ -37,11 +33,12 @@ class Twig {
return $code;
}
private function includeFiles($file) {
private function includeFiles($file): string {
$filePath = $this->viewsPath . preg_replace("/\.twig$/", "", $file) . ".twig";
if(!file_exists($filePath))
if(!file_exists($filePath)) {
throw new Exception("View file not found: {$filePath}");
}
$code = file_get_contents($filePath);
preg_match_all('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', $code, $matches, PREG_SET_ORDER);
@ -53,33 +50,39 @@ class Twig {
return preg_replace('/{% ?(extends|include) ?\'?(.*?)\'? ?%}/i', '', $code);
}
private function compilePHP($code) {
private function compilePHP($code): string {
return preg_replace('~\{%\s*(.+?)\s*%}~is', '<?php $1 ?>', $code);
}
private function compileEchos($code) {
private function compileEchos($code): string {
$code = preg_replace('~\{\{\s*(.+?)\s*\}\}~is', '<?=$1?>', $code);
return preg_replace('~\{\{\{\s*(.+?)\s*\}\}\}~is', '<?=htmlspecialchars($1, ENT_QUOTES, "UTF-8")?>', $code);
}
private function compileEscapedEchos($code) {
private function compileEscapedEchos($code):string {
return preg_replace('~\{{{\s*(.+?)\s*}}}~is', '<?=htmlentities($1, ENT_QUOTES, "UTF-8")?>', $code);
}
private function compileBlock($code) {
/*
*
*
*/
private function compileBlock($code): string {
preg_match_all('/{% ?block ?(.*?) ?%}(.*?){% ?endblock ?%}/is', $code, $matches, PREG_SET_ORDER);
foreach($matches as $match) {
if(!isset($this->blocks[$match[1]]))
if(!isset($this->blocks[$match[1]])) {
$this->blocks[$match[1]] = '';
}
$this->blocks[$match[1]] = str_replace('@parent', $this->blocks[$match[1]], $match[2]);
$code = str_replace($match[0], '', $code);
}
return $code;
}
private function compileYield($code) {
foreach($this->blocks as $block => $value)
private function compileYield($code): string {
foreach($this->blocks as $block => $value) {
$code = preg_replace('/{% ?yield ?' . $block . ' ?%}/', $value, $code);
}
return preg_replace('/{% ?yield ?(.*?) ?%}/i', '', $code);
}
}