feat: Поддержка psr4. Кеширование шаблона

This commit is contained in:
origami11@yandex.ru 2025-05-21 15:50:17 +03:00
parent 825641813b
commit 0c30dc230d
9 changed files with 71 additions and 61 deletions

1
.gitignore vendored
View file

@ -2,3 +2,4 @@
node_modules node_modules
temp temp
/vendor/ /vendor/
/examples/cache

View file

@ -4,13 +4,13 @@
# Переменные # Переменные
Для переменной name=Андрей шаблон Для переменной name=Ivan шаблон
```html ```html
<b>Hello, {{ name }}</div> <b>Hello, {{ name }}</div>
``` ```
преобразуется в преобразуется в
```html ```html
<b>Hello, Андрей</div> <b>Hello, Ivan</div>
``` ```
```html ```html
@ -18,7 +18,7 @@
``` ```
преобразуется в преобразуется в
```html ```html
<b>Hello, <!-- Андрей --></div> <b>Hello, <!-- Ivan --></div>
``` ```
# Циклы # Циклы

View file

@ -2,15 +2,10 @@
"name": "ctiso/klein", "name": "ctiso/klein",
"description": "simple template engine", "description": "simple template engine",
"license": "MIT", "license": "MIT",
"authors": [ "authors": [],
{
"name": "Phedor Podlesnov",
"email": "phedor@edu.yar.ru"
}
],
"autoload": { "autoload": {
"psr-0": { "psr-4": {
"Klein": "" "ctiso\\": "src/"
} }
}, },
"require": {} "require": {}

View file

@ -1,14 +1,16 @@
<?php <?php
require_once '../Klein.php'; require_once '../src/Klein.php';
use ctiso\Klein;
function title($x) { function title($x) {
return ucfirst($x); return ucfirst($x);
} }
$tpl = new Klein('tempalte.html'); $tpl = new Klein(__DIR__ . '/cache');
echo $tpl->render([ echo $tpl->render('template.html', [
'pagename' => 'awesome people', 'pagename' => 'awesome people',
'authors' => [['name' => 'Paul', 'age' => 10], ['name' => 'Jim', 'age' => 11], ['name' => 'Jane', 'age' => 12]], 'authors' => [['name' => 'Paul', 'age' => 10], ['name' => 'Jim', 'age' => 11], ['name' => 'Jane', 'age' => 12]],
'city'=> [ 'city'=> [

View file

@ -1,34 +1,34 @@
<?php <?php
require_once '../Klein.php';
use ctiso\Klein;
$data = [ $data = [
[ [
'id' => 0, 'id' => 0,
'id_table' => 0, 'id_table' => 0,
'name' => '',
'header' => 'Наименование муниципального образования',
'comment' => '',
'colspan' => 0,
'rowspan' => 4,
'row' => 0,
'position' => 0,
'type' => '',
],
[
'id' => 1,
'id_table' => 0,
'name' => '', 'name' => '',
'header' => '', 'header' => 'Header #1',
'comment' => 'Над строкой - Прибыло всего (взрослых и детей)', 'comment' => '',
'rowspan' => 0, 'colspan' => 0,
'row' => 0, 'rowspan' => 4,
'position' => 1, 'row' => 0,
'type' => '', 'position' => 0,
'type' => '',
],
[
'id' => 1,
'id_table' => 0,
'name' => '',
'header' => '',
'comment' => 'Header #2',
'rowspan' => 0,
'row' => 0,
'position' => 1,
'type' => '',
] ]
]; ];
require_once '../Klein.php'; $tpl = new Klein(__DIR__ . '/cache');
echo $tpl->render('template2.html'. ['content' => $data]);
$tpl = new Klein('template2.html');
echo $tpl->render(['content' => $data]);

View file

@ -1,9 +1,10 @@
<?php <?php
require_once '../Klein.php';
use ctiso\Klein;
$data = ['phedor', 'andrey']; $data = ['phedor', 'andrey'];
require_once '../Klein.php'; $tpl = new Klein(__DIR__ . '/cache');
$tpl = new Klein('template3.html'); echo $tpl->render('template3.html', ['names' => $data]);
echo $tpl->render(['names' => $data]);

View file

@ -1,12 +1,13 @@
<?php <?php
require_once '../Klein.php'; require_once '../Klein.php';
use ctiso\Klein;
function title($x) { function title($x) {
return ucfirst($x); return ucfirst($x);
} }
$tpl = new Klein('template.html'); $tpl = new Klein(__DIR__ . '/cache');
$u1 = new stdClass(); $u1 = new stdClass();
$u1->name = 'Paul'; $u1->name = 'Paul';
@ -20,7 +21,7 @@ $u3 = new stdClass();
$u3->name = 'Jane'; $u3->name = 'Jane';
$u3->age = 12; $u3->age = 12;
echo $tpl->render([ echo $tpl->render('template.html', [
'pagename' => 'awesome people', 'pagename' => 'awesome people',
'authors' => [$u1, $u2, $u3], 'authors' => [$u1, $u2, $u3],
'city'=> [ 'city'=> [

View file

@ -1,7 +1,7 @@
<div> <div>
{% for var in content %} {% for var in content %}
{% for key, value in var %} {% for key, value in var %}
<b>{{key}} - {{value}}</b> <b>{{ key }} - {{ value }}</b>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
</div> </div>

View file

@ -1,9 +1,18 @@
<?php <?php
class Klein { namespace ctiso;
public $code;
function __construct($html) { class Klein {
private $cache;
function __construct($cache) {
$this->cache = $cache;
if (!file_exists($cache)) {
mkdir($cache, 0777, true);
}
}
function compile($html, $target, $hash) {
$pattern = array_map(function ($grammar) { $pattern = array_map(function ($grammar) {
list(, $result) = $grammar; list(, $result) = $grammar;
$body = strtr($grammar[0], [' ' => "\s*", '+' => "\s+", ':var' => "(\w+(\s*\.\s*\w+)*)", ':id' => "(\w+)", '{{' => "{{\!?"]); $body = strtr($grammar[0], [' ' => "\s*", '+' => "\s+", ':var' => "(\w+(\s*\.\s*\w+)*)", ':id' => "(\w+)", '{{' => "{{\!?"]);
@ -15,7 +24,7 @@ class Klein {
$list = preg_split('/\.\s*/', $s); $list = preg_split('/\.\s*/', $s);
$first = array_shift($list); $first = array_shift($list);
return count($list) > 0 ? "Klein::get(".$pref.$first.", [".implode(",", array_map(function ($x) { return "'$x'"; }, $list))."])" : $pref.$first; return count($list) > 0 ? "Klein::get(".$pref.$first.", [".implode(",", array_map(fn ($x) => "'$x'", $list))."])" : $pref.$first;
}, preg_split("/\s*,\s*/", $x[$s[1]]))); }, preg_split("/\s*,\s*/", $x[$s[1]])));
}, $result) . " ?>"; }, $result) . " ?>";
return ($x[0][2] == '!') ? "<!-- $code -->" : $code; return ($x[0][2] == '!') ? "<!-- $code -->" : $code;
@ -38,22 +47,17 @@ class Klein {
["{% endmacro %}", "}"] ["{% endmacro %}", "}"]
]); ]);
$result = file_get_contents($html); $result = "<?php namespace tpl_$hash;\nuse ctiso\Klein; ?>" .file_get_contents($html);
foreach($pattern as $arg) { foreach($pattern as $arg) {
$result = preg_replace_callback($arg[0], $arg[1], $result); $result = preg_replace_callback($arg[0], $arg[1], $result);
} }
file_put_contents($target, $result);
$this->code = $result;
} }
static function get($arr, $items) { static function get($arr, $items) {
$result = $arr; $result = $arr;
foreach ($items as $key) { foreach ($items as $key) {
if (is_array($result)) { $result = (is_array($result)) ? $result[$key] ?? null : $result->{$key} ?? null;
$result = isset($result[$key]) ? $result[$key] : null;
} else {
$result = isset($result->{$key}) ? $result->{$key} : null;
}
} }
return $result; return $result;
} }
@ -66,10 +70,16 @@ class Klein {
, 'even' => $is_even]; , 'even' => $is_even];
} }
function render($vars) { function render($html, $vars) {
$hash = md5($html . filemtime($html));
$target = $this->cache . '/tpl_' . $hash . '.php';
if (!file_exists($target)) {
$this->compile($html, $target, $hash);
}
extract($vars); extract($vars);
ob_start(); ob_start();
eval(" ?>".$this->code."<?php "); include($target);
return ob_get_clean(); return ob_get_clean();
} }
} }