更新默认模板引擎功能
This commit is contained in:
parent
75a0127d60
commit
68d36f27d2
|
@ -85,15 +85,6 @@ class Engine
|
||||||
return self::$instance;
|
return self::$instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* 外部加载扩展标签
|
|
||||||
* @param $lib
|
|
||||||
*/
|
|
||||||
public function loadTaglib($lib)
|
|
||||||
{
|
|
||||||
$this->extend[] = $lib;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 处理模板继承
|
* 处理模板继承
|
||||||
* @param $template
|
* @param $template
|
||||||
|
@ -101,11 +92,11 @@ class Engine
|
||||||
*/
|
*/
|
||||||
private function parseExtend($template)
|
private function parseExtend($template)
|
||||||
{
|
{
|
||||||
$pattern = '#' . $this->left . 'extend +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
|
$pattern = '/' . $this->left . 'extend.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is';
|
||||||
preg_match($pattern, $template, $matches);
|
preg_match($pattern, $template, $matches);
|
||||||
if (!empty($matches)) {
|
if (!empty($matches)) {
|
||||||
$blockPattern = '#' . $this->left . 'block +name=[\'"](.*?)[\'"]' . $this->right;
|
$blockPattern = '/' . $this->left . 'block.*?name=[\'"](.*?)[\'"]' . $this->right;
|
||||||
$blockPattern .= '([\s\S]*?)' . $this->left . '\/block' . $this->right . '#';
|
$blockPattern .= '([\s\S]*?)' . $this->left . '\/block' . $this->right . '/is';
|
||||||
// 获得被继承的模板内容
|
// 获得被继承的模板内容
|
||||||
$file = $this->config['dir'] . $matches[1] . '.html';
|
$file = $this->config['dir'] . $matches[1] . '.html';
|
||||||
$extendFileContent = null;
|
$extendFileContent = null;
|
||||||
|
@ -154,14 +145,14 @@ class Engine
|
||||||
*/
|
*/
|
||||||
private function parseInclude($template)
|
private function parseInclude($template)
|
||||||
{
|
{
|
||||||
$pattern = '#' . $this->left . 'include +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
|
$pattern = '/' . $this->left . 'include.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is';
|
||||||
$template = preg_replace_callback($pattern, function ($result) {
|
$template = preg_replace_callback($pattern, function ($result) {
|
||||||
$str = null;
|
$string = null;
|
||||||
$file = $this->config['dir'] . $result[1] . '.html';
|
$file = $this->config['dir'] . $result[1] . '.html';
|
||||||
if (file_exists($file)) {
|
if (file_exists($file)) {
|
||||||
$str = file_get_contents($file);
|
$string = file_get_contents($file);
|
||||||
}
|
}
|
||||||
return $str;
|
return $string;
|
||||||
}, $template);
|
}, $template);
|
||||||
// 处理多层include
|
// 处理多层include
|
||||||
if ($this->hasInclude($template)) {
|
if ($this->hasInclude($template)) {
|
||||||
|
@ -177,7 +168,7 @@ class Engine
|
||||||
*/
|
*/
|
||||||
private function hasInclude($template)
|
private function hasInclude($template)
|
||||||
{
|
{
|
||||||
$pattern = '#' . $this->left . 'include +file=[\'"](.*?)[\'"] +/' . $this->right . '#';
|
$pattern = '/' . $this->left . 'include.*?file=[\'"](.*?)[\'"].*?\/' . $this->right . '/is';
|
||||||
preg_match($pattern, $template, $matches);
|
preg_match($pattern, $template, $matches);
|
||||||
return !empty($matches);
|
return !empty($matches);
|
||||||
}
|
}
|
||||||
|
@ -189,7 +180,7 @@ class Engine
|
||||||
*/
|
*/
|
||||||
private function parseVars($template)
|
private function parseVars($template)
|
||||||
{
|
{
|
||||||
preg_match_all('#{(.*?)}#', $template, $matches);
|
preg_match_all('/{(.*?)}/', $template, $matches);
|
||||||
$search = [];
|
$search = [];
|
||||||
$replace = [];
|
$replace = [];
|
||||||
for ($i = 0; $i < count($matches[0]); $i++) {
|
for ($i = 0; $i < count($matches[0]); $i++) {
|
||||||
|
@ -207,6 +198,15 @@ class Engine
|
||||||
return $template;
|
return $template;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 外部加载扩展标签
|
||||||
|
* @param $lib
|
||||||
|
*/
|
||||||
|
public function loadTaglib($lib)
|
||||||
|
{
|
||||||
|
$this->extend[] = $lib;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 标签处理
|
* 标签处理
|
||||||
* @param $template
|
* @param $template
|
||||||
|
@ -228,18 +228,19 @@ class Engine
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取标签处理结果
|
* 获取标签处理结果
|
||||||
* @param $name
|
* @param $method
|
||||||
* @param $tagContent
|
* @param $tag
|
||||||
* @return mixed
|
* @param string $content
|
||||||
|
* @return null
|
||||||
*/
|
*/
|
||||||
private function getTagParseResult($name, $tagContent = [])
|
private function getTagParseResult($method, $tag, $content = '')
|
||||||
{
|
{
|
||||||
if (method_exists($this, $name)) {
|
if (method_exists($this, $method)) {
|
||||||
return $this->{$name}($tagContent);
|
return $this->{$method}($tag, $content);
|
||||||
} else {
|
} else {
|
||||||
foreach ($this->extendInstance as $item) {
|
foreach ($this->extendInstance as $item) {
|
||||||
if (method_exists($item, $name)) {
|
if (method_exists($item, $method)) {
|
||||||
return $item->{$name}($tagContent);
|
return $item->{$method}($tag, $content);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -255,31 +256,97 @@ class Engine
|
||||||
private function _parseTags($template, $tags)
|
private function _parseTags($template, $tags)
|
||||||
{
|
{
|
||||||
foreach ($tags as $name => $item) {
|
foreach ($tags as $name => $item) {
|
||||||
$pattern = '#' . $this->left . $name . '(.*?)' . ($item['close'] ? null : '\/') . $this->right . '#';
|
$pattern = '/' . $this->left . '(?:(' . $name . ')\b(?>[^' . $this->right . ']*)|\/(' . $name . '))';
|
||||||
preg_match_all($pattern, $template, $matches);
|
$pattern .= $this->right . '/is';
|
||||||
for ($i = 0; $i < count($matches[0]); $i++) {
|
if ($item['close']) {
|
||||||
$tag = [];
|
preg_match_all($pattern, $template, $matches, PREG_SET_ORDER | PREG_OFFSET_CAPTURE);
|
||||||
if ($item['attr']) {
|
$nodes = [];
|
||||||
$attrPattern = '#(.*?)=[\'"](.*?)[\'"]#';
|
if (!empty($matches)) {
|
||||||
preg_match_all($attrPattern, $matches[1][$i], $result);
|
// 将匹配结果组合为成对数组
|
||||||
if (isset($result[0]) && !empty($result[0])) {
|
$start = [];
|
||||||
foreach ($result[1] as $key => $value) {
|
foreach ($matches as $match) {
|
||||||
$tag[trim($value, ' ')] = $result[2][$key];
|
// 为空则为结束标签
|
||||||
|
if ($match[1][0] == '') {
|
||||||
|
$tag = array_pop($start);
|
||||||
|
$nodes[$match[0][1]] = [
|
||||||
|
'name' => $name,
|
||||||
|
'start' => $tag[1],
|
||||||
|
'end' => $match[0][1],
|
||||||
|
'start_str' => $tag[0],
|
||||||
|
'end_str' => $match[0][0],
|
||||||
|
];
|
||||||
|
} else {
|
||||||
|
$start[] = $match[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset($matches, $start);
|
||||||
|
krsort($nodes);
|
||||||
|
|
||||||
|
if (!empty($nodes)) {
|
||||||
|
$nodes = array_merge($nodes, []);
|
||||||
|
$cut = '<!--CONTENT-->';
|
||||||
|
$method = '_' . $name;
|
||||||
|
$startArray = [];
|
||||||
|
foreach ($nodes as $pos => $node) {
|
||||||
|
$attr = $item['attr'] ? $this->getAttr($node['start_str'], explode(',', $item['attr'])) : [];
|
||||||
|
// 得到准备替换的值
|
||||||
|
$replace = explode($cut, $this->getTagParseResult($method, $attr, $cut));
|
||||||
|
while ($startArray) {
|
||||||
|
$begin = end($startArray);
|
||||||
|
// 如果当前结束位置大于最后一个开始标签的位置,则跳过,直接去替换这个结束标签
|
||||||
|
if ($node['end'] > $begin['start']) {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// 否则先替换掉这个标签后面的所有开始标签
|
||||||
|
$begin = array_pop($startArray);
|
||||||
|
$template = substr_replace($template, $begin['string'], $begin['start'], $begin['length']);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$template = substr_replace($template, $replace[1], $node['end'], strlen($node['end_str']));
|
||||||
|
$startArray[] = [
|
||||||
|
'start' => $node['start'],
|
||||||
|
'length' => strlen($node['start_str']),
|
||||||
|
'string' => $replace[0]
|
||||||
|
];
|
||||||
|
}
|
||||||
|
// 替换掉最后入栈,未进入while循环的开始标签
|
||||||
|
while ($startArray) {
|
||||||
|
$begin = array_pop($startArray);
|
||||||
|
$template = substr_replace($template, $begin['string'], $begin['start'], $begin['length']);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$function = ($item['close']) ? '_' . $name . '_start' : '_' . $name;
|
} else { // 自闭合标签处理
|
||||||
$template = str_replace($matches[0][$i], $this->getTagParseResult($function, $tag), $template);
|
$template = preg_replace_callback($pattern, function ($matches) use ($item) {
|
||||||
}
|
$method = '_' . $matches[1];
|
||||||
if ($item['close']) {
|
$attr = $item['attr'] ? $this->getAttr($matches[0], explode(',', $item['attr'])) : [];
|
||||||
$closePattern = '#' . $this->left . '\/' . $name . $this->right . '#';
|
return $this->getTagParseResult($method, $attr);
|
||||||
$template = preg_replace_callback($closePattern, function () use ($name) {
|
|
||||||
$function = '_' . $name . '_end';
|
|
||||||
return $this->getTagParseResult($function);
|
|
||||||
}, $template);
|
}, $template);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return preg_replace('#\?>([\r|\n|\s]*?)<\?php#', '', $template);
|
return preg_replace('/\?>([\r|\n|\s]*?)<\?php/is', '', $template);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取属性
|
||||||
|
* @param $string
|
||||||
|
* @param array $tags
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function getAttr($string, $tags = [])
|
||||||
|
{
|
||||||
|
$attr = [];
|
||||||
|
$attrPattern = '/[ +](.*?)=[\'"](.*?)[\'"]/is';
|
||||||
|
preg_match_all($attrPattern, $string, $result);
|
||||||
|
if (isset($result[0]) && !empty($result[0])) {
|
||||||
|
foreach ($result[1] as $key => $value) {
|
||||||
|
$name = trim($value, ' ');
|
||||||
|
if (in_array($name, $tags)) {
|
||||||
|
$attr[$name] = $result[2][$key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return $attr;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -289,15 +356,15 @@ class Engine
|
||||||
*/
|
*/
|
||||||
private function parseRaw($template)
|
private function parseRaw($template)
|
||||||
{
|
{
|
||||||
$pattern = '#' . $this->left . 'raw' . $this->right . '([\s\S]*?)';
|
$pattern = '/' . $this->left . 'raw' . $this->right . '([\s\S]*?)';
|
||||||
$pattern .= $this->left . '\/raw' . $this->right . '#';
|
$pattern .= $this->left . '\/raw' . $this->right . '/is';
|
||||||
$template = preg_replace_callback($pattern, function ($matches) {
|
$template = preg_replace_callback($pattern, function ($matches) {
|
||||||
return str_replace([
|
return str_replace([
|
||||||
$this->left, $this->right,
|
$this->left, $this->right,
|
||||||
'{', '}'
|
'{', '}'
|
||||||
], [
|
], [
|
||||||
'<raw!--', '--raw>',
|
'<RAW!--', '--RAW>',
|
||||||
'<-raw!--', '--raw->'
|
'<RAW!--', '--RAW>'
|
||||||
], $matches[1]);
|
], $matches[1]);
|
||||||
}, $template);
|
}, $template);
|
||||||
return $template;
|
return $template;
|
||||||
|
@ -311,8 +378,8 @@ class Engine
|
||||||
public function returnRaw($template)
|
public function returnRaw($template)
|
||||||
{
|
{
|
||||||
$template = str_replace([
|
$template = str_replace([
|
||||||
'<raw!--', '--raw>',
|
'<RAW!--', '--RAW>',
|
||||||
'<-raw!--', '--raw->'
|
'<RAW!--', '--RAW>'
|
||||||
], [
|
], [
|
||||||
$this->left, $this->right,
|
$this->left, $this->right,
|
||||||
'{', '}'
|
'{', '}'
|
||||||
|
@ -322,47 +389,35 @@ class Engine
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* php标签开始
|
* php标签开始
|
||||||
|
* @param $tag
|
||||||
|
* @param $content
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function _php_start()
|
private function _php($tag, $content)
|
||||||
{
|
{
|
||||||
return '<?php ';
|
return '<?php ' . $content . ' ?>';
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* php标签结束
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function _php_end()
|
|
||||||
{
|
|
||||||
return ' ?>';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if标签
|
* if标签
|
||||||
* @param $tag
|
* @param $tag
|
||||||
|
* @param $content
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function _if_start($tag)
|
private function _if($tag, $content)
|
||||||
{
|
{
|
||||||
return '<?php if (' . $tag['condition'] . '): ?>';
|
$parse = '<?php if (' . $tag['condition'] . '): ?>';
|
||||||
|
$parse .= $content;
|
||||||
|
$parse .= '<?php echo ' . $tag['condition'] . '; endif; ?>';
|
||||||
|
return $parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* if标签结束
|
* else标签
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function _if_end()
|
|
||||||
{
|
|
||||||
return '<?php endif; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* else标签(支持条件)
|
|
||||||
* @param $tag
|
* @param $tag
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function _else_start($tag)
|
private function _else($tag)
|
||||||
{
|
{
|
||||||
if (isset($tag['condition'])) {
|
if (isset($tag['condition'])) {
|
||||||
$parse = '<?php elseif (' . $tag['condition'] . '): ?>';
|
$parse = '<?php elseif (' . $tag['condition'] . '): ?>';
|
||||||
|
@ -375,44 +430,23 @@ class Engine
|
||||||
/**
|
/**
|
||||||
* volist标签
|
* volist标签
|
||||||
* @param $tag
|
* @param $tag
|
||||||
|
* @param $content
|
||||||
* @return string
|
* @return string
|
||||||
*/
|
*/
|
||||||
private function _volist_start($tag)
|
private function _volist($tag, $content)
|
||||||
{
|
{
|
||||||
if (substr($tag['name'], 0, 1) == ':') {
|
$parse = '<?php ' . (isset($tag['key']) ? '$' . $tag['key'] . ' = 0; ' : '');
|
||||||
$name = substr($tag['name'], 1);
|
$parse .= 'foreach($' . $tag['name'] . ' as ' . (isset($tag['index']) ? '$' . $tag['index'] . '=>' : '') . '$' . $tag['id'] . '): ';
|
||||||
} else {
|
$parse .= (isset($tag['key']) ? '$' . $tag['key'] . '++;' : '') . ' ?>';
|
||||||
$name = '$' . $tag['name'];
|
$parse .= $content;
|
||||||
}
|
$parse .= '<?php endforeach; ?>';
|
||||||
$key = (empty($tag['key'])) ? null : '$' . $tag['key'] . ' = 0;';
|
|
||||||
$parse = '<?php ' . $key . ' foreach (' . $name . ' as $' . $tag['id'] . '): ';
|
|
||||||
$parse .= ($key ? '$' . $tag['key'] . '++;' : null) . ' ?>';
|
|
||||||
return $parse;
|
return $parse;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* volist标签结束
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function _volist_end()
|
|
||||||
{
|
|
||||||
return '<?php endforeach; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* assign标签
|
|
||||||
* @param $tag
|
|
||||||
* @return string
|
|
||||||
*/
|
|
||||||
private function _assign($tag)
|
|
||||||
{
|
|
||||||
return '<?php $' . $tag['name'] . ' = ' . $tag['value'] . '; ?>';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 获取编译后的内容
|
* 获取编译后的内容
|
||||||
* @param $template
|
* @param $template
|
||||||
* @return bool|mixed|null|string|string[]
|
* @return mixed|null|string|string[]
|
||||||
*/
|
*/
|
||||||
public function compile($template)
|
public function compile($template)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue