什么是Dede标签?
Dede标签是织梦CMS内置的一套模板引擎语法,用于在模板文件(.htm)中动态调用数据库内容,并最终生成静态的HTML页面。

{dede:arclist titlelen='30' row='10'}...{/dede:arclist}:调用文章列表{dede:field.title/}:调用文章标题{dede:global.cfg_webname/}:调用网站配置名称
这些标签的本质是PHP代码,织梦在解析模板时,会把这些标签替换成实际的PHP执行代码。
如何修改现有的内置标签?
当你觉得某个内置标签的功能不够用,或者想修改它的默认行为时,就需要修改其源代码。核心原则是:找到生成该标签的PHP文件,并修改其逻辑。
步骤1:找到标签对应的PHP文件
织梦的标签系统有固定的文件存放位置,主要在 /include/taglib/ 目录下,这个目录下的每一个 .php 文件都对应一个或一组Dede标签。
arclist.lib.php:{dede:arclist}channel.lib.php:{dede:channel}flink.lib.php:{dede:flink}type.lib.php:{dede:type}article.lib.php:{dede:field}在文章页中的一些属性
举例:修改 {dede:arclist} 的排序方式

假设你想让文章列表除了按默认的发布时间排序外,还能支持按“点击量”排序。
- 找到文件:打开
/include/taglib/arclist.lib.php。 - 分析代码:在这个文件中,找到SQL查询语句,通常是在
else分支中,有一个$orwheresql和$ordersql变量。$ordersql就是控制排序的。 - 修改代码:找到
$ordersql的赋值部分,通常是这样的:// 原始代码,可能位于第100行左右 if ($orderby=='hot' || $orderby=='click') { $ordersql = " ORDER BY arc.click $orderway"; } else if ($orderby=='iscommend' || $orderby=='commend') { $ordersql = " ORDER BY arc.iscommend $orderway"; } else { $ordersql = " ORDER BY arc.sortrank $orderway"; }你可以看到,它已经支持
hot(点击量) 和iscommend(推荐) 等排序方式,如果你想让它支持自定义字段,weight(权重),你需要在这里增加一个判断:// 修改后的代码示例 if ($orderby=='hot' || $orderby=='click') { $ordersql = " ORDER BY arc.click $orderway"; } else if ($orderby=='iscommend' || $orderby=='commend') { $ordersql = " ORDER BY arc.iscommend $orderway"; } else if ($orderby=='weight') { // 新增一个按权重排序的选项 $ordersql = " ORDER BY arc.weight $orderway"; } else { $ordersql = " ORDER BY arc.sortrank $orderway"; } - 保存并测试:保存文件后,在你的模板中就可以这样使用了:
{dede:arorderby='weight' orderway='desc'} <li><a href="[field:arcurl/]">[field:title/]</a></li> {/dede:arclist}
步骤2:修改标签的默认参数
有些标签的默认参数可能不符合你的需求。{dede:arclist} 默认不调用副标题,你可以通过修改其PHP文件来改变默认行为。
-
找到文件:同样是
/include/taglib/arclist.lib.php。
(图片来源网络,侵删) -
分析代码:找到函数定义
function lib_aritelist(&$ctag, &$refObj),然后找到获取参数的代码,通常是attstr = $ctg->GetAtt('');。 -
修改代码:找到参数初始化的地方,给默认参数赋值,你想让
titlelen默认为50,可以这样修改:// 在函数开始处,找到类似这样的代码 $typeid = $ctag->GetAtt('typeid'); $titlelen = $ctag->GetAtt('titlelen'); // ... // $titlelen 为空,则设置默认值 if ($titlelen == '') { $titlelen = 50; // 设置默认长度为50 } -
保存并测试:之后,即使模板里不写
titlelen,它也会默认截取50个字符。
如何创建自定义标签?
当织梦内置标签完全无法满足你的需求时,就需要创建全新的自定义标签,这个过程稍微复杂,但非常灵活。
创建自定义标签的完整流程:
假设我们要创建一个 {dede:mylatestnews} 标签,用于调用指定栏目ID的最新5条新闻,并且要显示一个自定义字段 author (作者)。
第一步:创建标签处理文件
在 /include/taglib/ 目录下创建一个新的PHP文件,mylatestnews.lib.php。
<?php
// 文件名:/include/taglib/mylatestnews.lib.php
function lib_mylatestnews(&$ctag, &$refObj)
{
// 1. 获取标签属性
$attlist = "typeid|0,row|5";
FillAttsDefault($ctag->CAttribute->Items, $attlist);
$typeid = $ctag->CAttribute->Items['typeid'];
$row = $ctag->CAttribute->Items['row'];
// 2. 编写SQL查询语句
$innertext = $ctag->GetInnerText();
$dsql = clone $GLOBALS['dsql'];
$query = "SELECT id, title, author, arcurl FROM `#@__archives`
WHERE typeid = $typeid
ORDER BY pubdate DESC
LIMIT 0, $row";
$GLOBALS['mylatestnews'] = array(); // 定义一个全局变量来存储结果
$dsql->Execute('mylatestnews', $query);
while ($row = $dsql->GetArray('mylatestnews')) {
$GLOBALS['mylatestnews'][] = $row;
}
// 3. 返回PHP模板代码
// 这段代码会在模板中循环执行
$phpcode = <<<EOT
<?php
if (is_array(\$GLOBALS['mylatestnews'])) {
foreach(\$GLOBALS['mylatestnews'] as \$key => \$fields) {
\$fields['arcurl'] = GetFileUrl(\$fields['id'], \$fields['typeid'], \$fields['senddate'], \$fields['title'], \$fields['ismake'], \$fields['arcrank'], \$fields['channel'], \$fields['addinfos'], \$fields['nativeplace'], \$fields['litpic']);
\$fields['title'] = cn_substr(\$fields['title'], 30);
\$fields['author'] = \$fields['author'] ? '作者:' . \$fields['author'] : '';
echo <<<EOT_HTML
<li><a href="{\$fields['arcurl']}">{\$fields['title']}</a> {\$fields['author']}</li>
EOT_HTML;
}
}
?>
EOT;
return $phpcode;
}
?>
代码解释:
attlist:定义标签支持的属性,如typeid和row,并设置默认值。FillAttsDefault:用默认值填充未提供的属性。SQL查询:编写查询语句,从#@__archives表中获取指定栏目ID的最新文章。全局变量:将查询结果存入$GLOBALS['mylatestnews'],供模板调用。- 返回PHP代码:这是最关键的一步,我们返回了一段PHP代码,这段代码会在模板中执行,它遍历我们查询到的数据,并按照我们定义的HTML结构输出。
第二步:在模板中使用标签
你可以在任何模板文件中使用这个新标签了。
<ul>
{dede:mylatestnews typeid='5' row='8'}
<!-- 这里的内容会被 mylatestnews.lib.php 中返回的PHP代码替换 -->
<!-- 注意:这里的InnerText会被忽略,因为我们直接在PHP代码里输出了HTML -->
{/dede:mylatestnews}
</ul>
第三步:使标签支持InnerText
上面的例子直接在PHP代码里输出了HTML,不够灵活,更好的方式是让标签支持内部内容(InnerText),这样模板可以自由定义样式。
修改 mylatestnews.lib.php 文件:
<?php
// 文件名:/include/taglib/mylatestnews.lib.php
function lib_mylatestnews(&$ctag, &$refObj)
{
$attlist = "typeid|0,row|5";
FillAttsDefault($ctag->CAttribute->Items, $attlist);
$typeid = $ctag->CAttribute->Items['typeid'];
$row = $ctag->CAttribute->Items['row'];
$innertext = $ctag->GetInnerText(); // 获取标签内部的内容
$dsql = clone $GLOBALS['dsql'];
$query = "SELECT id, title, author, arcurl FROM `#@__archives`
WHERE typeid = $typeid
ORDER BY pubdate DESC
LIMIT 0, $row";
$GLOBALS['mylatestnews'] = array();
$dsql->Execute('mylatestnews', $query);
while ($row = $dsql->GetArray('mylatestnews')) {
$GLOBALS['mylatestnews'][] = $row;
}
// 返回一个更灵活的PHP代码,它会使用 $innertext
$phpcode = <<<EOT
<?php
if (is_array(\$GLOBALS['mylatestnews'])) {
foreach(\$GLOBALS['mylatestnews'] as \$key => \$fields) {
\$fields['arcurl'] = GetFileUrl(\$fields['id'], \$fields['typeid'], \$fields['senddate'], \$fields['title'], \$fields['ismake'], \$fields['arcrank'], \$fields['channel'], \$fields['addinfos'], \$fields['nativeplace'], \$fields['litpic']);
\$fields['title'] = cn_substr(\$fields['title'], 30);
\$fields['author'] = \$fields['author'] ? '作者:' . \$fields['author'] : '';
// 使用 str_replace 将标签内的占位符替换为实际值
\$temp_innertext = str_replace(
array('[field:title/]', '[field:author/]', '[field:arcurl/]', '[field:global name=autoindex/]'),
array(\$fields['title'], \$fields['author'], \$fields['arcurl'], \$key+1),
\$innertext
);
echo \$temp_innertext;
}
}
?>
EOT;
return $phpcode;
}
?>
你的模板可以这样使用,非常灵活:
<ul>
{dede:mylatestnews typeid='5' row='8'}
<li><span>[field:global name=autoindex/]</span> - <a href="[field:arcurl/]">[field:title/]</a> [field:author/]</li>
{/dede:mylatestnews}
</ul>
重要注意事项
- 备份!备份!备份! 修改任何核心文件前,务必备份原文件,织梦升级时,你修改过的文件可能会被覆盖,所以最好保留一份修改记录。
- 修改核心文件的风险:直接修改
/include/taglib/或/dede/等目录下的文件,在织梦升级时可能会丢失,对于重要的自定义功能,推荐使用模块/插件的方式来实现,而不是直接修改核心文件。 - 缓存问题:修改标签后,如果前台页面没有立即生效,请到后台的“系统 -> 数据库备份/恢复 -> SQL命令行工具”中执行
DEL FROM dede_arccache;清除文章缓存,或者直接删除/data/cache/目录下的缓存文件。 - 安全考虑:在自定义标签中处理用户输入时(如从URL获取ID),务必进行过滤和验证,防止SQL注入。
希望这份详细的指南能帮助你掌握修改和创建Dede标签的技能!
