WordPress + Elementor + ACF 实现产品下载列表:自动显示文件名和文件大小
在使用 WordPress 搭建企业官网或产品展示网站时,产品详情页通常需要提供资料下载功能,例如产品彩页、用户手册、安装说明书、软件包等。
如果每个产品都手动写下载链接,不仅维护麻烦,而且后期更换文件时也容易出错。更好的方式是使用 ACF 给产品添加文件字段,然后在前端自动读取文件信息,生成统一样式的下载列表。
本文介绍一种适用于 WordPress、Elementor 和 ACF 的实现方法,可以在产品详情页中自动显示两个文件下载项,并展示媒体库中文件的真实文件名和文件大小。
实现效果
最终前端会显示一个简洁的下载列表,每一行包含:
文件类型图标,例如 PDF、ZIP
文件名称,自动读取上传到媒体库的文件名
文件大小,例如 35.4MB、1.6MB
点击整行即可下载文件
同时,列表支持悬停交互效果:
鼠标悬停时背景变为浅蓝色
左侧出现蓝色装饰线
文件名称和文件大小变为主题蓝色
文件图标轻微上浮
整体无阴影,更适合放在产品详情页的下载 Tab 中
使用场景
这个方案适合以下页面:
产品详情页
资料下载区
Elementor 自定义产品模板
WooCommerce 产品详情页 Tab
企业官网产品资料模块
例如,一个产品可以在后台上传:
产品彩页下载
产品用户手册下载
前端会自动输出类似这样的下载列表:
SMA26-PRO_Plus-RTK-User-Manual_260427.pdf 35.4MB
SMA26-PRO-survey-system_catalog_260506.pdf 1.6MB
第一步:使用 ACF 添加文件字段
先在 ACF 中给产品添加两个文件字段。
建议字段设置如下:
字段类型:文件
返回值:文件数组
文件库:全部
字段名称可以设置为:
产品彩页下载
产品用户手册下载
需要注意的是,代码中读取的是 ACF 的“字段名称”,不是“字段标签”。如果你的字段名称是英文,例如 product_brochure_download、product_manual_download,那么后面代码中的字段名也要对应修改。
第二步:添加 Shortcode 代码
可以把下面这段代码添加到子主题的 functions.php 文件中,也可以使用 Code Snippets 插件添加。
如果使用 Code Snippets,建议新建一段 PHP 代码,并设置为在前台运行。
/** * 产品下载列表 Shortcode * 用法:[sma_product_downloads] */ add_shortcode('sma_product_downloads', function () { if (!function_exists('get_field')) { return ''; } $post_id = get_the_ID(); /** * 改成你 ACF 文件字段的“字段名称” * 注意:是字段名称,不是字段标签 */ $fields = [ '产品彩页下载', '产品用户手册下载', ]; $files = []; foreach ($fields as $field_name) { $file = get_field($field_name, $post_id); if (empty($file)) { continue; } $file_data = sma_get_acf_file_data($file); if (!empty($file_data['url'])) { $files[] = $file_data; } } if (empty($files)) { return ''; } ob_start(); ?> <style> .sma-download-list { width: 100%; max-width: 100%; margin: 0; padding: 8px 0; background: #ffffff; border: none; box-shadow: none; } .sma-download-item { position: relative; display: flex; align-items: center; justify-content: space-between; width: 100%; gap: 24px; padding: 20px 28px; border-bottom: 1px solid #eeeeee; background: #ffffff; color: #333333; text-decoration: none !important; box-shadow: none !important; outline: none; overflow: hidden; transition: background-color 0.22s ease, color 0.22s ease, border-color 0.22s ease; } .sma-download-item:first-child { border-top: 1px solid #eeeeee; } .sma-download-item::before { content: ""; position: absolute; left: 0; top: 16px; bottom: 16px; width: 3px; background: #0b4f7a; border-radius: 3px; opacity: 0; transform: scaleY(0.35); transition: opacity 0.22s ease, transform 0.22s ease; } .sma-download-item:hover { background: #f6fafd; color: #0b4f7a; border-bottom-color: #e2edf5; } .sma-download-item:hover::before { opacity: 1; transform: scaleY(1); } .sma-download-left { display: flex; align-items: center; gap: 18px; min-width: 0; flex: 1 1 auto; position: relative; z-index: 1; } .sma-download-icon { display: inline-flex; align-items: center; justify-content: center; width: 22px; height: 22px; min-width: 22px; border-radius: 3px; background: #25b45b; color: #ffffff; font-size: 7px; line-height: 1; font-weight: 700; letter-spacing: -0.2px; transition: background-color 0.22s ease, transform 0.22s ease; } .sma-download-item:hover .sma-download-icon { background: #0b4f7a; transform: translateY(-1px); } .sma-download-name { display: block; font-size: 15px; font-weight: 400; line-height: 1.55; color: inherit; word-break: break-word; } .sma-download-size { min-width: 90px; text-align: right; font-size: 14px; font-weight: 400; line-height: 1.4; color: #333333; white-space: nowrap; position: relative; z-index: 1; transition: color 0.22s ease; } .sma-download-item:hover .sma-download-size { color: #0b4f7a; } .sma-download-item:focus, .sma-download-item:active { outline: none; box-shadow: none !important; } @media (max-width: 767px) { .sma-download-list { padding: 4px 0; } .sma-download-item { align-items: flex-start; padding: 16px 14px; gap: 12px; } .sma-download-left { gap: 12px; } .sma-download-icon { width: 20px; height: 20px; min-width: 20px; font-size: 7px; margin-top: 2px; } .sma-download-name { font-size: 14px; line-height: 1.5; } .sma-download-size { min-width: auto; font-size: 13px; padding-top: 2px; } } @media (max-width: 480px) { .sma-download-item { flex-direction: column; align-items: stretch; } .sma-download-size { padding-left: 32px; text-align: left; color: #777777; } } </style> <div class="sma-download-list"> <?php foreach ($files as $file) : ?> <a class="sma-download-item" href="<?php echo esc_url($file['url']); ?>" download> <div class="sma-download-left"> <span class="sma-download-icon" aria-hidden="true"> <?php echo esc_html($file['type']); ?> </span> <span class="sma-download-name"> <?php echo esc_html($file['name']); ?> </span> </div> <?php if (!empty($file['size'])) : ?> <span class="sma-download-size"> <?php echo esc_html($file['size']); ?> </span> <?php endif; ?> </a> <?php endforeach; ?> </div> <?php return ob_get_clean(); }); /** * 兼容 ACF 文件字段返回:数组 / ID / URL */ function sma_get_acf_file_data($file) { $url = ''; $name = ''; $size = ''; $type = 'FILE'; if (is_array($file)) { $url = $file['url'] ?? ''; $id = $file['ID'] ?? 0; if (!empty($url)) { $name = basename(parse_url($url, PHP_URL_PATH)); $type = sma_get_file_type_label($name); } if (!empty($id)) { $file_path = get_attached_file($id); if ($file_path && file_exists($file_path)) { $size = sma_format_file_size(filesize($file_path)); } } if (empty($size) && !empty($file['filesize'])) { $size = sma_format_file_size($file['filesize']); } } elseif (is_numeric($file)) { $id = (int) $file; $url = wp_get_attachment_url($id); if (!empty($url)) { $name = basename(parse_url($url, PHP_URL_PATH)); $type = sma_get_file_type_label($name); } $file_path = get_attached_file($id); if ($file_path && file_exists($file_path)) { $size = sma_format_file_size(filesize($file_path)); } } elseif (is_string($file)) { $url = $file; $name = basename(parse_url($url, PHP_URL_PATH)); $type = sma_get_file_type_label($name); } return [ 'url' => $url, 'name' => $name, 'size' => $size, 'type' => $type, ]; } /** * 根据文件扩展名显示图标文字 */ function sma_get_file_type_label($filename) { $ext = strtolower(pathinfo($filename, PATHINFO_EXTENSION)); if ($ext === 'pdf') { return 'PDF'; } if ($ext === 'zip') { return 'ZIP'; } if (in_array($ext, ['doc', 'docx'], true)) { return 'DOC'; } if (in_array($ext, ['xls', 'xlsx'], true)) { return 'XLS'; } if (in_array($ext, ['jpg', 'jpeg', 'png', 'webp'], true)) { return 'IMG'; } return strtoupper(substr($ext, 0, 4)) ?: 'FILE'; } /** * 文件大小格式化 */ function sma_format_file_size($bytes) { $bytes = (int) $bytes; if ($bytes <= 0) { return ''; } if ($bytes >= 1048576) { return round($bytes / 1048576, 1) . 'MB'; } return round($bytes / 1024) . 'KB'; }
第三步:在 Elementor 中调用
代码添加完成后,进入 Elementor 编辑产品详情页模板。
在下载板块中添加一个 Shortcode 小工具,然后输入:
[sma_product_downloads]
保存后,前端就会自动读取当前产品中的 ACF 文件字段,并输出下载列表。
如果前端不是全宽怎么办?
代码中的 .sma-download-list 已经设置为:
width: 100%; max-width: 100%;
如果前端看起来仍然不是全宽,通常不是代码问题,而是 Elementor 外层容器限制了宽度。
可以检查以下位置:
Elementor Section 或 Container 的 Content Width 是否为 Full Width
外层容器是否设置了固定宽度
Column 或 Container 是否有左右 Padding
主题模板是否限制了产品详情内容宽度
如果想让下载列表铺满当前 Tab 内容区域,只需要确保放 Shortcode 的 Elementor 容器本身是全宽即可。
字段名称如何修改?
如果你的 ACF 字段名称不是中文,而是英文,例如:
product_catalog_download
product_manual_download
那么只需要修改代码中的这一段:
$fields = [ '产品彩页下载', '产品用户手册下载', ];
改成:
$fields = [ 'product_catalog_download', 'product_manual_download', ];
这样前端就会读取对应的两个文件字段。
代码特点
这段代码兼容 ACF 文件字段的多种返回值:
文件数组
文件 ID
文件 URL
同时会自动判断文件类型,并在前端显示不同的图标文字:
PDF 文件显示 PDF
ZIP 文件显示 ZIP
Word 文件显示 DOC
Excel 文件显示 XLS
图片文件显示 IMG
其他文件显示 FILE
文件大小会自动格式化为 KB 或 MB,前端展示更直观。
总结
通过 ACF 文件字段和 WordPress Shortcode,可以非常方便地为 Elementor 产品详情页添加下载列表。
相比手动写下载链接,这种方式有几个明显优势:
后台上传文件即可自动更新前端
文件名直接读取媒体库文件名
文件大小自动显示
样式统一,方便维护
适合多个产品复用
后期更换文件不需要改页面结构
对于企业官网、WooCommerce 产品页、设备产品资料下载页来说,这种方案维护成本低,展示效果也更加专业。

浙公网安备 33010602011771号