DedeCMS 技术问答

织梦附件字段图片多图调用

附件字段与图片字段区别

织梦自定义模型中涉及文件上传的字段类型主要有三类,开发者常混淆:

1. 单图字段(img)

只允许上传一张图片,存储为图片 URL 字符串,适合封面图、Logo、头像。

2. 图片集字段(imgs)

支持多图上传,存储为织梦专用格式({dede:img ...}{/dede:img}),适合作品集、产品图、相册。

3. 附件字段(addonfile)

支持任意文件类型上传(PDF、ZIP、DOC 等),存储为文件 URL,适合资料下载、合同附件、源码包。

本文重点讲解附件字段中包含多张图片时的调用方法,以及图片集字段的多图展示。

图片集字段的数据格式

图片集字段(如 imgurls)在数据库中存储格式为:

{dede:img text='说明文字' width='800' height='600'} /uploads/200101/1.jpg {/dede:img}
{dede:img text='第二张' width='800' height='600'} /uploads/200101/2.jpg {/dede:img}

这是一个嵌套的织梦标签字符串,必须用 {dede:field name='imgurls'} 包裹才能解析输出。

调用方法一:原生标签输出

内容页标准调用

{dede:field name='imgurls' alt='图片输出区'}
  <div class="gallery-item">
    <img src="[field:imgsrc/]" alt="[field:alttext/]">
    <p>[field:alttext/]</p>
  </div>
{/dede:field}

可用字段:

[field:imgsrc/]     图片地址
[field:imgsrctrue/] 原图地址(无水印)
[field:alttext/]    图片说明
[field:width/]      宽度
[field:height/]     高度
[field:pagestyle/]  分页样式

调用方法二:自定义函数解析

当需要更灵活的输出(如 grid 布局、lazyload、WebP 替换)时,可在 extend.func.php 中自定义函数:

// 解析图片集字段,返回数组
function ParseImageField($value) {
    if (empty($value)) return [];
    $pattern="/{dede:img([^}]*)}(.*){\/dede:img}/isU";
    preg_match_all($pattern, $value, $matches);
    $images=[];
    foreach ($matches[0] as $i=> $full) {
        $attrs=$matches[1][$i];
        $src=trim($matches[2][$i]);
        $text='';
        if (preg_match("/text=['\"]([^'\"]*)['\"]/", $attrs, $t)) {
            $text=$t[1];
        }
        $images[]=[
            'src'=> $src,
            'text'=> $text,
        ];
    }
    return $images;
}

// 直接输出 HTML
function ImageGallery($value) {
    $images=ParseImageField($value);
    if (empty($images)) return '';
    $html='<div class="gallery">';
    foreach ($images as $img) {
        $html .='<figure>';
        $html .='<img src="'.$img['src'].'" alt="'.$img['text'].'" loading="lazy">';
        if ($img['text']) {
            $html .='<figcaption>'.$img['text'].'</figcaption>';
        }
        $html .='</figure>';
    }
    $html .='</div>';
    return $html;
}

模板调用:

{dede:field.imgurls function="ImageGallery(@me)"/}

调用方法三:附件字段多图处理

附件字段(addonfile)如果是多图(用逗号分隔的多 URL),处理方式:

// 附件字段多图输出
function AttachmentImages($value) {
    if (empty($value)) return '';
    $urls=explode(',', $value);
    $urls=array_map('trim', $urls);
    $html='<div class="attach-gallery">';
    foreach ($urls as $url) {
        if (preg_match('/\.(jpg|jpeg|png|gif|webp)$/i', $url)) {
            $html .='<img src="'.$url.'" loading="lazy">';
        }
    }
    $html .='</div>';
    return $html;
}

列表页调用图片集

列表页默认不解析图片集字段,需要先用 function 提取第一张图作为缩略图:

// 提取图片集第一张图作为缩略图
function FirstImage($value) {
    $images=ParseImageField($value);
    return $images ? $images[0]['src'] : '';
}

模板:

{dede:list pagesize='10'}
  <a href="[field:arcurl/]">
    <img src="[field:imgurls function="FirstImage(@me)"/]">
    <h3>[field:title/]</h3>
  </a>
{/dede:list}

注意:列表附加字段需添加 imgurls

响应式画廊 CSS 示例

.gallery {
  display: grid;
  grid-template-columns: repeat(auto-fill, minmax(200px, 1fr));
  gap: 12px;
}
.gallery figure {
  margin: 0;
  border-radius: 8px;
  overflow: hidden;
  background: #f5f5f5;
}
.gallery img {
  width: 100%;
  height: 180px;
  object-fit: cover;
  display: block;
  transition: transform .3s;
}
.gallery figure:hover img { transform: scale(1.05); }
.gallery figcaption {
  padding: 8px;
  font-size: .85rem;
  color: #666;
  text-align: center;
}
@media (max-width: 640px) {
  .gallery { grid-template-columns: repeat(2, 1fr); }
}

注意事项

1. 图片集字段必须用 {dede:field name='imgurls'} 包裹,直接 {dede:field.imgurls/} 会输出原始标签字符串。
2. 自定义函数中正则要加 /isU 修饰符(不区分大小写、点匹配换行、非贪婪),否则多图解析会出错。
3. 移动端建议给图片加 loading="lazy",提升首屏加载速度。
4. 静态生成时图片路径会写入 HTML,更换域名需重新生成或用相对路径。
5. 附件字段若同时存图片与文档,前台展示前需用扩展名判断类型,避免把 PDF 当图片渲染。

后续优化方向

建议为图片集接入 WebP 自动转换与 CDN 加速,并生成多尺寸缩略图(thumbnail、medium、large),按视口加载对应尺寸,进一步优化移动端体验。长期可结合结构化数据(Schema.org ImageGallery)让搜索引擎更好理解图片内容,提升图片搜索流量。对于用户上传的高清图,建议后台设置最大宽度限制(如 1920px),避免单图过大拖慢整页性能。