web-dev-qa-db-fra.com

Définir le modèle de page automatiquement basé sur le parent

Comme le titre l'indique, j'essaie de définir chaque nouvelle page sous X parent avec un modèle de page spécifique. Soit par une fonction/plugin/code

exemple: si je crée une page "fromage suisse", c'est-à-dire une enfant de la page "chesses", wp lui attribuera automatiquement le modèle de page "fromage".

5
alme1304

Du côté de l’administrateur, vous pouvez mettre à jour par programme les métadonnées de la page-post_type:

global $post;
if ( 
    'swiss_cheese' === $post->post_parent 
    AND is_admin()
)
    update_post_meta( $post->ID, '_wp_page_template', 'some_template.php' );

Du côté des visiteurs, vous pouvez simplement sauter dans la redirection de modèle:

function wpse63267_template_include( $template )
{
    global $post;

    if ( 'swiss_cheese' === $post->post_parent )
    {
        $new_template = locate_template( array( 'swiss-cheese-template.php' ) );
        if ( ! empty( $new_template ) ) {
            return $new_template ;
        }
    }
    return $template;
}
add_filter( 'template_include', 'wpse63267_template_include', 99 );
5
kaiser

j'ai combiné la solution de Kaiser avec une autre solution trouvée sur le net pour la rendre plus dynamique et sécurisée.

de plus, dans le codex wp, il est indiqué: Le chargement d'un modèle différent à l'aide d'un crochet d'action template_redirect n'est pas une bonne utilisation. Si vous incluez un autre modèle et que vous utilisez ensuite exit () (ou die ()), aucun hook supplémentaire template_redirect ne sera exécuté ...

Et j'ai fait cette dynamique comme l'enfer. vous pouvez dire: les enfants de la page X utilisent le template Z. mais si vous définissez un template pour un childr de la page X dans l'interface d'administration, utilisez celui-ci (pour exactement cet enfant).

Voici une solution (si l'enfant de la page X redirige vers ...)

function jnz_is_child( $pid ) {
    global $post;
    $ancestors = get_post_ancestors( $post->$pid );
    $root = count( $ancestors ) - 1;
    $parent = $ancestors[$root];
    if( is_page() && ( $post->post_parent === $pid || in_array( $pid, $ancestors ) ) ) {
        return true;
    } else {
        return false;
    }
};
function wpse140605_template_redirect( $template ) {
    if ( $template === locate_template('page.php') ) { // if template is not set in admin interface
        if ( jnz_is_child( 656 ) || jnz_is_child( 989 ) ) {
            $new_template = locate_template( array( 'page-whatever.php' ) ); // if template file exist
            if ( '' != $new_template ) {
                return $new_template ;
            }
        }
    }
    return $template;
};
add_filter( 'template_include', 'wpse140605_template_redirect', 99 );

Donc, fondamentalement, dans la première fonction jnz_is_child(), je vérifie si la page est un enfant de la page X (ou même un enfant d'un enfant de X ..) par ID de page.

Et dans la deuxième fonction wpse140605_template_redirect() je fais le remplacement (si la page parent === 656 ou === 989: utilisez le modèle page-whatever.php). Bien entendu, la deuxième fonction peut contenir plusieurs fermetures if / else if, plus cette fonction vérifie si le fichier de modèle existe. Parce que s'il n'existe pas, php va lancer une erreur.

Et la première fonction est également utilisable partout ailleurs dans le thème (comme is_page() etc.).

Voici une autre variante si enfant, où même l'élément actuel est sélectionné (une combinaison de is_page et is_child):

function jnz_is_child( $pid ) {
  global $post;
    $ancestors = get_post_ancestors( $post->$pid );
    if( is_page() && ( is_page( $pid ) || $post->post_parent === $pid || in_array( $pid, $ancestors ) ) ) {
      return true;
    } else {
      return false;
    }
};
0
honk31