WordPress 的媒体库已经提供了基本的图片和文件管理功能,但对于需要大量处理媒体的项目来说,默认功能还有很大的扩展空间。批量处理图片(压缩、转换、重命名)、生成 PDF 缩略图、为媒体添加自定义字段、允许上传更多文件类型,这些都是媒体管理进阶开发中常见的需求。

批量处理图片的第一步是压缩。WordPress 本身不会自动压缩上传的图片,但你可以通过钩子在上传时触发压缩操作。使用 wp_handle_upload 过滤器可以获取上传文件的信息,然后调用压缩库(如 GD 或 Imagick):

add_filter('wp_handle_upload', 'compress_uploaded_image');
function compress_uploaded_image($file) {
    if (strpos($file['type'], 'image') === 0) {
        $image = wp_get_image_editor($file['file']);
        if (!is_wp_error($image)) {
            $image->set_quality(85);
            $image->save($file['file']);
        }
    }
    return $file;
}

set_quality(85) 可以在画质和文件大小之间取得平衡。对于大部分图片,85% 的质量肉眼几乎看不出差异,但文件大小能减少 30%-40%。

批量生成 WebP 版本同样是重要的优化手段。你可以在上传时生成 WebP 副本并保存为附件的一部分,也可以在 CDN 层面动态转换。

PDF 缩略图的生成对包含文档下载的网站来说很有价值。WordPress 本身不提供 PDF 缩略图功能,但可以使用 Imagick 扩展生成第一页的预览图:

add_action('add_attachment', 'create_pdf_thumbnail');
function create_pdf_thumbnail($attachment_id) {
    $file = get_attached_file($attachment_id);
    $file_type = wp_check_filetype($file);
    if ($file_type['ext'] !== 'pdf') return;
    
    if (extension_loaded('imagick')) {
        $imagick = new Imagick();
        $imagick->readImage($file . '[0]');
        $imagick->setImageFormat('jpg');
        $thumbnail_path = str_replace('.pdf', '-thumb.jpg', $file);
        $imagick->writeImage($thumbnail_path);
        $imagick->clear();
        
        $attachment = array(
            'post_mime_type' => 'image/jpeg',
            'post_title' => basename($thumbnail_path),
            'post_content' => '',
            'post_status' => 'inherit'
        );
        $thumb_id = wp_insert_attachment($attachment, $thumbnail_path, $attachment_id);
        require_once(ABSPATH . 'wp-admin/includes/image.php');
        $metadata = wp_generate_attachment_metadata($thumb_id, $thumbnail_path);
        wp_update_attachment_metadata($thumb_id, $metadata);
    }
}

这样 PDF 文件就会有一个对应的缩略图,在媒体库中显示为预览。

自定义媒体字段允许给图片添加额外的信息,比如版权信息、拍摄地点、图片来源、或图片的 alt 文本(默认已有)。添加媒体字段使用 attachment_fields_to_edit 过滤器:

add_filter('attachment_fields_to_edit', 'add_media_custom_field', 10, 2);
function add_media_custom_field($fields, $post) {
    $fields['copyright'] = array(
        'label' => '版权信息',
        'input' => 'text',
        'value' => get_post_meta($post->ID, '_copyright', true)
    );
    return $fields;
}

add_filter('attachment_fields_to_save', 'save_media_custom_field', 10, 2);
function save_media_custom_field($post, $attachment) {
    if (isset($attachment['copyright'])) {
        update_post_meta($post['ID'], '_copyright', sanitize_text_field($attachment['copyright']));
    }
    return $post;
}

这些自定义字段可以在前端用 get_post_meta(附件ID, '_copyright', true) 读取并显示。

允许上传更多文件类型可以扩展 WordPress 的支持范围。比如允许上传 SVG、WebP、ICO、SVGZ 等格式:

add_filter('upload_mimes', 'allow_additional_file_types');
function allow_additional_file_types($mimes) {
    $mimes['svg'] = 'image/svg+xml';
    $mimes['webp'] = 'image/webp';
    $mimes['ico'] = 'image/x-icon';
    $mimes['svgz'] = 'image/svg+xml';
    return $mimes;
}

需要注意的是,某些文件类型(如 SVG)存在安全风险,建议只允许可信用户上传。

媒体库的批量操作同样可以扩展。比如批量给多个图片添加版权信息,批量修改 alt 文本。这些操作可以通过自定义批量操作菜单实现,或者在媒体列表的筛选器上做文章。

媒体文件的目录结构也可以定制。默认情况下,WordPress 按年/月组织上传文件。如果希望更扁平的结构或者按类别组织,可以通过 upload_dir 过滤器修改:

add_filter('upload_dir', 'custom_upload_dir');
function custom_upload_dir($uploads) {
    if (isset($_POST['post_id'])) {
        $post = get_post($_POST['post_id']);
        if ($post) {
            $uploads['path'] = $uploads['basedir'] . '/custom/' . $post->post_type;
            $uploads['url'] = $uploads['baseurl'] . '/custom/' . $post->post_type;
            $uploads['subdir'] = '/custom/' . $post->post_type;
        }
    }
    return $uploads;
}

这个例子会把上传的文件按文章类型分别存储在不同的目录中。但要注意,这种修改会影响所有上传路径,需要处理好已有文件的兼容性。

媒体管理在内容型网站和电商网站中占据非常重要的位置。高效的媒体库管理能让内容编辑的工作效率大幅提升,也能为前端提供更丰富的图片展示能力。