调用文章正文里的第一张图片(最常用)
这是最常见的需求,比如在列表页,你想每篇文章都显示一张代表图,如果文章没有上传缩略图,就自动调用正文里的第一张图。
场景示例:
在列表页(list_article.htm)的循环标签内,显示文章的缩略图,如果没有缩略图,则显示正文里的第一张图。
实现代码:
{dede:list pagesize='10'}
<li>
<!-- 首先尝试调用文章的缩略图 -->
[field:array runphp='yes']
// 获取缩略图地址
$thumb = @me['litpic'];
// 判断缩略图是否存在,并且不是默认的 "defaultpic.gif"
if(!empty($thumb) && $thumb != '/uploads/allimg/defaultpic.gif') {
// 如果存在,则输出缩略图
@me = "<a href='{@me['arcurl']}'><img src='{$thumb}' alt='{@me['title']}' /></a>";
} else {
// 如果不存在,则调用正文里的第一张图
// 获取文章内容
$body = @me['body'];
// 使用正则表达式匹配第一个img标签
preg_match('/<img.*?src="(.*?)".*?>/i', $body, $match);
// 如果匹配到了图片
if(isset($match[1])) {
// 输出正文里的第一张图
@me = "<a href='{@me['arcurl']}'><img src='{$match[1]}' alt='{@me['title']}' /></a>";
} else {
// 如果既没有缩略图,正文里也没有图片,可以显示一个默认图
@me = "<a href='{@me['arcurl']}'><img src='/static/images/default.jpg' alt='{@me['title']}' /></a>";
}
}
[/field:array]
<h3><a href="[field:arcurl/]">[field:title/]</a></h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
</li>
{/dede:list}
代码解析:
[field:array runphp='yes']:这是一个强大的标签,它可以将当前文章的所有字段(如title,arcurl,litpic,body等)作为一个数组传递给PHP代码。$thumb = @me['litpic'];:获取文章的缩略图地址。if(!empty($thumb) && $thumb != '/uploads/allimg/defaultpic.gif'):这是一个健壮的判断,它不仅检查缩略图是否存在,还排除了系统默认的“无图片”占位图,你需要根据你的网站实际情况修改默认图片的路径。- *`preg_match('/<img.?src="(.?>/i', $body, $match);`**:这是核心代码。
preg_match是PHP的正则表达式匹配函数。/<img.*?src="(.*?)".*?>/i是一个正则表达式,用来查找HTML中的<img>标签。<img:匹配标签开始。- 非贪婪匹配任意字符,直到遇到下一个条件。
src="(":匹配src=",并开始捕获组。- 这是最重要的部分,它会捕获
src=""引号里的内容,也就是图片地址。 - 匹配引号结束。
.*?>:匹配<img>标签的其余部分直到>。/i:表示不区分大小写匹配。
$match:匹配结果会存放在这个数组里。$match[0]是整个匹配的字符串(如<img src="..." />),$match[1]就是我们想要的第一张图片的URL。
isset($match[1]):判断是否成功匹配到了图片。@me = "...":在runphp='yes'环境中,将最终的HTML字符串赋值给@me变量,DedeCMS会输出这个值。
调用文章正文里的所有图片并生成图集
如果你想获取一篇文章里的所有图片,用来制作一个图集或幻灯片展示,可以使用以下方法。
场景示例:页(article_article.htm)中,除了显示正文,还额外显示一个包含所有图片的缩略列表。
实现代码:
<!-- 文章正文 -->
[field:body/]
<!-- 调用文章里的所有图片 -->
<div class="article-gallery">
<h3>文章图集</h3>
<ul>
{dede:field.body runphp='yes'}
$body = @me;
$pattern = '/<img.*?src="(.*?)".*?>/i';
preg_match_all($pattern, $body, $matches);
$images = '';
if(isset($matches[1])) {
foreach($matches[1] as $imgUrl) {
// 排除掉一些无用的图片,比如编辑器自带的图标
if(strpos($imgUrl, 'editor') === false && strpos($imgUrl, 'defaultpic.gif') === false) {
// 你可以根据需要给图片添加样式,比如设置固定宽高
$images .= "<li><img src='{$imgUrl}' /></li>";
}
}
}
// 如果没有找到图片,可以显示提示
if(empty($images)) {
$images = '<li>暂无图片</li>';
}
@me = $images;
[/dede:field.body]
</ul>
</div>
代码解析:
preg_match_all:与preg_match不同,它会查找所有匹配项,而不仅仅是第一个。$matches[1]:由于我们使用了捕获组src="(.*?)",所以所有图片的URL都会被存放在$matches[1]这个数组中。foreach($matches[1] as $imgUrl):遍历所有找到的图片URL。strpos($imgUrl, 'editor') === false:这是一个非常实用的过滤技巧,很多富文本编辑器(如DedeCMS自带编辑器)在插入图片时会带有特定路径(如/include/dedemedia/editor/),我们可以用strpos函数来排除这些非内容图片,只保留真正的文章图片,请根据你的编辑器实际情况修改过滤条件。@me = $images;:将拼接好的HTML列表字符串赋值给@me进行输出。
通过自定义函数实现(推荐,代码更整洁)
如果你需要在多个地方调用文章里的第一张图,或者想让代码更易于管理和复用,最好的方式是将其封装成一个自定义函数。
步骤1:在include/helpers/extend.helper.php文件中添加函数
打开你网站根目录下的 include/helpers/extend.helper.php 文件,在文件末尾的 ?> 之前添加以下PHP函数:
/**
* 获取文章内容中的第一张图片路径
* @param string $body 文章内容
* @param string $defaultImg 默认图片路径
* @return string 图片路径
*/
function GetFirstImg($body, $defaultImg = '/static/images/default.jpg')
{
// 匹配第一个img标签
preg_match('/<img.*?src="(.*?)".*?>/i', $body, $match);
// 如果找到图片,返回图片地址
if (isset($match[1])) {
return $match[1];
}
// 如果没找到,返回默认图片
return $defaultImg;
}
步骤2:在模板中调用这个函数
你可以在任何模板文件中使用这个自定义函数了,代码会变得非常简洁。
场景示例:
与方法一相同,但在列表页调用。
{dede:list pagesize='10'}
<li>
<!-- 直接调用自定义函数,传入文章内容 [field:body/] -->
<a href="[field:arcurl/]">
<img src="{dede:field.body function='GetFirstImg(@me, "/static/images/no-img.jpg")'/}" alt="[field:title/]" />
</a>
<h3><a href="[field:arcurl/]">[field:title/]</a></h3>
<p>[field:description function='cn_substr(@me,100)'/]...</p>
</li>
{/dede:list}
代码解析:
{dede:field.body function='GetFirstImg(@me, "/static/images/no-img.jpg")'/}:dede:field.body:获取文章的body。function='...':这是DedeCMS调用自定义函数的方式。@me:在function中,@me代表当前字段的值,也就是[field:body/],它被作为第一个参数传递给了GetFirstImg函数。"/static/images/no-img.jpg":这是第二个参数,即默认图片路径,当文章没有图片时会使用它。
这种方法的优点是:
- 代码复用:一次定义,处处可用。
- 模板简洁:模板里不再需要复杂的PHP逻辑,可读性更强。
- 易于维护:如果需要修改获取图片的逻辑(比如增加新的过滤条件),只需修改
extend.helper.php中的函数即可,无需改动所有模板文件。
| 方法 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
runphp直接处理 |
无需额外文件,简单直接。 | 代码冗长,不易复用,污染模板。 | 快速实现,偶尔使用。 |
preg_match_all |
可以获取所有图片,功能强大。 | 逻辑比方法一更复杂。 | 制作文章图集、幻灯片。 |
| 自定义函数 | 推荐,代码整洁、复用性强、易于维护。 | 需要修改PHP文件。 | 多次调用,追求代码质量和可维护性的项目。 |
对于大多数开发者来说,强烈推荐使用方法三(自定义函数),这是最规范、最高效的解决方案。
