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
temp
/vendor/
/examples/cache

View file

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

View file

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

View file

@ -1,14 +1,16 @@
<?php
require_once '../Klein.php';
require_once '../src/Klein.php';
use ctiso\Klein;
function title($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',
'authors' => [['name' => 'Paul', 'age' => 10], ['name' => 'Jim', 'age' => 11], ['name' => 'Jane', 'age' => 12]],
'city'=> [

View file

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

View file

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

View file

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

View file

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

View file

@ -1,9 +1,18 @@
<?php
class Klein {
public $code;
namespace ctiso;
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) {
list(, $result) = $grammar;
$body = strtr($grammar[0], [' ' => "\s*", '+' => "\s+", ':var' => "(\w+(\s*\.\s*\w+)*)", ':id' => "(\w+)", '{{' => "{{\!?"]);
@ -15,7 +24,7 @@ class Klein {
$list = preg_split('/\.\s*/', $s);
$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]])));
}, $result) . " ?>";
return ($x[0][2] == '!') ? "<!-- $code -->" : $code;
@ -38,22 +47,17 @@ class Klein {
["{% endmacro %}", "}"]
]);
$result = file_get_contents($html);
$result = "<?php namespace tpl_$hash;\nuse ctiso\Klein; ?>" .file_get_contents($html);
foreach($pattern as $arg) {
$result = preg_replace_callback($arg[0], $arg[1], $result);
}
$this->code = $result;
file_put_contents($target, $result);
}
static function get($arr, $items) {
$result = $arr;
foreach ($items as $key) {
if (is_array($result)) {
$result = isset($result[$key]) ? $result[$key] : null;
} else {
$result = isset($result->{$key}) ? $result->{$key} : null;
}
$result = (is_array($result)) ? $result[$key] ?? null : $result->{$key} ?? null;
}
return $result;
}
@ -66,10 +70,16 @@ class Klein {
, '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);
ob_start();
eval(" ?>".$this->code."<?php ");
include($target);
return ob_get_clean();
}
}