web-dev-qa-db-fra.com

Existe-t-il un moyen de définir différents modèles de publication pour les publications parent et les publications enfants dans le même type de publication?

Après avoir jeté un coup d'œil aux questions suggérées pour éventuellement obtenir ma réponse, je n'arrive toujours pas à trouver quelque chose que je référence dans les fichiers php post-template.

Je tente de combiner deux types de publication personnalisés en un seul type. J'appellerai les types de messages personnalisés 'Client' et 'Projet'. Ce que j'ai fait est de créer un type de publication personnalisé "Clients et projets", puis de définir chacun des "clients" en tant que parent et les "projets" suivants en tant qu'enfants dans les "clients et projets".

J'ai déjà créé des modèles PHP, qui fonctionnent correctement pour chaque type de publication individuellement, mais je ne vois pas comment définir l'un des modèles à charger pour les "clients" (publications parent). ) et l’autre modèle à charger pour les "projets" (messages enfants).

La dénomination des fichiers est la suivante:

  • Les clients seraient clients_projects_parent.php
  • Les projets seraient clients_projects_child.php

J'ai trouvé cet extrait de code ici , mais cela n'a pas résolu mon problème.

function switch_page_template() {
    global $post;
    // Checks if current post type is a page, rather than a post
    if (is_page()){
        // Checks if page is parent, if yes, return
        if ($post->post_parent == 0)
            return true;
        else if ($post->post_parent != $post->ID){
            $parent_page_template = get_post_meta($post->post_parent,'_wp_page_template',true);
            $template = TEMPLATEPATH . "/{$parent_page_template}";
            if (file_exists($template)) {
                load_template($template);
                exit;
            }
        }
    }
}

add_action('template_redirect','switch_page_template');

Mon espoir ultime serait que chacune des publications Parent et Child charge respectivement un modèle PHP différent.

Mise à jour:

Je bricolais et essayais ceci:

add_action('template_redirect', 'get_template');

function get_template(){
    global $wp;
    global $wp_query;

    if(is_page('client_project') || '0' === $post->post_parent){
        include(TEMPLATEPATH . '/single-client_project.php');
    }elseif(is_page('client_project') || $post->post_parent > 0){
        include(TEMPLATEPATH . '/single-client_project_child.php');
    }
    else{
        include(TEMPLATEPATH . '/single-client_project.php');
    }
}

J'ai placé une instruction conditionnelle dans les modèles que j'essaie d'appeler/rediriger également:

global $post;

if ( is_page('client_project') || '0' == $post->post_parent ) {
    echo "<h1>This is a parent page</h1>";
    echo "<p>post parent = " . $post->post_parent . "</p>";

} else {
    echo "<h1>This is a child page</h1>";
    echo "<p>post parent = " . $post->post_parent . "</p>";
}

Maintenant, ce qui se passe, c’est que, lorsque les publications se chargent, chacune d’elles donne l’indication correcte de la boucle d’écho placée dans les fichiers de modèle, c.-à-d. la publication parent s'imprime 'Ceci est une page parent' et donne le numéro de publication correct pour le parent '0' , mais les modèles ne se chargent toujours pas correctement (ether le parent ou le template enfant ne charge pas chacun pour chaque type) ...

Je n'ai essayé cela qu'après apparemment toutes les autres méthodes m'ont échoué. Je suis sûr qu'il me manque quelque chose, mais je ne peux vraiment pas le comprendre.

MISE À JOUR FINALE:

J'ai finalement eu les modèles à échanger. Bien que ce soit dans ce que je peux seulement imaginer, c’est la pire des manières. En gros, je suis allé dans le modèle 'parent' et ai placé une instruction if juste avant le code de la page. Cela ressemble à ceci:

<?php 
    global $post;

    if(is_page('client_project') || $post->post_parent > 0){
        include(TEMPLATEPATH . '/single-client_project-child.php');
    }
?> 

Après avoir lu que cela fonctionnait, j’ai lu que TEMPLATEPATH était déprécié; je vais donc probablement échanger cela, mais je vais appeler cette réponse, @G. M., si vous le vouliez, j'apprécierais vraiment que vous écriviez la bonne façon de faire cela, ou du moins une meilleure façon. J'invite tous ceux qui rencontrent cette question à faire de même. Cheeers!

1
David Johnson

Le moyen le plus simple consiste à utiliser le crochet de filtre single_template (l'un des crochets {$type}_template ).

Il est déclenché par WordPress pour filtrer le fichier modèle trouvé pour les demandes de publication singulières.

add_filter('single_template', function($template) {

  $queried = get_queried_object();

  if ( $queried->post_type === 'clients_projects' ) { // only for this CPT
    // file name per OP requirements
    $file = 'clients_projects_';
    $file .= $queried->post_parent ? 'child' : 'parent';

    // using `locate_teplate` to be child theme friendly
    return locate_template("{$file}.php") ? : $template;
  }

  return $template;

});

Comment ça marche

Lorsque vous visitez une URL sur un site WordPress, WordPress traduit cette URL en un ensemble d'arguments de requête et déclenche une requête de base de données à l'aide de ceux-ci.

Il existe différents types de requêtes, pour une page, pour une archive, pour un article, etc. Consultez la page Etiquettes conditionnelles du Codex. Vous y trouverez une description exhaustive de tous les types de requête.

Dans votre cas, vous devez cibler un type de requête unique , car vous souhaitez modifier le modèle utilisé lorsqu'un seul CPT est requis.

Une fois qu'une requête est déclenchée, WordPress examine dans le dossier du thème un modèle à utiliser pour afficher les résultats de la requête. Examinez la hiérarchie des modèles pour comprendre quel fichier est utilisé pour chaque type de requête.

Lorsqu'un fichier est trouvé, avant d'inclure réellement ce fichier, WordPress le filtre en utilisant 2 filtres.

Dans le code ci-dessus, j’ai utilisé le filtre 'single_template' pour modifier le modèle que WordPress chargera, renvoyant un modèle différent d’un rappel associé à ce filtre.

Cependant, ce filtre est déclenché pour chaque requête unique, même pour les publications standard et autres CPT. Ainsi, avant de modifier le modèle, j'ai vérifié si la publication actuelle interrogée est l'une des publications du CPT que nous souhaitons cibler. . Pour obtenir le message actuel interrogé, j’ai utilisé [get_queried_object()][6] qui renvoie une requête singulière à l’objet message.

Si la publication en cours n'est pas de type publication cible, je renvoie simplement le fichier trouvé par WordPress, sans le modifier.

Si la publication en cours est un type de publication cible, je construis le nom du modèle en regardant l'attribut post_parent de la publication: si la publication a un parent, je construis 'clients_projects_child.php' si la publication n'a pas de parent Je retourne 'clients_projects_parent.php'.

Avant de renvoyer le fichier de modèle, j'utilise locate_template pour voir si, dans le thème (ou dans le thème enfant), ce fichier de modèle existe ou non. S'il existe, je le renvoie. Ainsi, au lieu de charger le modèle par défaut, WordPress charge le modèle personnalisé. Si le modèle n'existe pas, je renvoie le modèle par défaut, c'est celui que WordPress a trouvé.

1
gmazzap