跳到內容

相簿列表缺圖,最後用內容第一張圖補特色圖片

整理日期:2026-08-18

一個 WordPress 作品相簿網站,部分分類列表的卡片沒有圖片。

前台模板本身沒有壞。打開相簿後,可以看到內文有圖片,只是文章沒有設定特色圖片。

需求不只是修眼前幾篇:

  • 已有的舊相簿要一次補齊。
  • 未來新增或更新相簿時,也要自動處理。
  • 原本已經設定特色圖片的文章不能被覆蓋。
  • 相簿總數和缺少特色圖片的數量。
  • 內容使用一般 HTML、區塊編輯器,還是頁面編輯器 shortcode。
  • 圖片有沒有 wp-image-ID
  • 圖片是不是本站媒體庫的 /wp-content/uploads/ 網址。
  • 內容第一個 <img> 是否真的是相簿主圖。

資料一整理,才發現只抓 wp-image-ID 會漏掉大部分舊相簿。部分內容用頁面編輯器 shortcode 保存圖片網址,還有些文章在主圖前先出現 emoji 圖片。

這批舊內容雖然格式不同,卻都有一個共同點:真正的相簿圖片來自本站 /wp-content/uploads/

所以最小而穩定的規則是:

  1. 取內容中第一個本站 uploads 圖片網址。
  2. 把網址轉回媒體附件 ID。
  3. 如果是 -300x200 這類縮圖網址,移除尺寸後再查一次。
  4. 找不到網址時,才用 wp-image-ID 備援。

WPCodeBox 內放一段 PHP snippet。儲存相簿時自動補圖,管理員第一次進後台時再批次掃過既有相簿。

function site_album_first_image_id( $content ) {
$content = html_entity_decode( $content, ENT_QUOTES | ENT_HTML5, 'UTF-8' );
if ( preg_match( '~https?://[^\s"\'<>\]]+/wp-content/uploads/[^\s"\'<>\]]+\.(?:avif|gif|jpe?g|png|webp)~i', $content, $match ) ) {
$url = $match[0];
$id = attachment_url_to_postid( $url );
if ( ! $id ) {
$url = preg_replace( '~-\d+x\d+(?=\.(?:avif|gif|jpe?g|png|webp)$)~i', '', $url );
$id = attachment_url_to_postid( $url );
}
if ( $id && wp_attachment_is_image( $id ) ) {
return $id;
}
}
if ( preg_match( '/\bwp-image-(\d+)\b/', $content, $match ) ) {
$id = (int) $match[1];
return wp_attachment_is_image( $id ) ? $id : 0;
}
return 0;
}
function site_album_set_first_image( $post_id, $post = null ) {
$post = $post ?: get_post( $post_id );
if (
! $post ||
'album' !== $post->post_type ||
wp_is_post_revision( $post_id ) ||
( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) ||
has_post_thumbnail( $post_id )
) {
return false;
}
$id = site_album_first_image_id( $post->post_content );
return $id ? (bool) set_post_thumbnail( $post_id, $id ) : false;
}
add_action( 'save_post_album', 'site_album_set_first_image', 20, 2 );
add_action( 'admin_init', function () {
$done_key = 'site_album_featured_backfill_v1';
if ( ! current_user_can( 'manage_options' ) || get_option( $done_key ) ) {
return;
}
$ids = get_posts( array(
'post_type' => 'album',
'post_status' => 'any',
'posts_per_page' => -1,
'fields' => 'ids',
'no_found_rows' => true,
) );
foreach ( $ids as $id ) {
site_album_set_first_image( $id );
}
update_option( $done_key, gmdate( 'c' ), false );
}, 20 );

Snippet 不需要 <?php。執行位置用 Plugins Loaded,並保持 Always On。

批次完成後仍保留 snippet,因為 save_post_album 要繼續處理未來相簿。一次性掃描不會重複執行,因為完成後會留下 option。

  • 不要只掛 save_post_album,舊相簿不會因此自動回填。
  • 不要只抓 wp-image-ID,舊版頁面編輯器可能只保存圖片網址。
  • 不要把內容第一個任意外站圖片當特色圖片。
  • 不要覆蓋已經人工挑選的特色圖片。
  • 不要每次進後台都重掃全部相簿。
  • 自訂文章類型名稱。
  • 缺少特色圖片的文章數量。
  • 內容中實際保存的是附件 ID、HTML,還是 shortcode。
  • 圖片網址是否都來自本站媒體庫。
  • 是否要處理既有文章、未來文章,或兩者都要。
  • 已有特色圖片是否必須保留。
  • WordPress
  • 特色圖片
  • 自訂文章類型
  • 媒體庫
  • WPCodeBox