Obtenir un slug de type de publication personnalisé pour une page d'archive

14

Comment découvrir le slug de type de publication personnalisé lorsque je suis sur une page d'archive?

Par exemple, si /products/le archive-products.phpmodèle est déclenché , comment (de façon pragmatique) puis-je obtenir le slug de type de message?

Merci

Ben Everard
la source

Réponses:

18

Pour obtenir le type de publication actuel, utilisez get_post_type(). Demandez ensuite get_post_type_object()toutes les données dont vous avez besoin, par exemple le 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;
}
fuxia
la source
1
Je pense (n'avait pas testé) get_queried_object()obtiendrait les mêmes informations en moins de mouvements.
Rarst
@Rarst Peut-être, mais je pense que le code que j'ai suggéré est plus facile à comprendre.
fuxia
1
Les solutions de Toscho sont erronées, car get_post_type renvoie le type de publication de la page actuelle et, lorsque vous êtes dans la page d'archive, cette fonction retourne toujours "page". Je cherche à résoudre le même problème: quand je suis dans la page d'archive de 'livres' (4 exemple), je veux ceci: 'livres'. Quand je le recevrai, je le posterai.
eMarine
1
Malheureusement, ce n'est pas aussi simple que cela, mais vous feriez mieux de simplement $posttype = get_query_var('post_type');... J'ai ajouté une alternative complète.
majick
Je ne pense pas que cette réponse couvre toute l'histoire. Vous devez vérifier les règles d'installation de réécriture car de nombreux filtres (comme la page de la boutique woocommerce) apportent des modifications. Utilisez plutôt le propre mécanisme de Worpdress , voir ma réponse quelque part ci-dessous.
Jonas Lundman
6

J'utilise cela en dehors de la boucle sur le modèle archive.php pour obtenir sur quelle archive de publication personnalisée je suis.

C'est un combo des méthodes recommandées par @toscho et @Rarst:

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

Mise à jour: @majick a souligné que cela ne fonctionne que si vous avez défini le slug de réécriture pour votre CPT. La réécriture du slug est facultative lors de l'enregistrement d'un CPT et par défaut à post_type s'il n'est pas défini.

Jerry
la source
quand j'ai essayé, j'ai euNotice: Undefined property: stdClass::$rewrite in ***\wp-content\themes\marks-remarks\archive.php on line 4
patrickzdb
cela ne fonctionnera que si le slug de réécriture est défini pour le CPT enregistré, car il est facultatif et par défaut le post_type
majick
Merci d'avoir attrapé ce @majick! J'ai mis à jour le message pour refléter vos informations.
Jerry
s'avère que c'était la pointe de l'iceberg ... consultez ma nouvelle réponse pour la partie sous-marine :-)
majick
3

Les réponses deviennent confuses. Et peut - être Im aussi bien , mais le titre question est:

Obtenir un slug de type de publication personnalisé pour une page d'archive

Si vous voulez dire la page de destination de l' archive de type de publication , et lorsque vous is_post_type_archive()revenez true, vous voulez que le slug réponde à l'archive d'affichage actuelle :

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

- FIN DE RÉPONSE À LA QUESTION -

Explication:

Vous ne pouvez pas compter sur la limace enregistrée . Wordpress ne l'est pas non plus. Par exemple, lorsque vous appelez get_post_type_archive_link()Wordpress, vous vérifiez les règles de réécriture actuelles pour votre installation .

Où que vous soyez, à l'intérieur ou à l'extérieur de la boucle, de l'archive actuelle ou d'un seul article, inversez le get_post_type_archive_link()mécanisme. (Permaliens activés.)

Considérations:

Comme mentionné ici, le (s) type (s) de message dans la requête en cours peut être un array. Vous pouvez aller plus loin avec vos intentions en filtrant le type de message que vous recherchez, par exemple:

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

ou

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

Un autre point de vue:

Exemple de Woocommerce, est enregistré avec un objet de type de publication «produits» mais utilise en réalité un nom de règle réécrit (boutique):

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

Mark, Im using $responding_name, parce que les objectifs peuvent varier. Il n'existe pas d'archive de publication, c'est juste une URL.

cavameta
la source
Cela a été très clair merci. Je cherchais cette solution. Si la question ne cherchait pas "uniquement le nom du type de message", il devrait s'agir d'une réponse woted up.
Jonas Lundman
1

Il convient de noter que s'il has_archiveest défini sur true lors de l'enregistrement du type de publication personnalisé, l'archive du type de publication /cptslug/sera réécrite en interne ?post_type=cptslug. Donc, cela signifierait également que le résultat is_post_type_archive()sera vrai.

Malheureusement, lorsque le slug de réécriture enregistré est différent du type de publication, vous n'obtenez pas réellement de manière fiable post_type. par exemple. si votre type de publication était myplugin_carset que votre slug de réécriture l'était carset que vous devez obtenir myplugin_carsalors même cela (pour éviter les erreurs si l'objet interrogé actuel n'est pas un type de publication personnalisé) échouera toujours:

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

Mais parce que is_post_type_archivec'est vrai, c'est plus fiable:

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

Mais attendez, il y a plus ... il s'avère qu'avec un peu de test ce n'est vraiment pas aussi simple non plus ... et si vous êtes sur une page d'archive de taxonomie avec plusieurs types de messages dans la taxonomie ..? Ou attribuer des balises de publication à un type de publication personnalisé autre que la publication? Ou êtes-vous sur une page d'archive d'auteur? Page d'archive de date? ... ou même avoir un complexe tax_queryou meta_querypourWP_Query ?

La seule réponse fiable (sans tester tous les cas d'archives possibles) est de boucler les messages réels dans la requête ... Voici la fonction complète que j'ai trouvée pour travailler à la fois sur les pages singulières et d'archivage, et vous permettant éventuellement de passer un objet de requête personnalisé (ou objet de publication / ID de publication pour les publications singulières):

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
}

Cela renverra de manière fiable (ai-je dit cela?) Un tableau de types de publication s'il y en a plusieurs, ou une chaîne avec le type de publication unique s'il n'y a qu'un seul type. Il vous suffit de:

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

Exemple d'utilisation (juste pour le plaisir):

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

Pour voir l'effet, changez le type de publication personnalisé dans le code en postet ajoutez un thumbtype-postattribut de classe à vos images miniatures de publication ...

majick
la source
0

Vous pouvez utiliser ce code:

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

utilisez $ posttype_slug var tout ce dont vous avez besoin

Guy Ytzhak
la source
il faut $queried_object->query_var['post_type'];que cela fonctionne ...
majick
Non. $ Queried_object-> query_var contient uniquement une chaîne de type post. ce n'est pas un objet ou un tableau. regardez cette image: prntscr.com/bd58e1
Guy Ytzhak
ok mais seulement si l'objet interrogé est définitivement un objet de type post personnalisé, vous obtiendrez un objet correspondant différent et donc une valeur vide pour les pages d'archives catégorie / taxe / tag / auteur par exemple. même parce que ?post_type=postje me vide. comparer avecget_query_var('post_type');
majick
0

Vous pouvez utiliser ce code et ce code fonctionne pour moi,

 $ t_slug = get_query_var ('term');
Navin Bhudiya
la source
-3
if( get_post_type( get_the_ID() ) == 'projects' )
{
  //enter code for this post type
}
sous-air
la source