我有一个名为“advert”的自定义帖子类型和一个名为“advert\\u category”的相关自定义分类法,由第三方插件创建。我在插件中运行if
语句,必须为单个广告(例如.com/advert/a-single-advert.html)和自定义分类归档页面(例如.com/advert-category/services/)设置特定的主题布局,但第二个条件是is_tax( \'advert_category\' )
不起作用。这里怎么了?
我的代码:
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\' );
这是自定义帖子类型和自定义分类的注册方式:
// 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\'
);
最合适的回答,由SO网友:Pieter Goosen 整理而成
这里有很多问题:
pre_get_posts
不是设置模板的正确挂钩。pre_get_posts
用于在生成SQL以运行主查询的查询之前更改ain查询变量过滤器应always 归还一些东西。不这样做会产生意想不到的行为,而忘记这一点会让你在数小时内对问题进行调试。
使用globals控制主题功能或存储任何类型的数据都是不好的做法,编码也不是很安全。WordPress已经把全局语言弄得一团糟,尤其是命名约定。只需检查新手(不知道Wordpress的)是如何在不知不觉中使用变量的,如$post
和$posts
作为局部变量。这些是WordPress使用的本地全局变量,使用它们作为局部变量会破坏这些全局变量的值。
因此,页面上出现了一些错误,没有任何错误,因此您陷入了一场白费力气的追逐,试图调试您在不知不觉中破坏的东西。Globals是纯粹的邪恶,你应该避免使用它们。想想看,如果你使用这个变量$wpgo_global_column_layout
对于自定义查询的查询参数,您将中断需要设置的模板的值,您的模板不会加载,因为$wpgo_global_column_layout
没有被识别为有效的模板名称,您被填充了,不知道为什么您的模板没有加载,因为您的代码应该100%加载自定义模板
is_tax()
是用来检查一个帖子是否有特定术语的错误检查,is_tax()
只需检查您是否在分类法存档中。您应该使用has_term()
就是这样,检查某个帖子是否有特定的术语如果需要为分类页面设置模板,single_template
如果是错误的钩子,你应该使用taxonomy_template
钩子或更通用的template_include
滤器
在线中$post->post_type == \'advert\' || is_tax( \'advert_category\' )
, 我怀疑你使用了错误的运算符。您应该使用AND
操作人员我不会在这里解释,因为我已经做了类似的事情here. 请注意,在当前设置下,无论何时从帖子类型查看帖子advert
, 您的条件将返回true并激发第二个条件(is_tax( \'advert_category\' )
)失败。
如果需要根据父子顺序确定术语的目标,只需检查术语对象的$parent
所有物值为0
表示该术语是父项,任何其他值表示该术语是子项/孙子项/孙子项/等
让我们放下糟糕的全局变量,正确设置模板。我不知道你的主题是如何通过
$wpgo_global_column_layout
, 但以下内容应优先考虑。我对代码进行了注释,使其易于理解
对于单页:
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 );
请注意,所有代码都未经测试,因此请确保先在本地测试,并将debug设置为true。还要修改和滥用代码以满足您的需要