Najlepszy sposób na wykrycie, czy znajdujesz się na stronie POJEDYNCZEGO POST

9

Może to wydawać się całkiem miłe, ale podążaj za mną tutaj.

Próbuję dodać logikę poprzez pre_get_postsakcję. To cały podany mi obiekt WP_Query. (patrz koniec)

Rzeczy, które rozważałem przy użyciu:

  • is_single() - zbyt szeroki.
  • is_singular()- zbyt wcześnie, aby z tego korzystać, ponieważ get_queried_object()nie zostało to jeszcze ustawione.
  • $query->single właściwość - znowu zbyt szeroka.
  • $query->get('post_type')- nieustawione, ponieważ używa namewłaściwości.

czy namenaprawdę jest to jedyny wskaźnik tutaj?

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
źródło

Odpowiedzi:

10

Próbowałem to wcześniej rozwiązać na własne potrzeby. O ile mogę powiedzieć ...

  • post_typenie jest tak naprawdę ustawiony nigdzie dla posttypu posta.
  • Dla pagetypu postu widzę tylko klucz typu post w queried_object.
  • Dla typów CPT istnieje post_typeklucz, query_varsa także w query.
  • Pod tym względem menu Nav wydają się zachowywać jak inne CPT.

Dane są bardzo niespójne, ale jeśli wyeliminujesz strony i CPT, uważam, że możesz przyjąć ten posttyp.

Edycja: Kod roboczy z @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. 
  } 
} 

Sprawdzimy dla is_singular, bez postu typu (CPT mają post_typew query_vars), a nie strony lub przywiązania.

s_ha_dum
źródło
I działa wewnątrz pre_get_posts(przed uruchomieniem zapytania)?
gmazzap
Zastanawiam się, czy is_page()jest ustawiony na pre_get_postspoziomie. Jeśli tak, i mogę sprawdzić, czy post_typenie jest ustawiony w query_vars, myślę, że to tak dobre, jak to możliwe? Tak zepsute.
Eric Holmes,
1
is_pagewydaje się być ustawiony.
s_ha_dum
@ s_ha_dum Usunąłem komentarz, ponieważ wydaje się, że nie działa dla CPT ...
gmazzap
2
Dodanie działającego rozwiązania do swojej odpowiedzi.
Eric Holmes,
0

Nie wiem, czy to się przyda:

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

Użyj $ wp_query-> posts (tablica), aby sprawdzić typ postu.

ferenyl
źródło
Jeszcze nie. Wcześniejsze posty pojawiają się, zanim $wp_query->postszmienna zostanie zapełniona. W każdym razie dzięki!
Eric Holmes,
0

Po kilku testach widzę, że niestety nie można uzyskać typu postu cpt wewnątrz pre_get_postshaka. is_pageMożna tam pobrać tylko działające, ale nie standardowy typ postu ani cpt.

Jeśli masz tylko stronę i post (nie CPT) sprawdza się is_single()z truejak środki reagowania, że typ jest po postu, ponieważ return false dla stron.

Jeśli masz także CPT, obawiam się, że musisz wykonać dodatkowe zapytanie . Najprostsze, co mogę wymyślić, to po prostu pobrać post_typekolumnę, w której publikowany jest status postu, a wymagana jest nazwa postu (pomijanie wersji):

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

Jeśli chcesz sprawdzić konkretny typ postu, możesz napisać niestandardowy tag warunkowy, który zlicza wiersze o określonym typie postu i nazwie:

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

Oczywiście jest to potrzebne pre_get_post, w dowolnym późniejszym haku można użyć get_post_type()...

gmazzap
źródło
1
To na pewno zadziałałoby, ale spójrz na przyjętą odpowiedź, jest to znacznie mniej skomplikowane warunkowe, bez dodatkowego zapytania do bazy danych. :)
Eric Holmes,
Tak. Rozumiem, że chciałeś dokładnie wiedzieć, jaki typ posta wyświetlasz. Nie tylko, jeśli jesteś w widoku jednego posta. @EricHolmes
gmazzap
-1

To jest to, czego używam, choć specjalizuje się w mojej strukturze katalogów.

/**
 * 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
                }
            }
        }
    }
}

Przebieg może się różnić. Bity strpos, w których sprawdzam, czy pliki znajdują się w jednym katalogu, ale nie w innym, będą musiały zostać zmodyfikowane dla twojej kompilacji i prawdopodobnie mogłyby być ponownie wydajniej przetworzone. Istnieją, aby wyciąć wyniki powyżej i poniżej określonej struktury katalogów.

Uruchomienie thelist () w stopce da numerowaną listę każdego pliku szablonu .php użytego do skompilowania bieżącego widoku. Jest to szczególnie przydatne, gdy mamy do czynienia z motywem potomnym, który wyświetla tajemniczy element.

Imperatywne pomysły
źródło
Wygląda na przesadną. Fajny pomysł?
Eric Holmes,
Nie ma wielu dobrych sposobów na określenie, które szablony napędzają stronę, poza ich analizą. Myślę, że jeśli szukasz czegoś tak prostego, jak pojedyncza kontra strona, tak, to przesada. Spróbuj jednak uruchomić tę funkcję jakiś czas, pomijając dodatkowe warunki warunkowe ignorowania, a zobaczysz, dlaczego tego używam. Istnieje mnóstwo plików, które prowadzą do strony WP i bardzo przydatne może być poznanie ich wszystkich. Nawet to nie zidentyfikuje funkcji przechwyconych.
Imperative Ideas