web-dev-qa-db-fra.com

Afficher la relation hiérarchique entre les types de publication personnalisés dans la liste d'administration

J'ai deux types de messages personnalisés: "demande" et "citation". L'indicateur "hierarchical" est défini sur true pour tous les deux.

Un cpt 'request' peut être le parent d'un ou plusieurs cpt 'quotes'.

Comme il s’agit de deux types de publication différents, l’administrateur de WordPress dispose de listes de présentation distinctes (par exemple, edit.php? Post_type = request) pour les deux.

Ce que je recherche, c’est un moyen de formater la vue d'ensemble de la demande de la même manière qu'une liste de pages hiérarchique est formatée, par exemple:

  • Demande 1
    • Citation 1
    • Citation 2
  • Demande 2
    • Citation 3
    • Citation 4

Je n'ai besoin de faire cela que du côté administrateur (car je n'utilise pas le front-end).

2
Marc

La façon dont WordPress fonctionne pour les types de publication hiérarchiques est que la publication de publication doit toujours être du même type.

Pour cette raison, dans les écrans d’administration, le type de message dans edit.php est plutôt codé en dur.

Cependant, ce que WordPress fait, c'est d'exécuter un WP_Query où l'argument 'post_type' est l'argument actuel.

Alors, que pouvez-vous faire?

Tout d’abord, si vous souhaitez fusionner les deux écrans d’administration cpt, vous pouvez masquer l’écran d’admin pour "devis". C'est très simple: lorsque vous enregistrez le type de publication, définissez simplement l'argument 'public' sur false:

$args = array(
   // all other args here
  'hierarchical' => TRUE
  'public' => FALSE
);
register_post_type( 'quote', $args );

Pour ce faire, l’écran d’administration de devis n’est pas affiché, vous n'avez donc que celui de "demande".

Ce que vous devez faire, c'est intercepter la requête et définir l'argument 'post_type' pour qu'il contienne à la fois 'request' et 'quote'.

Le problème, c'est que la variable globale 'post_type' sera définie sur ce tableau, mais WordPress s'attend à ce que 'post_type' soit une chaîne se terminant par des erreurs. Pour éviter cela, nous devrions trouver un crochet pour forcer le 'post_type' global à être la chaîne 'request'.

Après un rapide coup d’œil au fichier responsable de la sortie de la table des publications de l’administrateur: 'wp-admin/includes/class-wp-posts-list-table.php', j’ai trouvé qu’un bon crochet pour la portée pouvait être le crochet de filtre 'edit_posts_per_page'.

Donc le code:

add_action( 'pre_get_posts', function( $query ) {
  if ( is_admin() ) { // do nothing if not is admin
    $scr = get_current_screen();
    // if in the right admin screen
    if ( $scr->base === 'edit' && $scr->post_type === 'request' ) {
      // force query to get both 'request' and 'quote' cpt
      $query->set( 'post_type', array( 'request', 'quote' ) );
      // force global $post_type to be = 'request' if is an array 
      add_filter( 'edit_posts_per_page', function( $perpage ) {
        global $post_type;
        if ( is_array( $post_type ) && in_array( 'request', $post_type ) ) {
          $post_type = 'request';
        }
        return $perpage; // we don't want to affect $perpage value 
      } );
    }
  }
  return $query;
} );
1
gmazzap