Uzyskaj niestandardowy typ postu dla strony archiwum

15

Jak odkryć ślimak niestandardowego typu posta, gdy jestem na stronie archiwum?

Na przykład, jeśli /products/uruchamia archive-products.phpszablon, w jaki sposób (pragmatycznie) mogę uzyskać ślimak typu post?

Dzięki

Ben Everard
źródło

Odpowiedzi:

19

Aby uzyskać bieżący typ wiadomości, użyj get_post_type(). Następnie zapytaj get_post_type_object()o wszystkie potrzebne dane, na przykład ślimak:

$post_type = get_post_type();
if ( $post_type )
{
    $post_type_data = get_post_type_object( $post_type );
    $post_type_slug = $post_type_data->rewrite['slug'];
    echo $post_type_slug;
}
fuxia
źródło
1
Myślę, że (nie testowałem) get_queried_object()uzyskałbym te same informacje w mniejszej liczbie ruchów.
Rarst
@Rarst Może, ale myślę, że kod, który zasugerowałem, jest łatwiejszy do zrozumienia.
fuxia
1
Rozwiązania Toscho są błędne, ponieważ get_post_type zwraca typ postu bieżącej strony, a kiedy jesteś na stronie archiwum, funkcja ta zawsze zwraca „stronę”. Mam zamiar rozwiązać to samo: kiedy przejdę do strony archiwum „książek” (4 przykłady), chcę tego: „książek”. Kiedy go dostanę, opublikuję go.
eMarine,
1
niestety nie jest to takie proste, choć lepiej byłoby po prostu $posttype = get_query_var('post_type');... Dodałem kompleksową alternatywę.
majick
Nie sądzę, że to jest odpowiedź na całą historię. Powinieneś sprawdzić reguły przepisywania instalacji, ponieważ wiele filtrów (takich jak strona sklepu woocommerce) wprowadza zmiany. Zamiast tego użyj własnego mechanizmu Worpdress , zobacz moją odpowiedź gdzieś poniżej.
Jonas Lundman
6

Korzystam z tego poza pętlą w szablonie archive.php, aby dowiedzieć się, na którym niestandardowym archiwum post jestem.

Jest to zestaw metod zalecanych przez @toscho i @Rarst:

$post_type = get_queried_object();
echo $post_type->rewrite['slug'];

Aktualizacja: @majick zwrócił uwagę, że działa to tylko wtedy, gdy ustawiłeś ślimak przepisywania dla CPT. Rewrite slug jest opcjonalny podczas rejestracji CPT i domyślnie ustawiony na post_type, jeśli nie jest ustawiony.

Nocnik
źródło
kiedy tego spróbowałem, dostałemNotice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4
patrickzdb,
zadziała to tylko wtedy, gdy dla zarejestrowanego CPT ustawiono ślimak przepisywania, ponieważ jest on opcjonalny i domyślnie ustawiony na typ post_ty
2016 r.
Dzięki za złapanie tego @majick! Zaktualizowałem wpis, aby odzwierciedlić Twoje informacje.
Jerry
okazuje się, że to był wierzchołek góry lodowej ... sprawdź moją nową odpowiedź dla części podwodnej :-)
majick
3

Odpowiedzi stają się mylące. I może ja też, ale główne pytanie brzmi:

Get zwyczaj postu typu ślimak na stronie archiwum

Jeśli masz na myśli stronę docelową archiwum typu posta i po is_post_type_archive()powrocie true, chcesz ślimaka odpowiadającego na bieżące archiwum przeglądania:

/* returns /products/ */

$responding_name = str_replace(get_home_url(), '', get_post_type_archive_link(get_query_var('post_type')));

/* continue to get 'products' without slug slashes */
$responding_name = str_replace('/', '', $responding_name);

- KONIEC ODPOWIEDZI NA PYTANIE -

Wyjaśnienie:

Nie można polegać na zarejestrowanym ślimaku . Wordpress też nie jest. Na przykład podczas wywoływania get_post_type_archive_link()Wordpress sprawdza bieżące reguły przepisywania dla instalacji .

Gdziekolwiek jesteś, wewnątrz lub na zewnątrz pętli, prąd archiwum lub pojedyncze stanowisko, odwrócić ten get_post_type_archive_link()mechanizm. (Permalinki włączone.)

Uwagi:

Jak wspomniano tutaj, typami postów w bieżącym zapytaniu może być array. Możesz iść dalej z intencjami, odfiltrowując szukany typ postu, na przykład:

$post_type = get_query_var('post_type'); 
if(is_array($post_type)) $post_type = reset($post_type);

lub

if(isset($post_types[0])) $post_type = $post_types[0];

Inny punkt widzenia:

Przykład Woocommerce jest zarejestrowany w obiekcie typu „produkty”, ale w rzeczywistości używa przepisanej nazwy reguły (sklep):

/* returns shop */
$responding_name = str_replace('/', '', str_replace(get_home_url(), '', get_post_type_archive_link('product')));

Zaznacz, używam $responding_name, ponieważ cele mogą się różnić. Archiwum postów nie istnieje, to tylko adres URL.

cavameta
źródło
Dzięki temu było bardzo jasne, dziękuję. Szukałem tego rozwiązania. Jeśli pytanie nie dotyczyło „tylko nazwy typu posta”, powinna to być odpowiedź na pytanie.
Jonas Lundman
1

Należy zauważyć, że jeśli has_archivepodczas rejestrowania niestandardowego typu postu zostanie ustawiona wartość true, archiwum rodzaju postu /cptslug/zostanie wewnętrznie przepisane ?post_type=cptslug. Oznaczałoby to również, is_post_type_archive()że zwróci się prawda.

Niestety, gdy zarejestrowany ślimak przepisywania różni się od typu postu, tak naprawdę nie otrzymujesz niezawodnie post_type. na przykład. jeśli Twój typ postu był, myplugin_carsa Twój komunikat o przepisywaniu był, carsi musisz to zrobić, myplugin_carsnawet to (aby zapobiec błędom, jeśli bieżący obiekt, którego dotyczy zapytanie, nie jest niestandardowym typem postu) nadal zawiedzie:

$queryobject = get_queried_object();
if (has_property('rewrite',$queryobject)) {
    if (isset($queryobject->rewrite['slug'])) {
         $posttype = $queryobject->rewrite['slug'];
     }
 }

Ale ponieważ is_post_type_archiveto prawda, jest to bardziej niezawodne:

if (is_post_type_archive()) {
    $posttype = get_query_var('post_type');
    // which is basically the same as:
    // global $wp_query;
    // $posttype = $wp_query->query_vars['post_type'];
} 
else ($posttype = 'post';}

Ale poczekaj, jest więcej ... okazuje się, że przy niewielkich testach to naprawdę nie jest takie proste ... co jeśli jesteś na stronie archiwum taksonomii z wieloma typami postów w taksonomii ...? Lub przypisać tagi postów do niestandardowego typu postu innego niż post? A może są na stronie archiwum autora? Data archiwizacji strony? ... a nawet mieć kompleks tax_querylub meta_querydla WP_Query?

Jedyną wiarygodną odpowiedzią (bez testowania dla każdego możliwego przypadku archiwum) jest zapętlenie rzeczywistych postów w zapytaniu ... Oto pełna funkcja, którą wymyśliłem do pracy zarówno na stronach pojedynczych, jak i archiwalnych, i pozwala opcjonalnie przekazać niestandardowy obiekt zapytania (lub obiekt postu / identyfikator postu dla pojedynczych postów):

function get_current_post_types($object=null) {

    // if a numeric value passed, assume it is a post ID
    if ( ($object) && (is_numeric($object)) ) {$object = get_post($object);}
    // if an object is passed, assume to be a post object
    if ( ($object) && (is_object($object)) ) {return get_post_type($object);}

    // standard single post type checks
    if (is_404()) {return '';}
    // update: removed this check, handled by is_singular
    // if (is_single()) {return 'post';}
    if (is_page()) {return 'page';}
    if (is_attachment()) {return 'attachment';}
    if (is_singular()) {return get_post_type();}

    // if a custom query object was not passed, use $wp_query global
    if ( (!$object) || (!is_object($object)) ) {
        global $wp_query; $object = $wp_query;
    }
    if (!is_object($object)) {return '';} // should not fail

    // if the post_type query var has been explicitly set
    // (or implicitly set on the cpt via a has_archive redirect)
    // ie. this is true for is_post_type_archive at least
    // $vqueriedposttype = get_query_var('post_type'); // $wp_query only
    if (property_exists($object,'query_vars')) {
        $posttype = $object->query_vars['post_type'];
        if ($posttype) {return $posttype;}
    }

    // handle all other cases by looping posts in query object
    $posttypes = array();
    if (method_exists($object,'found_posts')) {
        if ($object->found_posts > 0) {
            $queriedposts = $object->posts;
            foreach ($queriedposts as $queriedpost) {
                $posttype = $queriedpost->post_type;
                if (!in_array($posttype,$posttypes)) {$posttypes[] = $posttype;}
            }
            if (count($posttypes == 1)) {return $posttypes[0];}
            else {return $posttypes;}
         }
     }
     return ''; // nothin to see here
}

To niezawodnie (czy to powiedziałem?) Zwróci tablicę typów postów, jeśli występuje więcej niż jeden, lub ciąg znaków z jednym typem postów, jeśli istnieje tylko jeden typ. Wszystko, co musisz zrobić, to:

$posttypes = get_current_post_types();
// or pass a post ID 
$posttypes = get_current_post_types($postid);
// or pass a post object
$posttypes = get_current_post_types($post);
// or pass a custom query - that has been run
$posttypes = get_current_post_types($query);

Przykład użycia (tylko dla zabawy):

add_filter('the_posts','myplugin_fading_thumbnails',10,2);
function myplugin_fading_thumbnails($posts,$query) {
    if (!is_archive()) {return $posts;}
    $cptslug = 'myplugin_slug'; $dosomethingcool = false;
    $posttypes = get_current_post_types($query);
    if ( (is_array($posttypes)) && (in_array($cptslug,$posttypes)) ) {$dosomethingcool = true;}
    elseif ($cptslug == $posttypes) {$dosomethingcool = true;}

    if ($dosomethingcool) {
        global $fadingthumbnails; $fadingthumbnails = $cptslug;
        if (!has_action('wp_footer','myplugin_cpt_script')) {
            add_action('wp_footer','myplugin_cpt_script');
        }
    }

    function myplugin_cpt_script() {
        global $fadingthumbnails;
        echo "<script>var thumbnailclass = 'img.thumbtype-".$fadingthumbnails."';
        function fadeoutthumbnails() {jQuery(thumbnailclass).fadeOut(3000,fadeinthumbnails);}
        function fadeinthumbnails() {jQuery(thumbnailclass).fadeIn(3000,fadeoutthumbnails);}
        jQuery(document).ready(function() {fadeoutthumbnails();});
        </script>";
    }

    return $posts;
 }

Aby zobaczyć efekt, zmień niestandardowy typ wpisu w kodzie na posti dodaj thumbtype-postatrybut klasy do swoich miniatur zdjęć ...

majick
źródło
0

Możesz użyć tego kodu:

$queried_object = get_queried_object();
$posttype_slug = $queried_object->query_var;
echo $posttype_slug;

użyj $ posttype_slug var cokolwiek potrzebujesz

Guy Ytzhak
źródło
to musi $queried_object->query_var['post_type'];zadziałać ...
majick
Nie. $ Queried_object-> query_var zawiera tylko ciąg znaków typu post. to nie jest obiekt ani tablica. spójrz na to zdjęcie: prntscr.com/bd58e1
Guy Ytzhak
ok, ale tylko jeśli zapytany obiekt jest zdecydowanie niestandardowym obiektem typu post, otrzymasz inny odpowiedni obiekt, a tym samym pustą wartość na przykład dla stron kategorii / tax / tag / autor. nawet ?post_type=postgdy się opróżnię. porównaj zget_query_var('post_type');
majick
0

Możesz użyć tego kodu, a ten kod działa dla mnie,

 $ t_slug = get_query_var ('term');
Navin Bhudiya
źródło
-3
if( get_post_type( get_the_ID() ) == 'projects' )
{
  //enter code for this post type
}
subair
źródło