📜  不能在 init 挂钩上使用 is_home 查询 (1)

📅  最后修改于: 2023-12-03 15:35:55.401000             🧑  作者: Mango

不能在 init 挂钩上使用 is_home 查询

在WordPress主题开发中,我们经常需要在初始化阶段(init hook)执行一些操作,例如注册自定义的post type、taxonomy、自定义路由等等。然而,在init挂钩中使用is_home查询将会给您带来一些麻烦,下面我们来详细了解这个问题。

问题背景

在WordPress主题开发中,我们有时需要判断当前页面是否为首页,以便在首页上显示不同的内容。这时,我们可以使用 WordPress 的 is_home 函数来判断:

if ( is_home() ) {
    // 显示首页特定的内容
} else {
    // 显示其他内容
}

然而,在初始化阶段中使用is_home函数会出现一些奇怪的问题。例如,如果您在初始化挂钩中注册了自定义的分类法(Custom Taxonomy),那么在分类页面中,is_home() 函数将返回 true,这显然不是我们想要的结果。

问题原因

WordPress在初始化阶段时,还没有确定当前页面的类型,因此 is_home() 函数也无法确定当前页面是否为首页。因此,在初始化阶段中使用 is_home() 函数总是返回默认值 false。

那么,为什么在分类页面中 is_home() 函数会返回 true 呢?这是因为在初始化阶段中注册自定义分类法时,WordPress会检查当前页面的URL是否与自定义分类法的URL匹配,如果匹配,则将当前页面视为首页。

解决方案

要解决这个问题,我们可以使用其他钩子(hook)来替代 init。比如,我们可以使用 template_redirect 钩子:

add_action( 'template_redirect', 'my_theme_template_redirect' );

function my_theme_template_redirect() {
    if ( is_home() ) {
        // 显示首页特定的内容
    } else {
        // 显示其他内容
    }
}

或者,在您的主题中,您可以使用 pre_get_posts 钩子来修改主查询(main query),并将所有首页相关的逻辑都放在这个钩子中:

add_action( 'pre_get_posts', 'my_theme_pre_get_posts' );

function my_theme_pre_get_posts( $query ) {
    if ( $query->is_home() && $query->is_main_query() ) {
        // 显示首页特定的内容
    }
}

注意,使用 pre_get_posts 钩子时,我们必须通过 $query->is_main_query() 来确保当前查询是主查询。否则,我们的逻辑将会影响到所有查询。

总结

在 WordPress 主题开发中,我们需要避免在 init 挂钩上使用 is_home 查询。这样做会带来一些奇怪的问题,而且在某些情况下,会导致我们的主题出现意外的行为。我们可以使用其他钩子来替代 init,例如 template_redirectpre_get_posts。这样可以确保我们的逻辑在正确的时机执行,并且能够正确地识别当前页面的类型。