(Have_posts ()), while (have_posts ()) yeterli değilse neden koymak zorundayım?


22

"Döngü" hakkında bir sorum var.

<?php if ( have_posts() ) : while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>

Döngü WordPress Kodeksi sayfasından alınan kod .

Neden katılmalıyım if? whileDöngü varsa , iyi çalışıyor gibi görünüyor .

İfade yoksa hangi durumda sorun oluşur if?

Düzenle

@ Chip'in cevabını kabul ettim. ama dürüstçe söylemek gerekirse sadece son kısma ihtiyacım var.

Şimdi sorumdan ne bilmek istediğimi biliyorum.

ifdeyimi yalnızca gerektiğinde, yalnızca bir kez yazması gereken bir üstbilgi veya altbilgi koymak istiyorsanız kullanılır. "sarmalayıcı" kullanmazsanız, ififade gerekmez.


2
Thecontent'i okumadan önce oy kullandım, the_title belirleyici!
brasofilo

Mükemmel (final) düzenleme. Çoğu insan, if kullanarak ve bir süre sonra birbirini kullanmadan doğrudan kullanmaktadır. Muhtemelen kopyala ve yapıştır yüzünden.
Herbert Van-Vliet

Yanıtlar:


29

WordPress şablon yükleyicisi, çoğu durumda uygun bağlam şablonu şablonunu içerecektir, bu bağlam için sorgu gönderilmese bile. Örneğin:

  • Ana Blog Yazıları Dizini
  • Kategori Arşiv Dizini (Kategori var, ancak gönderi yok)
  • Etiket Arşivi Dizini (Etiket var, ancak mesajı yok)
  • Yazar Arşivi İndeksi (Yazar var ancak yayın yok)
  • Arama Sonuçları Dizini

Bu nedenle, bu durumlarda, uygun şablon dosyası yüklenecek, ancak sorgu gönderilemediğinden gönderiler gönderilmez.

Kavram kanıtı örnekleri:

Bu nedenle, bu bağlamlarda, şablon dosyasının if ( have_posts() )koşullu içermesi yararlıdır .

Diğer bağlamlarda, sorgu gönderilmezse şablon dosya asla yüklenmez. Örneğin:

  • Tek blog yazısı
  • Statik sayfa

Bu bağlamlarda, if ( have_posts() )muhtemelen gereksizdir.

Düzenle

Sorgunun the_post () tarafından çağrıldığını anlıyorum, değil mi? Ve eğer (have_posts ()) varsa, yazı yoksa sorgu asla gerçekleşmez.

Neler olduğunu anlamak için, WordPress işlemlerinin sırasına bakmak zorundasınız . wp_loadedİle başlayan (ve bazı netlik için ihmal):

  • wp_loaded
  • parse_request
  • send_headers
  • parse_query
  • pre_get_posts
  • wp
  • template_redirect
  • get_header
  • wp_head
  • the_post
  • wp_footer

Peki neler oluyor ve hangi sırada?

  • Sorgu başlatıldı:
    • parse_query
    • pre_get_posts
    • wp
  • Şablon seçildi:
    • template_redirect
  • Şablon yüklenir / çıkar. Aşağıdaki işlemler şablon tarafından gerçekleştirilir :
    • get_header
    • wp_head
    • the_post
    • dynamic_sidebar
    • get_footer
    • wp_footer

Yani, the_posttarafından ateş the_post()olur, uzun süre sonra sorgu mesajlar getirilen, ayrıştırılır ve şablon yüklenir.

Bilmediğim çok fazla bilgi verdiğiniz için minnettarım, ama istediğim bu değildi.

Oh, ama tam olarak istediğinin bu olduğuna inanıyorum .

Asıl soru şudur: geçerli bir sorgu dönüşü nedir? Kategori arşiv dizini gibi bağlamlar için, sorgu geçerli ve sorgulanan kategori kimliği varsa, bu kategoriye atanmış bir yazı olmasa bile kategori şablonu yüklenir .

Niye ya? Çünkü ayrıştırılmakta olan sorgu (IIRC) &cat={ID}- bu kategoriye atanmış mesaj olmasa bile geçerli bir sorundur ve bu nedenle ayrıştırma sırasında 404 ile sonuçlanmaz.

Bu durumda geçerli bir sorgu alırsınız ve bir şablon dosyası yüklenir, ancak yazı gönderilmez . Böylece if ( have_posts() ), aslında, alakalı. Yine, işte bir örnek: kategori var, ancak atanmış yazı yok. Kategori şablon dosyası ile yüklenen if ( have_posts() )dönenfalse .

Bu, tek blog gönderileri ve statik sayfalar gibi bir gönderi değişkeni ( &p={ID}) içeren sorgular için geçerli olmaz , çünkü gönderi gerçekten varolmaz ve ayrıştırıldığında, sorgu geçerli bir nesne döndürmez.

Düzenle 2

Eğer bir kategori şablonunda if (have_posts ()) olup olmadığını ve kategorinin postası olmadığını doğru anlarsam, 404.php döndürür, post-example.php gönderilmeden dönmesi gerekse bile. Bu doğru mu?

Hayır. Unutmayın: şablon olarak seçilir template_redirect. Eğer sorgu geçerliyse, uygun şablon dosyası yüklenir. Sorgu geçerli değilse, 404 şablonu yüklenir.

Bu nedenle, bir şablon yüklendiğinde - örneğin kategori şablonu - döngü çıktığında, şablon değişmez .

İşlem sırasına tekrar bakın:

  • parse_query
  • pre_get_posts
  • wp
  • template_redirect- burada şablon seçilir ve yüklenir. Bu, geri dönüşü olmayan şablon noktasıdır . Bu noktadan sonra şablon değişemez.
  • ...
  • the_post- Postdata burada döngü çağrısının bir parçası olarak kurulur. Buna şablonun içinde denir ve şablon , sorgu nesnesindeki kullanılabilir verilere göre değişmez

Son Düzenleme

Ve ben yazıların varlığını kontrol ederken, neden aynı testi iki kez yapmam gerektiğini iddia ediyorum. Bu sadece benim sorduğum ilk noktadan itibaren sorum.

Ve bununla nihayet anladım: başından beri, sorunuzun WordPress veya WordPress Loop ile ilgisi yoktu . İstediğiniz herhangi bir PHP whiledöngüsünü ifaynı koşulu kontrol eden bir koşul içinde sarmayı istiyorsunuz .

Bu soru WPSE'nin kapsamı dışında, ancak kısaca açıklayacağım:

Bir ifkoşullu ikili değerlendirmedir: ya ya trueda false, ve bu şartın içinde ne olduğu bir kez yapılır .

Bir whilekoşullu a, döngü : tezgahın bir çeşit göre, bazı kesikli bir süre boyunca doğru kalır; ve bu şartın içinde ne olduğu birkaç kez yapılır - sayacın her tekrarı için bir kez .

Öyleyse, eğer bir şeyler listesi doldurulursa, sıralanmamış bir şeyler listesi almak istediğinizi varsayalım. Bir whiledöngü kullanır ve ifsarmalayıcıyı atlarsanız, işaretlemeniz şöyle görünür:

<ul>
<?php while ( list_of_things() ) : ?>
    <li><?php the_list_item(); ?></li>
<?php endwhile; ?>
</ul>

Ve list_of_things()boş olsaydı , oluşturulan çıktı şöyle olurdu:

<ul>
</ul>

Gereksiz (ve geçersiz) işaretler.

Ancak ifkoşullu bir sarmalayıcı eklerseniz , bunu yapabilirsiniz:

<?php if ( list_of_things() ) : ?>
    <ul>
    <?php while ( list_of_things() ) : ?>
        <li><?php the_list_item(); ?></li>
    <?php endwhile; ?>
    </ul>
<?php endif; ?>

Ve eğer list_of_things()boş olsaydı , hiçbir işaretleme yapılmazdı.

Bu sadece bir örnek. Bu ifkoşullu sarıcı için birçok kullanım alanı vardır ve ifkoşullu sargı , döngüden tamamen farklı bir amaca hizmet eder while.


2
Benim tekil yazı / sayfa şablonları olarak, uzun zamandan beri, sadece kullanmak the_post();nedeniyle de whilegereksizdir. Bilgilerin eksiksizliği için +1.
gmazzap

@GM Muhtemelen if( have_posts() )ifadeyi kaldırmak mantıklı (bulmaya çalıştığım şey bu), fakat sadece the_post()tekil sayfalarda kullanmayın !
Sunyatasattva

@ChipBennett Her şey göz önüne alındığında, if( have_post() )tam döngüden önceki durumu single-*.phpve page-*.phpşablon dosyaları bağlamındaki durumu kaldırmanın güvenli olduğunu düşünüyor musunuz?
Sunyatasattva

1
“Güvenli” nin gerçekten bu bağlamda kesin bir anlamı yoktur.
Chip Bennett,

10

Chip'in cevabını geliştirmek gerçekten imkansız, ama sadece kovalamacayı kesmek:

Herhangi bir yazıif olmadığında farklı bir şey göstermek istiyorsanız bu kısmı kullanın . Bu, özellikle bir tarih veya kategori arşiv sayfasında faydalıdır. Birisi gönderileri olmayan bir sayfaya giderse, döngü hiçbir zaman gerçekleşmeyeceğinden, hiçbir şekilde görünmeyen bir mesajdan ibaret bir mesaja sahip olmak güzeldir.

if ( have_posts() ):
  // Yep, we have posts, so let's loop through them.
  while ( have_posts() ) : the_post();
  // do your loop
  endwhile;
else :
  // No, we don't have any posts, so maybe we display a nice message
  echo "<p class='no-posts'>" . __( "Sorry, there are no posts at this time." ) . "</p>";
endif;

Ve bunların hepsi bilmek istiyor.
Herbert Van-Vliet

0

Şimdiye kadar cevaplarda yer almayan bazı hususlar olabilir. İf ifadesini çıkarmanız önerilmez.

İf ifadesi yaygın olarak kullanılır:

  • no posts foundSöz konusu kategorinin kendisine atanmış bir makalesi olmadığını belirtecek bir şey çıktılar .
  • Çevreleyen html'nin (ul gibi) makalelerden önce ve sonra çıkıp çıkmayacağına karar vermek.

Ya yeni bir kanca eklenirse?

İf ifadesini kullanmamanın olası bir diğer sorunu, eğer wordpress ekibi ilk $wp_query->have_posts()çağrıyı tetikleyen yeni bir kanca eklemeye karar verdiyse , yanlış zamanda tetikleyecektir. Ve bu beklenmeyen bir davranışa neden olursa, spesifikasyona uygun şekilde uymamak sizin suçunuz olacaktır.

Diğer geliştiriciler wordpress döngüsü için belirli bir yapı görmeyi beklemektedir.

Sanırım diğer geliştiriciler wordpress döngüsünün tamamını görmeyi bekliyor. Belki de orada olmayan bir if ifadesini aramalarını sağlamak kötü bir fikirdir.


-1

Bunu kontrol yapısı teorisinin temel bir sorusu olarak görüyorum. While döngüsü içindeki kapalı blok, koşul (have_posts ()) ilk kez false olarak değerlendirilirse bir kez bile çalışmaz.

Bu nedenle, if ( have_posts() )WordPress döngüsünün amacı , while koşulu değerlendirilmeden önce have_posts () işlevini yalnızca bir kez çalıştırmaktır. Eğer have_posts()hiçbir yan etkisi vardır, o zaman if ( have_posts() )tamamen anlamsızdır. Eğer have_posts()yan etkileri var mı aşağıdaki gibi basitleştirmek olabilir:

<?php have_posts(); ?>
<?php while ( have_posts() ) : the_post(); ?>
<?php endwhile; else: ?>
<p><?php _e('Sorry, no posts matched your criteria.'); ?></p>
<?php endif; ?>

3
Bu sadeleştirme geçersiz PHP, if ifadesi ekli olmayan başka bir ifadeniz var. En iyi ihtimalle okumak zor
Tom J Nowell

1
ifÇünkü orada elseondan sonra. Başka sebep yok. Mesaj yoksa, hoş bir "mesaj yok" mesajı görüntülemek hiçbir şey göstermekten daha iyidir.
Otto,
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.