Ottenere lo slug del custom post type per una pagina di archivio

7 ott 2012, 14:33:27
Visualizzazioni: 64.3K
Voti: 18

Come posso scoprire lo slug del custom post type quando mi trovo in una pagina di archivio?

Per esempio, se /products/ attiva il template archive-products.php, come posso ottenere (programmaticamente) lo slug del post type?

Grazie

0
Tutte le risposte alla domanda 7
5
24

Per ottenere il tipo di post corrente usa get_post_type(). Poi richiedi a get_post_type_object() tutti i dati di cui hai bisogno, ad esempio lo slug:

$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;
}
7 ott 2012 16:48:23
Commenti

Penso (non l'ho testato) che get_queried_object() potrebbe ottenere le stesse informazioni con meno passaggi.

Rarst Rarst
9 ott 2012 04:15:53

@Rarst Forse, ma credo che il codice che ho suggerito sia più semplice da comprendere.

fuxia fuxia
9 ott 2012 04:18:13

La soluzione di Toscho è sbagliata, perché get_post_type restituisce il tipo di post della pagina corrente e, quando sei in una pagina di archivio, questa funzione restituisce sempre "page". Sto cercando di risolvere lo stesso problema: quando sono nella pagina di archivio di 'books' (per esempio), voglio ottenere 'books'. Quando lo risolvo, lo posterò.

eMarine eMarine
25 giu 2013 12:58:43

purtroppo non è così semplice, anche se sarebbe meglio usare semplicemente $posttype = get_query_var('post_type'); ... ho aggiunto un'alternativa più completa.

majick majick
6 giu 2016 21:56:23

Non credo che questa risposta copra l'intera questione. Dovresti verificare le regole di rewrite installate, poiché molti filtri (come la pagina shop di WooCommerce) apportano modifiche. Usa il meccanismo integrato di WordPress invece, vedi la mia risposta più in basso.

Jonas Lundman Jonas Lundman
21 ott 2017 20:17:02
4

Sto utilizzando questo codice al di fuori del loop nel template archive.php per ottenere su quale archivio di custom post mi trovo.

È una combinazione dei metodi consigliati sia da @toscho che da @Rarst:

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

Aggiornamento: @majick ha fatto notare che questo funziona solo se hai impostato lo slug rewrite per il tuo CPT. Lo slug rewrite è opzionale quando si registra un CPT e di default usa il post_type se non impostato.

29 ott 2014 17:42:33
Commenti

quando ho provato questo ho ottenuto Notice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4

patrickzdb patrickzdb
20 ott 2015 16:37:15

questo funzionerà solo se lo slug di rewrite è impostato per il CPT registrato, poiché è opzionale e di default utilizza il post_type

majick majick
3 giu 2016 06:23:37

Grazie per averlo segnalato @majick! Ho aggiornato il post per includere la tua informazione.

Jerry Jerry
3 giu 2016 17:23:55

a quanto pare quella era solo la punta dell'iceberg... guarda la mia nuova risposta per la parte sommersa :-)

majick majick
6 giu 2016 21:53:49
2

Le risposte possono risultare confuse. E forse lo sono anch'io, ma la domanda principale è:

Ottenere lo slug di un custom post type per una pagina archivio

Se intendi la pagina archivio del post type, e quando is_post_type_archive() restituisce true, vuoi ottenere lo slug corrispondente all'archivio corrente che stai visualizzando:

/* restituisce /products/ */

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

/* procedi per ottenere 'products' senza gli slash */
$responding_name = str_replace('/', '', $responding_name);

-- FINE DELLA RISPOSTA ALLA DOMANDA --

Spiegazione:

Non puoi affidarti allo slug registrato. Nemmeno Wordpress lo fa. Ad esempio, quando chiami get_post_type_archive_link(), Wordpress controlla le regole di rewrite correnti per la tua installazione.

Dovunque tu sia, dentro o fuori dal loop, archivio corrente o singolo post, inverti il meccanismo di get_post_type_archive_link(). (Con i permalink abilitati.)

Considerazioni:

Come menzionato qui, il/i post type nella query corrente possono essere un array. Puoi andare oltre con le tue intenzioni filtrando il post type che cerchi, ad esempio:

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

oppure

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

Un altro punto di vista:

Esempio con Woocommerce, che registra il post type object come 'products' ma in realtà utilizza una regola di rewrite diversa (shop):

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

Mark, sto usando $responding_name, perché gli obiettivi possono variare. Un archivio post non esiste, è solo un URL.

21 ott 2017 21:32:49
Commenti

Questo ha reso tutto molto chiaro, grazie. Stavo cercando proprio questa soluzione. Se la domanda non avesse cercato "solo il nome del tipo di post", questa sarebbe stata la risposta più votata.

Jonas Lundman Jonas Lundman
21 ott 2017 21:36:51

Esatto! $post_type_link = get_post_type_archive_link( get_query_var( 'post_type' ) ); era proprio ciò di cui avevo bisogno.

squarecandy squarecandy
25 nov 2020 19:11:27
1

Puoi utilizzare questo codice e questo codice funziona per me,

$t_slug = get_query_var('term');
10 ago 2016 07:50:16
Commenti

Questo è meglio di get_post_type(), poiché restituirà il valore corretto anche quando l'archivio è vuoto

cameronjonesweb cameronjonesweb
29 mar 2021 08:11:48
0

Va notato che se has_archive è impostato su true durante la registrazione del Custom Post Type, l'archivio del post type /cptslug/ verrà riscritto internamente come ?post_type=cptslug. Ciò significa anche che is_post_type_archive() restituirà true.

Sfortunatamente, quando lo slug di rewrite registrato è diverso dal post type, non si ottiene in modo affidabile il post_type. Ad esempio, se il tuo post type fosse myplugin_cars e il tuo rewrite slug fosse cars, e hai bisogno di ottenere myplugin_cars, anche questo (per prevenire errori se l'oggetto corrente della query non è un custom post type) fallirà comunque:

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

Ma poiché is_post_type_archive è true, questo è più affidabile:

if (is_post_type_archive()) {
    $posttype = get_query_var('post_type');
    // che è sostanzialmente lo stesso di:
    // global $wp_query;
    // $posttype = $wp_query->query_vars['post_type'];
} 
else ($posttype = 'post';}

Ma aspetta, c'è di più... si scopre con un po' di testing che non è davvero così semplice... cosa succede se sei su una pagina di archivio tassonomico con più post type nella tassonomia..? O assegni tag a un custom post type diverso da post? O sei su una pagina di archivio autore? Archivio data? ...o hai anche una complessa tax_query o meta_query per WP_Query?

L'unica risposta affidabile (senza testare ogni possibile caso di archivio) è ciclare i post effettivi nella query... Ecco la funzione completa che ho creato per funzionare sia su pagine singole che di archivio, e che ti permette di passare opzionalmente un oggetto query personalizzato (o un oggetto post/ID post per post singoli):

function get_current_post_types($object=null) {

    // se viene passato un valore numerico, assumi che sia un ID post
    if ( ($object) && (is_numeric($object)) ) {$object = get_post($object);}
    // se viene passato un oggetto, assumi che sia un oggetto post
    if ( ($object) && (is_object($object)) ) {return get_post_type($object);}

    // controlli standard per post type singoli
    if (is_404()) {return '';}
    // update: rimosso questo controllo, gestito da is_singular
    // if (is_single()) {return 'post';}
    if (is_page()) {return 'page';}
    if (is_attachment()) {return 'attachment';}
    if (is_singular()) {return get_post_type();}

    // se non è stato passato un oggetto query personalizzato, usa il globale $wp_query
    if ( (!$object) || (!is_object($object)) ) {
        global $wp_query; $object = $wp_query;
    }
    if (!is_object($object)) {return '';} // non dovrebbe fallire

    // se la query var post_type è stata impostata esplicitamente
    // (o implicitamente sul cpt tramite un redirect has_archive)
    // cioè, questo è true almeno per is_post_type_archive
    // $vqueriedposttype = get_query_var('post_type'); // solo $wp_query
    if (property_exists($object,'query_vars')) {
        $posttype = $object->query_vars['post_type'];
        if ($posttype) {return $posttype;}
    }

    // gestisci tutti gli altri casi ciclando i post nell'oggetto query
    $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 ''; // nulla da vedere qui
}

Questo restituirà in modo affidabile (l'ho detto?) un array di post type se ce n'è più di uno, o una stringa con il singolo post type se ce n'è solo uno. Tutto ciò che devi fare è:

$posttypes = get_current_post_types();
// o passa un ID post
$posttypes = get_current_post_types($postid);
// o passa un oggetto post
$posttypes = get_current_post_types($post);
// o passa una query personalizzata - che è stata eseguita
$posttypes = get_current_post_types($query);

Esempio di Utilizzo (solo per divertimento):

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

Per vedere l'effetto, cambia il custom post type nel codice in post e aggiungi un attributo di classe thumbtype-post alle immagini miniatura dei tuoi post...

6 giu 2016 21:53:05
3

Puoi utilizzare questo codice:

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

Utilizza la variabile $posttype_slug come preferisci

3 giu 2016 17:42:57
Commenti

serve $queried_object->query_var['post_type']; per farlo funzionare...

majick majick
6 giu 2016 21:57:25

No. $queried_object->query_var contiene solo la stringa del post type. Non è un oggetto o un array. Guarda questa immagine: http://prntscr.com/bd58e1

Guy Ytzhak Guy Ytzhak
6 giu 2016 22:33:58

ok ma solo se l'oggetto interrogato è sicuramente un oggetto di custom post type, otterrai un oggetto diverso e quindi un valore vuoto per le pagine di archivio di categoria/tassonomia/tag/autore per esempio. Anche con ?post_type=post ottengo vuoto. Confronta con get_query_var('post_type');

majick majick
6 giu 2016 23:31:21
0
-4
if( get_post_type( get_the_ID() ) == 'projects' )
{
  //inserisci il codice per questo tipo di post
}
13 mar 2014 06:22:18