J'ai créé les pages et la hiérarchie suivantes:
Les pages Grand-parent ont un champ personnalisé ACF pour choisir la couleur.
J'aimerais que cette sélection de couleurs soit appliquée aux pages Grand-parent, Parent et Enfant.
Dans la boucle, j'ai écrit le code suivant pour saisir la sélection de couleurs des grands-parents:
<div class="<?= get_field('colour', $post->post_parent); ?>">
Disons que j'ai choisi la couleur "rouge".
Voici le résultat du front-end:
La couleur est uniquement appliquée aux pages grand-parent et parent. Les pages enfants ne renvoient aucune couleur (null).
Comment puis-je inclure les pages enfants aussi?
Autant que je sache, il n'y a pas de limite au nombre de niveaux d'ascendance que peuvent avoir les pages. Par conséquent, aucune solution ne doit dépendre d'un référencement spécifique à un ancêtre particulier. La meilleure solution serait d'obtenir une liste de tous les ancêtres de la page et de les parcourir jusqu'à ce que vous trouviez une valeur pour votre champ. Puis arrêtez de les parcourir et retournez la valeur trouvée. La fonction get_post_ancestors()
peut être utilisée pour cela:
$colour = null;
/**
* Get the IDs of the page's ancestors into a list.
*/
$page_ids = get_post_ancestors( $post );
/**
* Put the current page's ID at the beginning of the list so we don't have to
* handle it separately.
*/
array_unshift( $page_ids, $post->ID );
/**
* Loop over pages and find the first one with a colour.
*/
foreach ( $page_ids as $page_id ) {
$maybe_colour = get_post_meta( 'colour', $page_id, true );
/**
* If the page has a value for colour, put it in the colour variable and
* stop the loop.
*/
if ( $maybe_colour ) {
$colour = $maybe_colour;
break;
}
}
echo $colour;
Pour économiser de l'espace dans votre modèle, vous pouvez l'ajouter à une fonction et l'utiliser à la place:
function wpse_310439_get_the_colour( $post = 0 ) {
$post = get_post( $post );
$page_ids = get_post_ancestors( $post );
array_unshift( $page_ids, $post->ID );
$colour = null;
foreach ( $page_ids as $page_id ) {
$maybe_colour = get_post_meta( 'colour', $page_id, true );
if ( $maybe_colour ) {
$colour = $maybe_colour;
break;
}
}
return $colour;
}
Puis dans votre modèle:
<div class="<?php echo esc_attr( wpse_310439_get_the_colour() ); ?>">
Je ne sais pas trop comment vos pages de grands-parents obtiennent le style car votre code dit de saisir le champ du parent. Les parents des grands-parents doivent avoir la valeur 0, ce qui signifie qu'ils n'ont pas de parents. Il y a peut-être quelque chose qui me manque dans votre hiérarchie.
Un conditionnel devrait fonctionner ici:
(en supposant que vous ayez déjà spécifié global $post
dans votre modèle):
<div class="<?php
// if this is a top-level post, grab its field
if($post->post_parent == 0) { ?>
// output the field - no need to pass an ID as it is the ID of this post
the_field('colour');
// if this is not a top-level post (child, grandchild, or so forth)
} else {
// get all of this post's ancestors: parent, grandparent, and so forth
$ancestors = get_post_ancestors();
// get the last item in the array - the "top" parent (grandparent)
$id = end($ancestors);
// now pull its field
the_field('colour', $id);
} ?>
">
Un moyen non ACF d'obtenir le même effet serait d'ajouter vos classes souhaitées à la classe <body>
dans functions.php
:
<?php // add a filter to the body_class() function
add_filter('body_class', 'wpse_310439');
function wpse_310429($classes) {
// pull ancestors of the current page/post/cpt
$ancestors = get_post_ancestors();
// if this is a particular page ID, or a child of that ID
if(is_page('12345') || end($ancestors) == '12345') {
// add a class to the <body>
$classes[] = 'blue';
} elseif(is_page('54321') || end($ancestors == '54321') {
$classes[] = 'yellow';
}
// always return $classes so body gets regular classes
return $classes;
} ?>
De cette façon, vous définissez les classes dans les fichiers de thème et vous devez également utiliser la cascade pour cibler le div ayant besoin de la coloration (au lieu de .blue
, vous utiliseriez quelque chose comme body.blue div.styleme
), mais aucun plugin n'est nécessaire. :)