Cara terbaik untuk mendeteksi jika Anda berada di halaman SINGLE POST

9

Jadi ini mungkin tampak seperti hal yang cukup kasar, tetapi ikuti saya di sini.

Saya mencoba menambahkan beberapa logika melalui pre_get_poststindakan. Ini adalah seluruh objek WP_Query yang diberikan kepada saya. (lihat bagian akhir)

Hal-hal yang saya pertimbangkan untuk digunakan:

  • is_single() - terlalu luas.
  • is_singular()- terlalu dini untuk menggunakan ini, karena get_queried_object()belum diatur.
  • $query->single properti - lagi terlalu luas.
  • $query->get('post_type')- tidak disetel, karena menggunakan nameproperti.

adalah namebenar-benar satu-satunya indikator di sini?

WP_Query Object
(
    [query] => Array
        (
            [page] => 
            [name] => abcs-of-mental-health
        )

    [query_vars] => Array
        (
            [page] => 
            [name] => abcs-of-mental-health
            [error] => 
            [m] => 0
            [p] => 0
            [post_parent] => 
            [subpost] => 
            [subpost_id] => 
            [attachment] => 
            [attachment_id] => 0
            [static] => 
            [pagename] => 
            [page_id] => 0
            [second] => 
            [minute] => 
            [hour] => 
            [day] => 0
            [monthnum] => 0
            [year] => 0
            [w] => 0
            [category_name] => 
            [tag] => 
            [cat] => 
            [tag_id] => 
            [author_name] => 
            [feed] => 
            [tb] => 
            [paged] => 0
            [comments_popup] => 
            [meta_key] => 
            [meta_value] => 
            [preview] => 
            [s] => 
            [sentence] => 
            [fields] => 
            [menu_order] => 
            [category__in] => Array
                (
                )

            [category__not_in] => Array
                (
                )

            [category__and] => Array
                (
                )

            [post__in] => Array
                (
                )

            [post__not_in] => Array
                (
                )

            [tag__in] => Array
                (
                )

            [tag__not_in] => Array
                (
                )

            [tag__and] => Array
                (
                )

            [tag_slug__in] => Array
                (
                )

            [tag_slug__and] => Array
                (
                )

            [post_parent__in] => Array
                (
                )

            [post_parent__not_in] => Array
                (
                )

        )

    [tax_query] => 
    [meta_query] => 
    [queried_object] => 
    [queried_object_id] => 0
    [post_count] => 0
    [current_post] => -1
    [in_the_loop] => 
    [comment_count] => 0
    [current_comment] => -1
    [found_posts] => 0
    [max_num_pages] => 0
    [max_num_comment_pages] => 0
    [is_single] => 1
    [is_preview] => 
    [is_page] => 
    [is_archive] => 
    [is_date] => 
    [is_year] => 
    [is_month] => 
    [is_day] => 
    [is_time] => 
    [is_author] => 
    [is_category] => 
    [is_tag] => 
    [is_tax] => 
    [is_search] => 
    [is_feed] => 
    [is_comment_feed] => 
    [is_trackback] => 
    [is_home] => 
    [is_404] => 
    [is_comments_popup] => 
    [is_paged] => 
    [is_admin] => 
    [is_attachment] => 
    [is_singular] => 1
    [is_robots] => 
    [is_posts_page] => 
    [is_post_type_archive] => 
    [query_vars_hash] => f473ebf7f725c2627dc5fd9a1429f626
    [query_vars_changed] => 
    [thumbnails_cached] => 
)
Eric Holmes
sumber

Jawaban:

10

Saya sudah mencoba untuk menyelesaikan masalah ini sebelumnya untuk tujuan saya sendiri. Sejauh yang saya tahu ...

  • post_typetidak benar-benar diatur di mana pun untuk postjenis posting.
  • Untuk pagejenis posting saya hanya melihat kunci jenis posting queried_object.
  • Untuk jenis CPT ada post_typekunci masuk query_varsdan juga masuk query.
  • Menu Nav tampaknya berperilaku seperti CPT lain dalam hal ini.

Data sangat tidak konsisten tetapi jika Anda menghilangkan halaman dan CPT saya percaya Anda dapat menganggap postjenisnya.

Edit: Kode yang berfungsi dari @EricHolmes:

add_action( 'pre_get_posts', 'something_for_single_posts_only' ) ; 
function something_for_single_posts_only( $query ) { 
  if( $query->is_main_query() 
    && $query->is_singular() 
    && ! $query->get( 'post_type' ) 
    && ! $query->is_page() 
    && ! $query->is_attachment() 
  ) { 
      // do something for single posts only. 
  } 
} 

Kami memeriksa is_singular, tidak ada jenis posting (CPT ada post_typedi query_vars), bukan halaman atau lampiran.

s_ha_dum
sumber
Dan itu berfungsi di dalam pre_get_posts(sebelum menjalankan query)?
gmazzap
Saya ingin tahu apakah is_page()sudah diatur di pre_get_postslevel. Jika ya, dan saya bisa mengecek apakah post_typetidak diset di query_vars, saya kira itu sama baiknya dengan yang didapat? Sangat rusak.
Eric Holmes
1
is_pagetampaknya diatur.
s_ha_dum
@s_ha_dum Saya menghapus komentar karena sepertinya tidak berfungsi untuk CPT ...
gmazzap
2
Menambahkan solusi yang berfungsi ke jawaban Anda.
Eric Holmes
0

Saya tidak tahu apakah ini akan berguna:

function hwl_home_pagesize( $query ) {
    global $wp_query;
    if (is_main_query() && count($wp_query->posts) < 2) {

    }

}
add_action( 'pre_get_posts', 'hwl_home_pagesize', 1 );

Gunakan $ wp_query-> posts (array) untuk memeriksa jenis posting.

ferenyl
sumber
Belum. Pra mendapatkan posting terjadi sebelum $wp_query->postsvariabel benar-benar diisi. Terimakasih Meskipun!
Eric Holmes
0

Setelah beberapa tes saya melihat bahwa sayangnya tidak mungkin untuk mendapatkan posting tipe cpt di dalam pre_get_postshook. Hanya is_pageberfungsi tetapi tidak tipe pos standar atau cpt dapat diambil di sana.

Jika Anda hanya memiliki halaman dan posting (tanpa cpt) tanda centang is_single()dengan truesebagai respons berarti bahwa jenis posting adalah posting, karena itu mengembalikan false untuk halaman.

Jika Anda juga memiliki CPT, saya khawatir Anda harus melakukan kueri tambahan . Yang paling sederhana yang bisa saya pikirkan adalah hanya mendapatkan post_typekolom tempat status posting dipublikasikan dan post_name adalah yang diperlukan (melewatkan revisi):

function test( $q ) {
  if ( is_single() ) {
    global $wpdb;
    $type = $wpdb->get_var( $wpdb->prepare(
      "SELECT post_type FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' AND post_type <> 'revision'",
      $q->query['name']
    ) );
    var_dump($type);
  }
}
add_action( 'pre_get_posts', 'test', 1); 

Jika Anda ingin memeriksa jenis posting tertentu, Anda dapat menulis tag bersyarat kustom yang hanya menghitung baris dengan post_type yang diberikan dan nama yang diberikan:

function is_single_post_type( $type = 'post' ) {
  if ( is_single() ) {
    global $wpdb, $wp_query;
    $is = $wpdb->get_var( $wpdb->prepare(
      "SELECT count(ID) FROM $wpdb->posts WHERE post_name = %s AND post_status = 'publish' AND post_type = %s",
      $wp_query->query['name'], $type
    ) );
    return $is > 0;
  }
  return false;
}

Tentu saja ini diperlukan pre_get_post, dalam kaitan apa pun nanti yang dapat Anda gunakan get_post_type()...

gmazzap
sumber
1
Ini pasti akan berhasil, tetapi lihat pada jawaban yang diterima, itu adalah persyaratan yang jauh lebih rumit, tanpa permintaan tambahan ke database. :)
Eric Holmes
Iya. Saya mengerti bahwa Anda ingin tahu persis jenis posting yang Anda tampilkan. Tidak hanya jika Anda berada dalam satu tampilan posting tunggal. @EricHolmes
gmazzap
-1

Ini yang saya gunakan, meskipun khusus untuk struktur direktori saya sendiri.

/**
 * Function to list all templates used in a page
 * @author Imperative Ideas with thanks to Rarst
 * @uri http://wordpress.stackexchange.com/a/89005
 */

function thelist() {
    $included_files = get_included_files();
    $stylesheet_dir = str_replace( '\\', '/', get_stylesheet_directory() );
    $template_dir   = str_replace( '\\', '/', get_template_directory() );
    echo '<h3 class="debugtitle">Theme file templates used in this page</h3>';
    foreach ( $included_files as $key => $path ) {

        $path   = str_replace( '\\', '/', $path );

        if ( false === strpos( $path, $stylesheet_dir ) && false === strpos( $path, $template_dir ) )
            unset( $included_files[$key] );

        if(!strpos($path, '/wp-content/themes/') === false) { // Files IN this directory
            if(strpos($path, '/library/') === false) { // Ignore this subdir
                if(strpos($path, '/hybrid-core/') === false) { // Ignore this subdir
                    echo $key." = ". $path."</br>"; // Finally, output the list
                }
            }
        }
    }
}

Jarak tempuh dapat bervariasi. Bit-bit tegar tempat saya memeriksa apakah file ada dalam satu direktori tetapi tidak yang lain perlu dimodifikasi untuk versi Anda dan mungkin bisa difaktorkan ulang dengan lebih efisien. Mereka ada untuk memotong hasil di atas dan di bawah struktur direktori tertentu.

Menjalankan daftar () di footer akan memberi Anda daftar nomor dari setiap file template .php yang digunakan untuk mengkompilasi tampilan saat ini. Ini sangat berguna ketika berhadapan dengan tema anak yang memberikan komponen misteri.

Ide Imperatif
sumber
Tampak berlebihan. Ide yang keren?
Eric Holmes
Tidak ada banyak cara bagus untuk menentukan templat apa yang mendorong halaman, selain menguraikannya. Saya kira jika Anda mencari sesuatu yang sederhana seperti halaman vs tunggal, ya, itu berlebihan. Coba jalankan fungsi beberapa saat, minus syarat abaikan ekstra, dan Anda akan melihat mengapa saya menggunakan ini. Ada TON file yang digunakan untuk mengemudi halaman WP dan itu bisa sangat berguna untuk mengetahui apa itu semua. Bahkan ini tidak akan mengidentifikasi fungsi yang terhubung.
Ide Imperatif