Bútaúthluta vantar valmyndamyndir í WordPress

No comments

05.09.2026|

No comments

Tiempo de lectura Lectura: 13 min, 5 s
Número de palabras Palabras: 2423
Número de visitas Visitas: 11
Icono de traducción
Úthluta vantar forsíðumyndum í stórum stíl í WordPress. Listi sem sýnir bæði vantar og núverandi myndir.

Fyrir nokkrum dögum kláraði ég langþráða verkefni sem þurfti að gera en ég hafði frestað því í langan tíma. Égsótti allarvantar forsíðamyndir og bætti við allri vantar valmyndatexta. Ég kláraði líka að skrifa allar vantar meta-lýsingar. Alls bætti ég við eða breytti yfir 15.000 færslum með þremur einnota kóðabrotum sem ég bjó til sjálfur. Í dag deili ég hér kóðabroti til að sækja vantar forsíðamyndir, sem ég notaði einnig til að framkvæma þetta verkefni á öðrum vefsíðum.

Ef þú hefur verið að blogga um tíma er nokkuð líklegt að þú hafir nokkuð mörg eldri innlegg sem ekki hafa úthlutað sérstaka forsíðumynd. Þetta gerðist oft á tímum klassíska ritilsins, þegar við settum mynd beint inn í textann en gleymdum að velja hana í reitnum "Valin mynd".

Að skilja færslur eftir án aðalsmyndar er ekki bara fagurfræðilegt mál, meðal annars; það hefur bein áhrif á fínstillingu vefsíðunnar þinnar og notendaupplifunina:

  1. Félagslegt SEO og Open Graph: Þegar færslan er deilt á samfélagsmiðlum, skilaboðaforritum eða efnisaðilum finnur Open Graph-merkingin (og:image) ekki skýrt úrræði til birtingar, sem dregur verulega úr smellihlutfalli (CTR).
  2. Sjónræn samræmi í þemanu: Nútímaleg sniðmát (t.d. þau sem hönnuð eru með GeneratePress eða GenerateBlocks) byggja á forsíðumyndinni til að búa til skráargirðingar, lista yfir tengdar færslur eða hausa. Án hennar brotnar uppsetningin eða skilur eftir sig misræmdar eyður.
  3. Uppgötvun og fóðurstraumar (RSS / Google Discover): Verkfæri eins og Google Discover eða RSS-lesarar forgangsraða eða krefjast efnis með tengdri smámynd í hári upplausn til að bæta greinakortið.

Til að leysa þetta án þess að nota viðbætur (eins og þessa) eða hægar ferla hef ég búið til þennan einfalda, léttvæga PHP-kóðabrot sem stillir sjálfkrafa fyrstu myndina í hverri færslu sem aðalmynd beint úr WordPress-stjórnborðinu. Ef færslan þín inniheldur engar myndir geturðu úthlutað sjálfgefinni mynd með því að bæta vefslóð hennar við kóðann.

Hvað gerir þessi kóðabrot nákvæmlega?

Kóðinn bætir snjöllum, innbyggðum lotuvinnsluverkfæri við færslulista WordPress (wp-admin/edit.php):

  • Bættu við sérsniðnum dálki: Búðu til dálkinn "Falt forvalmyndamynd " í listanum yfir færslur til að sjá á einu augabragði hvaða færslur skortir smámynd.
  • 3-laga vinnsla: Þegar þú virkjar úthlutun fyrir færslu leitar hún að myndinni í þessari nákvæmu röð:
    1. Skoðaðu hvort einhverjar myndir séu beint tengdar við færsluna í Myndasafninu.
    2. Ef engar beinar viðhengi eru til (til dæmis ef þau voru sett inn í gegnum myndablokk eða HTML), skannaðu efnið fyrir fyrsta -merkið til að draga út ID-ið með attachment_url_to_postid().
    3. Ef færslan inniheldur alls engar myndir, er sjálfgefin (vara) mynd sem tilgreind er í stillingunum notuð.
  • AJAX fjöldavinnsla (lotuvinnsla): inniheldur hnapp í hausnum ( "Úthluta öllum á þessari síðu") sem vinnur alla færslur sem sjást á skjánum í röð með samfelldum ósamhverfum beiðnum. Þú getur líka gert þetta handvirkt með því að nota einstaklingshnappinn fyrir hverja færslu í listanum.
  • Sía drög: útilokar sjálfkrafa færslur í drögastöðu svo þú getir einbeitt þér eingöngu að birtu efni.
  • Röðunarsúla: Leyfir þér að raða listanum þannig að allar færslur sem ekki hafa valmyndmynd séu hópaðar saman efst.

Af hverju er það svo léttvægt og hefur það ekki áhrif á frammistöðu netþjónsins?

Algeng áhyggjuefni þegar þessi tegund sjálfvirks tóls er notuð er ótti við að læsa gagnagrunninn eða yfirhlaða PHP-minni á vefsíðum með þúsundir greina. Þetta kóðabrot hefur verið hannað í samræmi við eftirfarandi fínstillingarkröfur:

1. Keyrir aðeins í stjórnendahlutanum (is_admin())

Kóðinn er eingöngu pakkaður fyrir innsláttar­skjá stjórnendaborðsins (edit.php). Hann bætir ekki einni einustu línu af aukakóða við beiðnir á opinberu vefsvæðinu. Notendur þínir og hraðamælingar verða ekki fyrir neinum áhrifum.

2. Beinar fyrirspurnir til Meta-geymslu

Til að ákvarða hvort færsla innihaldi mynd eða ekki framkvæmir kóðabrot ekki flókin gagnagrunnaleit fyrir hverja röð. Það notar metadata-lykilinn _thumbnail_id, sem WordPress hleður beint í minni með metadata-geymslunni þegar listinn er birtur. Taflan hleðst nánast samstundis.

3. Stigskipt asynkron vinnsla (raðbundinn AJAX-lykkja)

Í stað þess að keyra gríðarlega fyrirspurn á gagnagrunninum til að uppfæra 700 eða 1.000 færslur í einu (sem myndi valda tímalokun eða nota alla vinnsluminni netþjónsins), vinnur hnappurinn "Úthluta öllum" færslurnar eina í einu með JavaScript-heitum:

POST 1 (AJAX)⟶OK-svör⟶POST 2 (AJAX)⟶OK-svör…

Þetta tryggir stöðuga og samræmda nýtingu auðlinda, sem gerir þér kleift að sjá framvindu í rauntíma, röð fyrir röð.

4. Engin skráardúplikun

Kóðabrotinu hleður ekki niður, sameinar ekki aftur né afritar myndir á harða disknum þínum. Það tekur einfaldlega ID myndarinnar sem þegar er í fjölmiðlasafninu þínu og tengir hana við færsluna með því að úthluta viðeigandi meta_gildi í wp_postmeta-töflunni.

Kóðinn (PHP + JavaScript)

Þú getur bætt þessum kóða við functions.php -skrána í barnþema þínu, í sérsniðið viðbót eða með sérsniðnu functions-viðbót eins og Code Snippets eða álíka.

Athugið: Mundu að stilla breytuna $default_image_url á línu 56 á fullri vefslóð almennu myndarinnar sem þú vilt úthluta færslum sem innihalda engar myndir í texta.

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
}

Hvernig notarðu það?

  • Farðu í 'Færslur '-lista í stjórnendaspjaldinu þínu.
  • Opnaðu flipann 'Skoðunarvalkostir' efst og breyttu fjölda sýndra atriða á síðu í 50 eða 100. (Byrjaðu á því að prófa lægri tölu og hækkaðu hana smám saman ef netþjónninn bregst vel við.)

Bútaúthluta vantar valmyndir í WordPress. Sýningarmöguleikar

  • Smelltu á kolunnarhausinn "Missing Highlights" til að raða og hópa eftir ógreindum færslum. Í síum geturðu valið á milli "Has", "Missing" eða "All".
  • Þegar þú ert viss um að þú sért tilbúinn að byrja að úthluta vantar forsíðumyndum í lotum, smelltu á bláa hnappinn " " merktan "Assign all on this page" og láttu lotukerfið klára að úthluta smámyndunum fyrir þá lotu. Ef þú kýst geturðu úthlutað þeim einni og einni.
  • Farðu á næstu síðu og endurtaktu þar til þú hefur lokið við að hreinsa bókasafnið þitt.

Valfrjálst: sjálfvirkur úthlutunarkóðarúttak

Til að forðast að þurfa að endurtaka þetta verkefni í framtíðinni geturðu bætt við þessum stutta kóðabrot. Það keyrir í bakgrunni aðeins þegar þú vista eða birtir færslu: ef það greinir að þú hafir ekki valið aðalmynd handvirkt, úthlutar það sjálfkrafa fyrstu myndinni í efninu (eða sjálfgefnu varamyndinni, sem þú þarft að bæta við í $default_image_url =).

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 );
        }
    }
}

Leave a Comment

Eitthvað að segja?

Este blog se aloja en LucusHost

LucusHost, el mejor hosting