J'ai un type de message personnalisé nommé 'advert' et une taxonomie personnalisée associée nommée 'advert_category', créée par un plugin tiers. Je lance dans un plugin une instruction if
qui doit définir (comme je l’attendais) une disposition de thème spécifique pour les annonces uniques (example.com/advert/a-single-advert.html) et pour les pages d’archive taxonomie personnalisées (example.com/ advert-category/services /), mais la deuxième condition is_tax( 'advert_category' )
ne fonctionne pas. Qu'est-ce qui ne va pas ici?
Mon code:
function my_advert_single_template( ) {
global $post;
global $wpgo_global_column_layout;
if ( $post->post_type == 'advert' || is_tax( 'advert_category' ) ) {
$wpgo_global_column_layout = "2-col-l";
}
}
add_filter( 'single_template', 'my_advert_single_template' );
Voici comment le type de publication personnalisé et la taxonomie personnalisée sont enregistrés:
// register post type and taxonomy in order to allow default data insertion.
register_post_type( 'advert' );
register_taxonomy( 'advert_category', 'advert' );
$hid = wp_insert_post(array(
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Adverts',
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_content' => "[adverts_list]"
));
$aid = wp_insert_post(array(
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Add',
'post_parent' => $hid,
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_content' => "[adverts_add]"
));
$mid = wp_insert_post(array(
'post_type' => 'page',
'post_status' => 'publish',
'post_title' => 'Manage',
'post_parent' => $hid,
'comment_status' => 'closed',
'ping_status' => 'closed',
'post_content' => "[adverts_manage]"
));
wp_insert_term(
'Default',
'advert_category'
);
Vous avez beaucoup de problèmes ici:
pre_get_posts
n'est pas le bon crochet pour définir des modèles. pre_get_posts
sont utilisés pour modifier les vars de requête de requête ain juste avant que les instructions SQL ne soient générées pour exécuter la requête principale
Un filtre devrait toujours retourner quelque chose. Si vous ne le faites pas, vous aurez un comportement inattendu, et en oublier cela peut vous mener à la poursuite de l'oie sauvage pendant des heures pour résoudre le problème.
L'utilisation de globals pour contrôler les fonctionnalités de thème ou pour stocker tout type de données est une mauvaise pratique et un codage pas très sûr. WordPress a déjà créé un tel fouillis de globaux, en particulier de conventions de nommage. Il suffit de vérifier comment les débutants (qui ne connaît pas Wordpress) utilisent sans le savoir des variables telles que $post
et $posts
en tant que variables locales. Ce sont des utilisations globales natives par WordPress, et leur utilisation en tant que variables locales annule les valeurs de ces propriétés globales.
À cause de cela, quelque chose sur la page ne va pas, il n'y a pas d'erreurs, vous êtes donc coincé dans une chasse à l'oie sauvage qui tente de déboguer quelque chose que vous avez cassé à votre insu. Les globales sont un pur mal et vous devriez éviter de les utiliser. Pensez simplement que si vous utilisez la variable $wpgo_global_column_layout
pour les arguments d'une requête personnalisée, vous casserez la valeur du modèle à définir, votre modèle ne se chargera pas car les valeurs de $wpgo_global_column_layout
ne sont pas reconnues comme un nom de modèle valide. , vous êtes bourré et vous ne savez pas pourquoi votre modèle ne se charge pas car votre code est chargé à 100% de charger un modèle personnalisé
is_tax()
est le mauvais chèque à utiliser pour vérifier si une publication a un certain terme ou non, is_tax()
vérifie simplement si vous êtes sur une archive de taxonomie ou non. Vous devriez utiliser has_term()
qui ne fait que cela, vérifie si un message a un terme donné
Si vous avez besoin de définir un modèle pour une page de taxonomie, single_template
correspond au mauvais crochet, utilisez plutôt le taxonomy_template
hook ou le plus générique template_include
filter.
Dans la ligne $post->post_type == 'advert' || is_tax( 'advert_category' )
, je suppose que vous utilisez le mauvais opérateur. Vous devriez utiliser l'opérateur AND
. Je ne vais pas expliquer cela ici car j'ai déjà fait quelque chose de similaire ici . Notez qu'avec la configuration actuelle, chaque fois que vous affichez une publication à partir de la publication advert
, votre condition retourne true et se déclenche que la seconde condition (is_tax( 'advert_category' )
) échoue ou non.
Si vous devez cibler un terme en fonction de l'ordre parent_child, il vous suffit de vérifier la propriété $parent
de l'objet du terme. Une valeur de 0
signifie que le terme est un parent, toute autre valeur signifie que le terme est un terme enfant/petit-enfant/petit-petit-enfant/etc
Laisse tomber les globals de merde et définir les modèles correctement. Je ne sais pas comment votre thème définit exactement les modèles via le $wpgo_global_column_layout
, mais ce qui suit devrait fonctionner en priorité. J'ai commenté le code pour le rendre facile à suivre
add_filter( 'single_template', function ( $template )
{
// Remove all filters from the current filter
remove_all_filters( current_filter(), PHP_INT_MAX );
/**
* Get the current single post object. We will use get_queried_object
* as it is safer to use as $post
*
* @see https://wordpress.stackexchange.com/q/167706/31545
*/
$current_post = get_queried_object();
// Check if the current post belongs to the advert post type, if not, bail
if ( $current_post->post_type !== 'advert' )
return $template;
// Get the post terms
$terms = get_the_terms(
$current_post, // Current post object
'advert_category' // Taxonomy name
);
// If $terms are empty or throws a WP_Error object, bail
if ( !$terms || is_wp_error( $terms ) )
return $template
/**
* Get the first term and check if it is a top level term or not.
* Load template according to parent value
*
* NOTE, this only work correctly if the post has one term only
*/
if ( $terms[0]->parent == 0 ) {
$part = 'single-parent.php'; // Set the template to use for parent terms
} else {
$part = 'single-child.php'; // Set the child term template
}
// Check if the template exists, if not bail
$locate_template = locate_template( $part );
if ( !$locate_template )
return $template;
// We have reached this point, set our custom template
return $template = $locate_template;
}, PHP_INT_MAX + 1 );
add_filter( 'taxonomy_template', function ( $template )
{
// Remove all filters from the current filter
remove_all_filters( current_filter(), PHP_INT_MAX );
// Get the current term object. We will use get_queried_object
$current_term = get_queried_object();
// If the current term does not belong to advert post type, bail
if ( $current_term->taxonomy !== 'advert_category' )
return $template;
// Check if the term is top level or not and set template accordingly
if ( $current_term->parent == 0 ) {
$part = 'taxonomy-parent.php'; // Set the template to use for parent terms
} else {
$part = 'taxonomy-child.php'; // Set the child term template
}
// Check if the template exists, if not bail
$locate_template = locate_template( $part );
if ( !$locate_template )
return $template;
// We have reached this point, set our custom template
return $template = $locate_template;
}, PHP_INT_MAX + 1 );
Juste une note, tout le code n’a pas été testé, alors assurez-vous de le tester localement d’abord avec debug défini sur true. Également modifier et abuser du code pour répondre à vos besoins
Vous avez deux problèmes dans votre fonction:
Regarde ça:
function my_advert_single_template( $single_template ) {
global $post;
global $wpgo_global_column_layout;
if ( $post->post_type == 'advert' || has_term( 'util-categorie', 'advert_category' ) ) {
$wpgo_global_column_layout = "2-col-l";
}
return $single_template;
}
add_filter( 'single_template', 'my_advert_single_template' );