A hiányzó kiemelt képek tömeges hozzárendelése a WordPressben

No comments

05.09.2026|

No comments

Tiempo de lectura Lectura: 15 min, 18 s
Número de palabras Palabras: 2833
Número de visitas Visitas: 22
Icono de traducción
Hiányzó kiemelt képek tömeges hozzárendelése a WordPressben. A hiányzó és a meglévő képeket egyaránt tartalmazó lista.

Néhány napja befejeztem egy régóta esedékes feladatot, amit már rég meg kellett volna csinálnom, de hosszú ideje halogattam.Pótoltam az összeshiányzó kiemelt képet, és hozzáadtam az összes hiányzó alt szöveget a képekhez. Ezenkívül befejeztem az összes hiányzó meta leírás megírását is. Összesen több mint 15 000 bejegyzést adtam hozzá vagy szerkesztettem három saját, egyszeri használatra készült kódrészletem segítségével. Ma itt megosztom azt a kódrészletet, amellyel a hiányzó kiemelt képeket pótoltam, és amelyet más webhelyeken is használtam ennek a feladatnak az elvégzéséhez.

Ha már egy ideje blogolsz, akkor nagy valószínűséggel van jó néhány régebbi bejegyzésed, amelyhez nincs hozzárendelve kiemelt kép. Ez régebben, a klasszikus szerkesztő idején gyakran előfordult, amikor a képet közvetlenül a bejegyzés szövegébe illesztettük be, de elfelejtettük kiválasztani a „Kiemelt kép” mezőben.

Ha a bejegyzéseket kiemelt kép nélkül teszel közzé, az nem csupán esztétikai kérdés, hanem – többek között – közvetlenül befolyásolja a webhelyed optimalizálását és a felhasználói élményt is:

  1. Közösségi SEO és Open Graph: Amikor a bejegyzést közösségi médián, üzenetküldő alkalmazásokban vagy tartalomgyűjtő oldalakon osztják meg, az Open Graph-címkék (og:image) nem találnak egyértelmű forrást a megjelenítéshez, ami drasztikusan csökkenti a CTR-t (átkattintási arányt).
  2. A téma vizuális egységessége: A modern sablonok (például a GeneratePress vagy a GenerateBlocks segítségével tervezettek) a kiemelt képre támaszkodnak az archívumrácsok, a kapcsolódó bejegyzések listáinak vagy a fejléc kialakításához. Ennek hiányában az elrendezés összeomlik, vagy rosszul igazított rések maradnak.
  3. Felfedezés és hírcsatornák (RSS / Google Discover): Az olyan eszközök, mint a Google Discover vagy az RSS-olvasók, előnyben részesítik vagy megkövetelik a hozzájuk tartozó nagy felbontású miniatűrképet tartalmazó tartalmakat a cikkkártya megjelenésének javítása érdekében.

Annak érdekében, hogy ezt pluginok (például ez) vagy lassú folyamatok igénybevétele nélkül oldjam meg, készítettem ezt az egyszerű, könnyű PHP-kódrészletet, amely közvetlenül a WordPress irányítópultjáról automatikusan beállítja az egyes bejegyzések első képét kiemelt képként. Ha a bejegyzésedben nincs kép, akkor a kódba beillesztve az URL-jét, hozzárendelhetsz egy alapértelmezett képet.

Mit is csinál pontosan ez a kódrészlet?

A kód egy intelligens, beépített kötegelt feldolgozó eszközt ad hozzá a WordPress bejegyzéslistájához (wp-admin/edit.php):

  • Egyéni oszlop hozzáadása: Hozzon létre egy „Hiányzó kiemelt kép” nevű oszlopot a bejegyzések listájában, hogy egy pillantásra láthassa, melyik bejegyzésnél hiányzik a miniatűrkép.
  • 3 lépéses feldolgozás: Amikor engedélyezed a hozzárendelést egy bejegyzéshez, a rendszer pontosan ebben a sorrendben keresi meg a képet:
    1. Ellenőrizd, hogy vannak-e a Média-könyvtárban olyan képek, amelyek közvetlenül a bejegyzéshez vannak csatolva.
    2. Ha nincsenek közvetlen mellékletek (például ha azokat képblokkon vagy HTML-kódon keresztül illesztették be), akkor keresse meg a tartalomban az első <img> címkét, és az attachment_url_to_postid() függvény segítségével vonja ki annak azonosítóját.
    3. Ha a bejegyzés egyáltalán nem tartalmaz képet, akkor a rendszer a konfigurációban megadott alapértelmezett (tartalék) képet rendeli hozzá.
  • AJAX tömeges feldolgozás (kötegelt feldolgozás): A fejlécben található egy gomb („⚡ Az ezen az oldalon látható összes bejegyzés hozzárendelése”), amely egymást követő aszinkron kérések segítségével sorban feldolgozza a képernyőn látható összes bejegyzést. Ezt manuálisan is elvégezheti a listában szereplő egyes bejegyzések mellé tartozó gombok segítségével.
  • Vázlatok kiszűrése: A rendszer automatikusan kizárja a „vázlat” állapotú bejegyzéseket, így kizárólag a közzétett tartalmakra koncentrálhat.
  • Rendezhető oszlop: Lehetővé teszi a lista rendezését úgy, hogy az összes kiemelt kép nélküli bejegyzés a lista tetején legyen csoportosítva.

Miért ilyen könnyű, és ez nem befolyásolja-e a szerver teljesítményét?

Az ilyen típusú automatizált eszközök használatakor gyakran felmerülő aggodalom az, hogy az adatbázis leállhat, vagy a PHP memóriája túlterhelődhet azokon a webhelyeken, ahol több ezer cikk található. Ezt a kódrészletet a következő optimalizálási szempontok figyelembevételével tervezték:

1. Csak az Admin részben fut (is_admin())

A kód kizárólag az adminisztrációs panel beviteli képernyőjéhez (edit.php) készült. A nyilvános webhelyre érkező kérésekhez egyetlen sor felesleges kódot sem ad hozzá. Ez semmilyen módon nem befolyásolja a felhasználókat és a sebességi mutatókat.

2. A lekérdezéseket a Meta Cache-hez kell irányítani

Annak megállapításához, hogy egy bejegyzés tartalmaz-e képet vagy sem, a kódrészlet nem végez bonyolult adatbázis-lekérdezéseket minden egyes sorra vonatkozóan. A _thumbnail_id metaadat-kulcsot használja, amelyet a WordPress a lista megjelenítésekor natívan betölt a memóriába a metaadat-gyorsítótár segítségével. A táblázat szinte azonnal betöltődik.

3. Lépcsőzetes aszinkron feldolgozás (szekvenciális AJAX-ciklus)

Ahelyett, hogy egy hatalmas lekérdezést futtatnánk az adatbázisban 700 vagy 1 000 bejegyzés egyszerre történő frissítésére (ami időtúllépést okozna, vagy kimerítené a szerver teljes memóriáját), az „Assign All” gomb a bejegyzéseket egyenként dolgozza fel JavaScript-promiszek segítségével:

1. POST (AJAX)⟶„OK” válasz⟶2. POST (AJAX)⟶„OK” válasz…

Ez biztosítja az erőforrások stabil és következetes felhasználását, így soronként, valós időben követheti nyomon az előrehaladást.

4. Nincs fájlismétlődés

A kódrészlet nem tölti le, nem egyesíti és nem másolja a képeket a merevlemezre. Egyszerűen csak felveszi a Média-könyvtárban már meglévő kép azonosítóját, és a wp_postmeta táblában a megfelelő meta_value érték hozzárendelésével összekapcsolja azt a bejegyzéssel.

A kód (PHP + JavaScript)

Ezt a kódot beillesztheted a gyermektéma functions.php fájljába, egy egyéni bővítménybe, vagy egy egyéni függvényeket tartalmazó bővítményen keresztül, például a Code Snippets-en vagy hasonló eszközön keresztül.

Megjegyzés: Ne felejtsd el az 56. sorban a $default_image_url változót annak az általános képnek a teljes URL-címére beállítani, amelyet azokhoz a bejegyzésekhez szeretnél hozzárendelni, amelyek szövegében nincs kép.

PHP


// 1. Añadir columna personalizada en el listado de entradas
add_filter( 'manage_posts_columns', 'custom_featured_status_column' );
function custom_featured_status_column( $columns ) 
    $columns['featured_missing'] = 'Destacada Faltante';
    return $columns;
}

// 2. Hacer la columna ordenable al hacer clic en el encabezado
add_filter( 'manage_edit-post_sortable_columns', 'custom_featured_sortable_column' );
function custom_featured_sortable_column( $columns ) {
    $columns['featured_missing'] = 'featured_missing';
    return $columns;
}

// 3. Modificar la consulta para ordenar por presencia de _thumbnail_id
add_action( 'pre_get_posts', 'custom_featured_column_orderby' );
function custom_featured_column_orderby( $query ) {
    if ( ! is_admin() || ! $query->is_main_query() ) return;

    if ( $query->get( 'orderby' ) === 'featured_missing' ) {
        $query->set( 'meta_key', '_thumbnail_id' );
        $query->set( 'orderby', 'meta_value_num' );
        $query->set( 'meta_compare', 'NOT EXISTS' );
    }
}

// 3.1. Añadir desplegable de filtro nativo en el listado de entradas
add_action( 'restrict_manage_posts', 'custom_featured_filter_dropdown' );
function custom_featured_filter_dropdown( $post_type ) {
    if ( $post_type !== 'post' ) return;

    $selected = isset( $_GET['filter_featured_status'] ) ? sanitize_text_field( $_GET['filter_featured_status'] ) : '';
    ?>
    <select name="filter_featured_status" id="filter_featured_status">
        <option value=""><?php _e( 'Todas las destacadas', 'textdomain' ); ?></option>
        <option value="has_img" <?php selected( $selected, 'has_img' ); ?>>Tiene</option>
        <option value="missing_img" <?php selected( $selected, 'missing_img' ); ?>>Falta</option>
    </select>
    <?php
}

// 3.2. Aplicar el filtro del desplegable a la consulta de WP_Query
add_filter( 'parse_query', 'custom_featured_filter_apply' );
function custom_featured_filter_apply( $query ) {
    global $pagenow;
    if ( ! is_admin() || $pagenow !== 'edit.php' || ! $query->is_main_query() ) return;

    if ( isset( $_GET['filter_featured_status'] ) && $_GET['filter_featured_status'] !== '' ) {
        $filter_value = sanitize_text_field( $_GET['filter_featured_status'] );
        $meta_query   = (array) $query->get( 'meta_query' );

        if ( $filter_value === 'has_img' ) {
            $meta_query[] = array(
                'key'     => '_thumbnail_id',
                'compare' => 'EXISTS',
            );
        } elseif ( $filter_value === 'missing_img' ) {
            $meta_query[] = array(
                'key'     => '_thumbnail_id',
                'compare' => 'NOT EXISTS',
            );
        }

        $query->set( 'meta_query', $meta_query );
    }
}

// 4. Mostrar el estado y el botón rápido en la columna (Excluyendo borradores)
add_action( 'manage_posts_custom_column', 'custom_featured_status_column_content', 10, 2 );
function custom_featured_status_column_content( $column, $post_id ) {
    if ( $column === 'featured_missing' ) {
        if ( get_post_type( $post_id ) !== 'post' || get_post_status( $post_id ) === 'draft' ) {
            echo '<span style="color: #999;">—</span>';
            return;
        }

        $has_thumbnail = get_post_meta( $post_id, '_thumbnail_id', true );

        if ( $has_thumbnail ) {
            echo '<span style="color: #46b450; font-weight: bold;">✔ Tiene</span>';
        } else {
            echo '<span style="color: #dc3232; font-weight: bold;">❌ Falta</span> ';
            echo '<button type="button" class="button button-small set-first-img-btn" data-postid="' . esc_attr( $post_id ) . '">Asignar imagen</button>';
            echo '<span class="set-img-status" style="margin-left:5px;"></span>';
        }
    }
}

// 5. Procesar la asignación por AJAX (con fallback a la imagen por defecto)
add_action( 'wp_ajax_set_first_image_as_featured', 'ajax_set_first_image_as_featured' );
function ajax_set_first_image_as_featured() {
    check_ajax_referer( 'set_first_image_nonce', 'nonce' );

    $post_id = isset( $_POST['post_id'] ) ? intval( $_POST['post_id'] ) : 0;
    if ( ! $post_id || ! current_user_can( 'edit_post', $post_id ) ) {
        wp_send_json_error( 'Sin permisos o ID inválido' );
    }

    if ( get_post_status( $post_id ) === 'draft' ) {
        wp_send_json_error( 'La entrada es un borrador' );
    }

    // =========================================================================
    // CONFIGURACIÓN: Reemplaza esta URL por la URL completa de tu imagen por defecto
    // =========================================================================
    $default_image_url = 'https://tu-dominio.com/wp-content/uploads/imagen-por-defecto.jpg';

    // A. Buscar adjuntos directos al post
    $attachments = get_posts( array(
        'post_type'      => 'attachment',
        'posts_per_page' => 1,
        'post_parent'    => $post_id,
        'post_mime_type' => 'image',
        'orderby'        => 'menu_order',
        'order'          => 'ASC',
        'fields'         => 'ids'
    ) );

    if ( ! empty( $attachments ) ) {
        set_post_thumbnail( $post_id, $attachments[0] );
        wp_send_json_success( '¡Asignada primera!' );
    }

    // B. Si no hay adjuntos, buscar <img> en el contenido
    $post = get_post( $post_id );
    preg_match_all( '/<img.+?src=[\'"]([^\'"]+)[\'"]/i', $post->post_content, $matches );

    if ( isset( $matches[1][0] ) ) {
        $attachment_id = attachment_url_to_postid( $matches[1][0] );
        if ( $attachment_id ) {
            set_post_thumbnail( $post_id, $attachment_id );
            wp_send_json_success( '¡Asignada primera!' );
        }
    }

    // C. Si no hay ninguna imagen en el post, asignar la imagen por defecto
    if ( ! empty( $default_image_url ) ) {
        $default_id = attachment_url_to_postid( $default_image_url );

        if ( $default_id ) {
            set_post_thumbnail( $post_id, $default_id );
            wp_send_json_success( '¡Asignada por defecto!' );
        }
    }

    wp_send_json_error( 'No se encontró ninguna imagen en el post ni ID de fallback' );
}

// 6. Cargar JS y botón masivo en el admin (edit.php)
add_action( 'admin_footer-edit.php', 'custom_featured_ajax_script' );
function custom_featured_ajax_script() {
    $screen = get_current_screen();
    if ( $screen->post_type !== 'post' ) return;
    
    $nonce = wp_create_nonce( 'set_first_image_nonce' );
    ?>
    <script>
    jQuery(document).ready(function($) {
        $('<button type="button" id="process-all-page-btn" class="page-title-action" style="margin-left:10px; background:#2271b1; color:#fff; border-color:#2271b1;">⚡ Asignar todas en esta página</button>')
            .insertAfter('.wp-heading-inline');

        function processButton($btn) {
            return new Promise(function(resolve) {
                var $status = $btn.siblings('.set-img-status');
                var postId = $btn.data('postid');

                $btn.prop('disabled', true).text('Procesando...');

                $.post(ajaxurl, {
                    action: 'set_first_image_as_featured',
                    post_id: postId,
                    nonce: '<?php echo $nonce; ?>'
                }, function(response) {
                    if (response.success) {
                        $btn.parent().html('<span style="color: #46b450; font-weight: bold;">✔ ' + response.data + '</span>');
                    } else {
                        $status.css('color', '#dc3232').text(response.data);
                        $btn.prop('disabled', false).text('Asignar imagen');
                    }
                    resolve();
                }).fail(function() {
                    $btn.prop('disabled', false).text('Error');
                    resolve();
                });
            });
        }

        $(document).on('click', '.set-first-img-btn', function(e) {
            e.preventDefault();
            processButton($(this));
        });

        $('#process-all-page-btn').on('click', async function(e) {
            e.preventDefault();
            var $batchBtn = $(this);
            var $pendingButtons = $('.set-first-img-btn:not(:disabled)');

            if ($pendingButtons.length === 0) {
                alert('No hay entradas pendientes de asignar en esta página.');
                return;
            }

            $batchBtn.prop('disabled', true).text('Procesando por lote...');

            for (var i = 0; i < $pendingButtons.length; i++) {
                await processButton($($pendingButtons[i]));
            }

            $batchBtn.text('¡Lote completado!').css('background', '#46b450');
            setTimeout(function() {
                $batchBtn.prop('disabled', false).text('⚡ Asignar todas en esta página').css('background', '#2271b1');
            }, 3000);
        });
    });
    </script>
    <?php
}

Hogyan kell használni?

  • Nyisd meg a „Bejegyzések” listát az adminisztrációs panelen.
  • Nyissa meg a tetején található „Megjelenítési beállítások” fület, és állítsa be az oldalanként megjelenítendő elemek számát 50-re vagy 100-ra. (Kezdje kisebb számokkal, és fokozatosan növelje őket, ha a szerver megfelelően reagál.)

A hiányzó kiemelt képek tömeges hozzárendelése a WordPressben. Megjelenítési beállítások

  • Kattintson a „Hiányzó kiemelt elemek” oszlopfejlécére a fennmaradó bejegyzések rendezéséhez és csoportosításához. A szűrőkben választhat a „Van”, „Hiányzik” vagy „Minden” lehetőségek közül.
  • Ha biztos benne, hogy készen áll a hiányzó kiemelt képek tömeges hozzárendelésének megkezdésére, kattintson a kék gombra, amelyen az „Assign all on this page” felirat látható, és hagyja, hogy a folyamat befejezze a miniatűrök hozzárendelését az adott tételhez. Ha úgy kívánja, a képeket egyenként is hozzárendelheti.
  • Lépj át a következő oldalra, és ismételgesd ezt, amíg be nem fejezted a könyvtárad rendezését.

Opcionális: automatikus hozzárendelési kódrészlet

Annak érdekében, hogy a jövőben ne kelljen ezt a műveletet megismételni, beillesztheted ezt a rövid kódrészletet. Ez csak akkor fut a háttérben, amikor egy bejegyzést mentesz vagy közzéteszel: ha észleli, hogy nem választottál ki kézzel kiemelt képet, automatikusan a tartalomban szereplő első képet rendeli hozzá (vagy az alapértelmezett tartalék képet, amelyet a $default_image_url = sorba kell beírnod).

PHP

// Asignar imagen destacada automáticamente al publicar/guardar nuevas entradas
add_action( 'save_post_post', 'auto_set_featured_image_on_save', 10, 3 );
function auto_set_featured_image_on_save( $post_id, $post, $update ) {
    // Evitar autoguardados, revisiones o peticiones AJAX/REST innecesarias
    if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
    if ( wp_is_post_revision( $post_id ) || $post->post_status === 'auto-draft' ) return;

    // Si la entrada ya tiene imagen destacada marcada, no hacemos nada
    if ( has_post_thumbnail( $post_id ) ) return;

    $default_image_url = 'https://tu-dominio.com/wp-content/uploads/imagen-por-defecto.jpg';

    // 1. Buscar primera imagen en el contenido
    preg_match_all( '/<img.+?src=[\'"]([^\'"]+)[\'"]/i', $post->post_content, $matches );

    if ( isset( $matches[1][0] ) ) {
        $attachment_id = attachment_url_to_postid( $matches[1][0] );
        if ( $attachment_id ) {
            set_post_thumbnail( $post_id, $attachment_id );
            return;
        }
    }

    // 2. Si el post no tiene imágenes, asignar la imagen por defecto
    if ( ! empty( $default_image_url ) ) {
        $default_id = attachment_url_to_postid( $default_image_url );
        if ( $default_id ) {
            set_post_thumbnail( $post_id, $default_id );
        }
    }
}

Szólj hozzá!

Van valami mondanivalója?

Este blog se aloja en LucusHost

LucusHost, el mejor hosting