Ana sorgunun ve özel sorgunun bu özel temada nasıl çalıştığı hakkında bazı şüpheler mi var?


20

WordPress tema geliştirmede oldukça yeniyim ve PHP (Java ve C # 'dan geldim) içine girmiyorum ve bu özel temada aşağıdaki duruma sahibim

Ana sayfada da görebileceğiniz gibi ilk olarak öne çıkan yazıları içeren bir bölümü ( evidenza'da Articoli olarak adlandırıyorum ) gösterdim (belirli bir etiketi kullanarak uyguladım) ve altında en son yayını içeren başka bir alan ( Ultimi Articoli adlı ) var öne çıkan yazı değil.

Bunu yapmak için bu kodu kullanın:

<section id="blog-posts">

<header class="header-sezione">
        <h2>Articoli in evidenza</h2>
</header>

<!--<?php query_posts('tag=featured');?>-->

<?php
    $featured = new WP_Query('tag=featured');

    if ($featured->have_posts()) : 
            while ($featured->have_posts()) : $featured->the_post();
            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
                 get_template_part('content', get_post_format());

             endwhile;
        wp_reset_postdata();
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>


<header class="header-sezione">
    <h2>Ultimi Articoli</h2>
</header>

<?php
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            /*
             * Include the post format-specific template for the content. If you want to
             * use this in a child theme, then include a file called called content-___.php
             * (where ___ is the post format) and that will be used instead.
             */
            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
    ?>

</section>

İyi çalışıyor, ancak bu çözümün kalitesi ve tam olarak nasıl çalıştığı hakkında bazı şüphelerim var.

Tüm özellikli yayınları seçmek için WP_Query, belirli bir etikete sahip bir sorguyu tanımlayan yeni bir nesne oluşturan bu satırı kullanıyorum featured:

$featured = new WP_Query('tag=featured');

Sonra have_posts()yöntemini kullanarak bu sorgu sonucunu yineleme .

Yani, anladığım kadarıyla, bu WordPress ana sorgu değil, ama benim tarafımdan oluşturulan yeni bir sorgu. Anladığım kadarıyla, daha iyi yeni bir sorgu (bittiğinde) oluşturmak ve bu tür bir işlem gerçekleştirmek istediğinizde ana sorguyu kullanmak daha iyidir.

Doğru mu yoksa bir şey mi kaçırıyorum? Doğruysa, bana açıklayabilir misiniz, neden yeni bir özel sorgu oluşturmak ve Wordpress ana sorgusunu değiştirmemek daha iyidir?

Tamam, devam ediyor. 'Öne çıkan' etiketine sahip olmayan tüm yayınları gösteriyorum. Bunu yapmak için, tam tersine ana sorguyu değiştirir bu kod snippet'i kullanın:

    <?php
    // get the term using the slug and the tag taxonomy
    $term = get_term_by( 'slug', 'featured', 'post_tag' );
    // pass the term_id to tag__not_in
    query_posts( array( 'tag__not_in' => array ( $term->term_id )));
    ?>

    <?php
        if (have_posts()) :
            // Start the Loop.
            while (have_posts()) : the_post();
                get_template_part('content', get_post_format());

            endwhile;
        else :
            // If no content, include the "No posts found" template.
            get_template_part('content', 'none');

        endif;
        ?>

Bence bu oldukça korkunç. Bu doğru mu?

GÜNCELLEME:

Aynı işlemi yapmak için, function.php dosyasına eklediğim bu işlevi (aşağıdaki büyük cevapta) buldum.

function exclude_featured_tag( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        $query->set( 'tag__not_in', 'array(ID OF THE FEATURED TAG)' );
    }
}
add_action( 'pre_get_posts', 'exclude_featured_tag' );

Bu işlev, sorgu değişkeni nesnesi oluşturulduktan sonra, ancak gerçek sorgu çalıştırılmadan önce çağrılan bir kancaya sahiptir.

Yani, anladığım kadarıyla, giriş parametresi olarak bir sorgu nesnesi alır ve belirli bir etiket (benim durumumda featuredetiket mesajları) hariç tüm mesajları seçerek (aslında filtreler) değiştirir

Öyleyse, önceki sorguyu (özellikli yayınları göstermek için kullanılan sorgu) bu işlevle yalnızca temamdaki özellikli olmayan yayınları göstermek için nasıl kullanabilirim? Yoksa yeni bir sorgu oluşturmak zorunda mıyım?

Yanıtlar:


33

Asıl sorunuz temel olarak ne zaman özel bir sorgu çalıştırılacağı ve ana sorgudan ne zaman yararlanılacağıdır. Üç parçaya ayıralım

BÖLÜM BİR

Özel bir sorgu ne zaman çalıştırılır (Bu kesin bir liste değildir)

  • Özel içerik kaydırıcıları oluşturmak için

  • Sayfada öne çıkan bir içerik alanı oluşturmak için

  • Yayınları görüntülemeniz gerekiyorsa page.php şablonlarında

  • Statik bir ön sayfada özel içeriğe ihtiyacınız varsa

  • İlgili, popüler veya bilgilendirici yayınları görüntüle

  • Ana sorgunun kapsamı dışındaki diğer ikincil veya tamamlayıcı içerik

Ana sorgu ne zaman kullanılır?

Birincil içeriği görüntülemek için

  • Ana sayfanızda ve arka uçta bir blog sayfası olarak ayarlanan sayfada

  • Archive.php, category.php, author.php, taxonomy.php, tag.php ve date.php gibi şablonları içeren tüm arşiv sayfaları

  • GÜNCELLEME: Gerçek sayfalarda ve statik bir ön sayfada özel içerik görüntüleme ( bkz . Gerçek sayfalarda ve statik ön sayfalarda pre_get_posts kullanma )

BÖLÜM İKİ

Tüm özellikli mesajları seçmek için belirli bir etiketi özellikli bir sorgu tanımlayan yeni bir WP_Query nesnesi oluşturan bu satırı kullanıyorum:

Yani, anladığım kadarıyla, bu WordPres ana sorgu değil ama benim tarafımdan oluşturulan yeni bir sorgu. Ne anladım daha iyi (gibi) yeni bir sorgu oluşturmak ve bu tür işlemleri gerçekleştirmek istediğinizde ana sorguyu kullanmak değil

Doğru. Bu, ana sorgu kapsamı dışında kalır. Bu, ana sorgu ile oluşturulamayan ikincil veya tamamlayıcı içeriktir. Sen DAİMA GEREKEN birini kullanın WP_Queryveya get_postskendi özel sorguları oluşturun.

ASLA query_posts özel sorgular veya başka bir sorgu oluşturmak için KULLANMAYIN . Vurgu.

Not: Bu işlev eklentiler veya temalar tarafından kullanılmak üzere tasarlanmamıştır. Daha sonra açıklandığı gibi, ana sorguyu değiştirmek için daha iyi, daha performanslı seçenekler vardır. query_posts (), bir sayfanın ana sorgusunu, sorgunun yeni örneğiyle değiştirerek değiştirmenin aşırı basit ve sorunlu bir yoludur. Verimsizdir (SQL sorgularını yeniden çalıştırır) ve bazı durumlarda açıkça başarısız olur (özellikle yazıların sayfalandırılmasıyla uğraşırken).

Hareketli

Tamam, devam özellikli etiketi olmayan tüm mesajları gösterir, bunu yapmak için ben tam olarak ana sorguyu değiştirmek bu kod snippet'i kullanın:

query_posts( array( 'tag__not_in' => array ( $term->term_id )));

Bu yüzden bunun oldukça korkunç olduğunu düşünüyorum. Bu doğru mu?

Hepsi yanlış ve ifadeniz maalesef doğru. Daha önce de belirtildiği gibi, ASLA kullanmayın query_posts. Performans için kötü olan tamamen yeni bir sorgu çalıştırır ve çoğu durumda sayfalamanın doğru çalışması için ana sorgunun ayrılmaz bir parçası olan sayfalandırmayı keser.

Bu birincil içeriğinizdir, bu nedenle ana sorguyu varsayılan döngü ile kullanmalısınız, bu şekilde görünmelidir ve ihtiyacınız olan tek şey budur

<?php
    if (have_posts()) :
        // Start the Loop.
        while (have_posts()) : the_post();

            get_template_part('content', get_post_format());

        endwhile;
    else :
        // If no content, include the "No posts found" template.
        get_template_part('content', 'none');

    endif;
?>

Bu bölümden tamamen kurtulabilir, silebilir, yakabilir ve unutabilirsiniz

<?
// get the term using the slug and the tag taxonomy
$term = get_term_by( 'slug', 'featured', 'post_tag' );
// pass the term_id to tag__not_in
query_posts( array( 'tag__not_in' => array ( $term->term_id )));
?>

Tamam, bunu yaptıktan sonra, özellik etiketindeki yayınların ana sorgunuzu ve varsayılan döngüyü kullanarak ana sayfanızda göründüğünü göreceksiniz.

Bu etiketi ana sayfadan kaldırmanın doğru yolu pre_get_posts. Bu, ana sorguyu ve her zaman birincil içerik döngünüzde değişiklik yapmak için kullanmanız gereken kancayı değiştirmenin uygun yoludur .

Bu nedenle, ile kod pre_get_postsdoğrudur ve bu, kullanmanız gereken işlevdir. Sadece bir şey, her zaman bir yönetici sayfasında olmadığınızı kontrol edin çünkü pre_get_postsarka ucu da değiştirir. Bu kullanıma doğru kod olduğu Yani functions.phpkaldır mesajlarý tagged özellikli ana sayfasından

add_action( 'pre_get_posts', 'exclude_featured_tag' );
function exclude_featured_tag( $query ) 
{
    if (    !is_admin() 
         && $query->is_home() 
         && $query->is_main_query() 
    ) {
        $query->set( 'tag__not_in', [ID OF THE FEATURED TAG] );
    }
}

ÜÇÜNCÜ KISIM

Gelecekte yardımcı olacak ekstra okuma materyali


Zevkle. Kullanışlı bulduğuna sevindim. Enjou :-)
Pieter Goosen

Vay, oldukça cevap! Ancak kritik bir bilgi eksik: ana mesaj sayfasının yanı sıra WP "bu bir yazı sayfasıdır" nasıl söyleyebilirim ? Diyelim ki 10,11,12 kategorisine sahip bir gönderi listesi ve 13,14,15 kategorisine sahip başka bir liste istiyorum. Ana sorguya kategorileri enjekte etmek için pre_get_posts nasıl kullanabilirsiniz, ama nasıl WP uygun sayfalandırma ile gönderilerin bir listesi olarak işlemek için söyleyebilirim? Buradaki kapsamlı cevabınızı gerçekten takip etmek zorunda mıyım wordpress.stackexchange.com/a/215027/74134 Çünkü bir Sayfa mı? Elbette WordPress bir sitede birden çok blog listesine izin veriyor mu?
Mark Berry
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.