主页 > 网站建设 > 建站知识 > dedecms模板原理,实现标签替换

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

POST TIME:2017-11-13 00:35

正则匹配出所有的arclist标签并构造SQL

取出数据并替换field为相应字段的数据

为field标签添加一个function属性

<?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='LEFTJOINdede_addon17bONa.id=b.aid';
else
$leftJoin='';
if(isset($attrArr['addfields']))
$extraFields=','.$attrArr['addfields'];
else
$extraFields='';
//解析属性
$sql="SELECTa.*$extraFields
FROMdede_archivesa$leftJoin
ORDERBY$orderby$orderway
LIMIT$limit";
$dsql->Execute('me',$sql);
$html='';
//每个arclist对应的多个数据
while($row=$dsql->GetArray('me'))
{
//重置模板字符串,不要在原模板上面进行替换
$_tep=$a[2][$k];
/**
<li>
<imgsrc="[field:litpic/]"/><br/>
标题:[field:title/]<br/>
评分分值:[field:pffzfunction="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'解析成功!';
functionstrToArray($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;

}


收缩
  • 微信客服
  • 微信二维码
  • 电话咨询

  • 400-1100-266