原码笔记

原码笔记

dedecms模板原理,实现标签替换

小诸哥 0

文章介绍

<?php require_once(dirname(__FILE__)."/../include/common.inc.php");

//1. 读入模板文件$str = file_get_contents('test.html');

//2. 使用正则匹配出页面中所有的 arclist 标签

$re = '/{dede:arclist(.*)}(.*){\/dede:arclist}/Us';

// 执行正则匹配

// 第一个参数:正则

// 第二个参数:字符串

// 第三个参数:这个函数会把匹配到的结果放第三个参数的数组中

// 返回值:匹配到的个数preg_match_all($re, $str, $a);

//3. 循环每一个匹配到的arclist标签进行处理:

foreach ($a[0] as $k => $v){  

/****************处理标签1.根据标签上的属性构造一个SQL语句 **************/  

// 取出标签相应的属性字符串并把属性转化成一个数组,如:row="10" channelid="17" addfields="pffz,pfrs,yuyan" orderby="id" orderway="desc"  $attrArr = strToArray($a[1][$k]);  

// 根据构造构造SQL语句上的变量:

if(isset($attrArr['row']))    $limit = $attrArr['row'];  

else    $limit = 20; 

if(isset($attrArr['orderby']))    $orderby = $attrArr['orderby'];  

else    $orderby = 'id';  

if(isset($attrArr['orderway']))    $orderway = $attrArr['orderway'];  

else    $orderway = 'desc';  

// 连表的属性:

if(isset($attrArr['channelid']))    $leftJoin = ' LEFT JOIN dede_addon17 b ON a.id=b.aid ';  

else    $leftJoin = '';  

if(isset($attrArr['addfields']))    $extraFields = ','.$attrArr['addfields'];  

else    $extraFields = '';  

// 解析属性:

$sql = "SELECT a.*$extraFields      FROM dede_archives a $leftJoin      ORDER BY $orderby $orderway      LIMIT $limit"; 

$dsql->Execute('me', $sql);  

$html = '';  

// 每个arclist对应的多个数据:

while($row = $dsql->GetArray('me'))  {    

// 重置模板字符串,不要在原模板上面进行替换:

$_tep = $a[2][$k];    

/**    

<li>

<img src="[field:litpic/]" /><br />      

标题:[field:title/]<br />      

评分分值:

[field:pffz  function="getSmallStar(@me)"/]<br />      

评分人数:[field:pfrs/]<br />      

语言:[field:yuyan/]    

</li>

**/    

// 把字符串中的[field:xxxx/]替换成$row['xxxx']变量。    

$_re = '/\[field:(\w+)(\s+function=("|\')(\w+)\((.*)\)\3)?\/\]/U';    

preg_match_all($_re, $_tep, $_a);    

/**

array 0 =>  array   0 => string '[field:litpic/]' (length=15)   1 => string '[field:title/]' (length=14)   2 => string '[field:pffz/]' (length=13)   3 => string '[field:pfrs/]' (length=13)   4 => string '[field:yuyan/]' (length=14) 1 =>  array   0 => string 'litpic' (length=6)   1 => string 'title' (length=5)   2 => string 'pffz' (length=4)   3 => string 'pfrs' (length=4)   4 => string 'yuyan' (length=5)  

*/  

// 再循环每一条 记录中的每个字段的值:

foreach($_a[0] as $_k => $_v){

if($_a[4][$_k] == '')

// 把[field:xxx/]字符串替换成相应的$row[xxx]变量:

$_tep = str_replace($_v, $row[$_a[1][$_k]], $_tep);

else

{

// 如果参数中有@me就把@me替换成当前这个字段的数据库中的值

$_a[5][$_k] = str_replace('@me', $row[$_a[1][$_k]], $_a[5][$_k]);

// 如果有函数就调用函数

$funStr = '$_val='.$_a[4][$_k]."({$_a[5][$_k]});";

eval($funStr);

$_tep = str_replace($_v, $_val, $_tep);

}

}

$html .= $_tep;

}  

// 到这arclist标签就已经都解析成了相应的数据,把整个arclist标签替换成解析之后的数据,$html就是arclist最终解析完成之后的HTML的字符串:

$str = str_replace($v, $html, $str);  

// 一个arclist就解析完成了

}

// 把解析好的字符串生成前台静态页:

file_put_contents('./index.html', $str);

echo '解析成功!';

function strToArray($str){  

$str = trim($str);  

// 从属性字符串中匹配出每个属性,格式如:

row="10" channelid="17" addfields="pffz,pfrs,yuyan" orderby="id" orderway="desc"  $re = '/[a-z]+\s*=\s*("|\').*\1/U';  

$data = array();  

preg_match_all($re, $str, $a);  

foreach ($a[0] as $k => $v)  {    

$_a = explode('=', $v);

// 去掉属性值左右的引号,属性左右的引号是单引号还是双引号不能确定所以需要使用$a[1][$k]变量来代替,这个变量是正则中的第一个括号的内容,匹配的就是引号:

$_a[1] = ltrim($_a[1], $a[1][$k]);

$_a[1] = rtrim($_a[1], $a[1][$k]);

$data[$_a[0]] = $_a[1];  

}  

return $data;

}

标签: dede cms 模板 原理 实现 标签