如何按附件元数据(艺术家、专辑等)排序WordPress播放列表?
按附件元数据排序WordPress播放列表的方法
WordPress自带的播放列表短代码默认只能按wp_posts表的字段排序,但要实现按专辑、艺术家、比特率这类附件元数据排序,我们可以通过手动排序附件ID再传入播放列表的方式来实现,具体方案如下:
方法一:手动排序ID后传入播放列表
这种方法直接可控,不需要修改底层查询,适合自定义需求:
步骤1:编写排序函数
把下面的代码添加到主题functions.php或自定义插件中:
function sort_attachment_ids_by_metadata($ids, $orderby, $order = 'ASC') { // 把ID字符串转成数组 $id_array = explode(',', $ids); $attachments = array(); foreach ($id_array as $id) { $id = trim($id); if (!is_numeric($id)) continue; // 获取附件的元数据 $metadata = wp_get_attachment_metadata($id); if (!$metadata) { // 如果没有元数据,默认值设为空或0,避免排序出错 $sort_value = in_array($orderby, ['bitrate', 'duration', 'year', 'filesize']) ? 0 : ''; } else { // 根据排序字段获取对应的值 switch ($orderby) { case 'artist': $sort_value = $metadata['artist'] ?? ''; break; case 'album': $sort_value = $metadata['album'] ?? ''; break; case 'bitrate': $sort_value = (int)($metadata['bitrate'] ?? 0); break; case 'duration': $sort_value = (int)($metadata['length'] ?? 0); // 原生时长存在length字段 break; case 'year': $sort_value = (int)($metadata['year'] ?? 0); break; case 'filesize': $sort_value = (int)($metadata['filesize'] ?? 0); break; default: $sort_value = ''; } } $attachments[] = [ 'id' => $id, 'sort_value' => $sort_value ]; } // 执行排序 usort($attachments, function($a, $b) use ($orderby, $order) { $val_a = $a['sort_value']; $val_b = $b['sort_value']; // 数字类型字段按数值比较 if (in_array($orderby, ['bitrate', 'duration', 'year', 'filesize'])) { $compare = $val_a - $val_b; } else { // 文本类型按字符串比较(支持中文) $compare = strcmp(mb_strtolower($val_a), mb_strtolower($val_b)); } // 处理排序方向 return $order === 'DESC' ? -$compare : $compare; }); // 提取排序后的ID,转成字符串 $sorted_ids = implode(',', array_column($attachments, 'id')); return $sorted_ids; }
步骤2:调用播放列表时使用排序后的ID
现在你可以这样生成按艺术家降序排序的播放列表:
// 原始ID列表 $original_ids = '7,8,9'; // 按艺术家降序排序ID $sorted_ids = sort_attachment_ids_by_metadata($original_ids, 'artist', 'DESC'); // 生成播放列表 echo wp_playlist_shortcode( array( 'ids' => $sorted_ids, 'order' => 'DESC', 'orderby' => 'title' // 这里可随便填,ID顺序已手动排序 ));
方法二:通过钩子自动处理(更优雅)
如果你想直接在短代码里指定orderby为artist、album等字段,不需要手动调用排序函数,可以用钩子修改短代码参数:
添加下面的代码到functions.php(别忘了同时保留上面的sort_attachment_ids_by_metadata函数):
add_filter('shortcode_atts_wp_playlist', 'custom_playlist_orderby_shortcode_atts', 10, 3); function custom_playlist_orderby_shortcode_atts($out, $pairs, $atts) { // 检查是否指定了自定义的元数据排序字段 $allowed_meta_fields = ['artist', 'album', 'bitrate', 'duration', 'year', 'filesize']; if (!empty($atts['orderby']) && in_array($atts['orderby'], $allowed_meta_fields) && !empty($out['ids'])) { $order = isset($atts['order']) ? strtoupper($atts['order']) : 'ASC'; // 排序ID列表 $out['ids'] = sort_attachment_ids_by_metadata($out['ids'], $atts['orderby'], $order); // 把orderby改回title,避免内置逻辑干扰 $out['orderby'] = 'title'; } return $out; }
现在你可以直接像内置语法一样调用:
echo wp_playlist_shortcode( array( 'ids' => '7,8,9', 'order' => 'DESC', 'orderby' => 'artist' // 直接指定元数据字段 ));
注意事项
- 原生WordPress的音频元数据中,时长字段是
length(秒数),文件大小是filesize(字节),代码已对应这些字段 - 如果你的附件元数据存在单独的自定义字段(比如
_audio_artist),只需修改排序函数里的取值逻辑,用get_post_meta($id, '_audio_artist', true)代替$metadata['artist']即可 - 代码中用
mb_strtolower确保中文等多字节字符的排序准确性
内容的提问来源于stack exchange,提问作者greg
相关产品推荐
相关产品推荐

