搜索
系统检测到您的用户名不符合规范:

tp6模板block多继承修复(测试)

浏览:805 发布日期:2020年04月23日 分类:ThinkPHP6专区 关键字: block,tp6,thinkphp6,block嵌套
如题,目前我自己使用暂时没有发现什么问题,一起交流下看看怎么改进。
模板文件位置为:\vendor\topthink\think-template\src\Template.php。

由于模板继承(extend)只能解析一次block正好今天遇到这个问题就顺手研究了一下,修复后可使用如下代码{extend name="base/frame" /}


{block name="head"}

{block name="base_css"}{/block}

{block name="css"}{/block}

{block name="base_js"}{/block}

{block name="js"}{/block}

{/block}


{block name="body"}

{block name="base_main"}

{include file="base/page-head" /}

{block name="main"}{/block}

{include file="base/footer" /}
{/block}

{block name="base_bottom"}{/block}

{block name="bottom"}{/block}

{:hook('bottom')}

{/block}
修改代码如下:新增2个方法,改进模板的parseExtend方法 /**
* 修复parent值被替换
* @param $blocks
* @param $_blocks
* @return array
*/
private function mergeBlock(&$blocks, $_blocks)
{
if (is_array($blocks)) {
foreach ($_blocks as $_block => $_values) {
if (array_key_exists($_block, $blocks)) {
$blocks[$_block]['content'] = $_values['content'];
} else {
$blocks[$_block] = $_values;
}
}
} else {
$blocks = [];
}

return $blocks;
}

/**
* 替换嵌套的block
* @param $blocks
* @param string $pKey
* @param string $key
* @return mixed
*/
private function updateBlocks(&$blocks, $pKey = '', $key = '')
{
$begin = $this->config['tpl_begin'];
$end = $this->config['tpl_end'];

if (empty($pKey) && empty($key)) {
foreach ($blocks as $k => $v) {
if (!empty($blocks[$k]['parent'])) {
$this->updateBlocks($blocks, $blocks[$k]['parent'], $k);
}
}
} else {
if (isset($blocks[$pKey]) && isset($blocks[$key])) {
$pBlock = &$blocks[$pKey];
$block = &$blocks[$key];

$search = "/{$begin}block name=\"{$key}\"{$end}[\s\S]*?{$begin}\/block{$end}/";
$replace = $block['content'];

$pBlock['content'] = preg_replace($search, $replace, $pBlock['content']);

if (!empty($pBlock['parent'])) {
$this->updateBlocks($blocks, $pBlock['parent'], $key);
}
}
}

return $blocks;
}

/**
* 解析模板中的extend标签
* @access private
* @param string $content 要解析的模板内容
* @return void
*/
private function parseExtend(string &$content): void
{
$regex = $this->getRegex('extend');
$array = $blocks = $baseBlocks = [];
$extend = '';

$func = function ($template) use (&$func, &$regex, &$array, &$extend, &$blocks, &$baseBlocks) {
if (preg_match($regex, $template, $matches)) {
if (!isset($array[$matches['name']])) {
$array[$matches['name']] = 1;
// 读取继承模板
$extend = $this->parseTemplateName($matches['name']);

// 递归检查继承
$func($extend);

// 取得block标签内容
$blocks = $this->mergeBlock($blocks, $this->parseBlock($template));//修复点1

return;
}
} else {
// 取得顶层模板block标签内容
$baseBlocks = $this->parseBlock($template, true);

if (empty($extend)) {
// 无extend标签但有block标签的情况
$extend = $template;
}
}
};

$func($content);

$blocks = $this->updateBlocks($blocks);//修复点2

if (!empty($extend)) {
if ($baseBlocks) {
$children = [];
foreach ($baseBlocks as $name => $val) {
$replace = $val['content'];

if (isset($children[$name]) && is_array($children[$name])) {
// 如果包含有子block标签
foreach ($children[$name] as $key) {
$replace = str_replace($baseBlocks[$key]['begin'] . $baseBlocks[$key]['content'] . $baseBlocks[$key]['end'], $blocks[$key]['content'], $replace);
}
}

if (isset($blocks[$name])) {
// 带有{__block__}表示与所继承模板的相应标签合并,而不是覆盖
$replace = str_replace(['{__BLOCK__}', '{__block__}'], $replace, $blocks[$name]['content']);

if (!empty($val['parent'])) {
// 如果不是最顶层的block标签
$parent = $val['parent'];

if (isset($blocks[$parent])) {
$blocks[$parent]['content'] = str_replace($blocks[$name]['begin'] . $blocks[$name]['content'] . $blocks[$name]['end'], $replace, $blocks[$parent]['content']);
}

$blocks[$name]['content'] = $replace;
$children[$parent][] = $name;

continue;
}
} elseif (!empty($val['parent'])) {
// 如果子标签没有被继承则用原值
$children[$val['parent']][] = $name;
$blocks[$name] = $val;
}

if (!$val['parent']) {
// 替换模板中的顶级block标签
$extend = str_replace($val['begin'] . $val['content'] . $val['end'], $replace, $extend);
}
}
}

$content = $extend;
unset($blocks, $baseBlocks);
}
}
上传不了附件,可以自行按照代码修改测试。
最佳答案
评论() 相关
后面还有条评论,
评论支持使用[code][/code]标签添加代码
您需要登录后才可以评论 登录 | 立即注册
收藏
有妳、真好
积分:1898 等级:LV3
热点推荐
(追記) (追記ここまで)
最新更新

我们

合作

网站

信息

ThinkPHP 是一个免费开源的,快速、简单的面向对象的 轻量级PHP开发框架 ,创立于2006年初,遵循Apache2开源协议发布,是为了敏捷WEB应用开发和简化企业应用开发而诞生的。ThinkPHP从诞生以来一直秉承简洁实用的设计原则,在保持出色的性能和至简的代码的同时,也注重易用性。并且拥有众多的原创功能和特性,在社区团队的积极参与下,在易用性、扩展性和性能方面不断优化和改进,已经成长为国内最领先和最具影响力的WEB应用开发框架,众多的典型案例确保可以稳定用于商业以及门户级的开发。

AltStyle によって変換されたページ (->オリジナル) /