在初始化窗口小部件区域之前访问WooCommerce产品类别

时间:2018-03-01 作者:Sillzen

我打算以编程方式为WooCommerce中的每个产品类别创建一个小部件区域。

我当前的functions.php:

function add_widget_areas() {
    $args = array(
        \'taxonomy\'   => \'product_cat\',
        \'hide_empty\' => false,
        \'parent\'     => 0,
    );
    $product_cats = get_terms( $args );

    foreach ( $product_cats as $product_cat ) {
        register_sidebar(
            array(
                \'name\'          => \'Filter sidebar -\' . $product_cat->name,
                \'id\'            => \'filter_sidebar_\' . $product_cat->name,
                \'before_widget\' => \'<div class="filter-sidebar-\' . $product_cat->name . \'">\',
                \'after_widget\'  => \'</div>\',
                \'before_title\'  => \'<h2 class="filter-title">\',
                \'after_title\'   => \'</h2>\',
            )
        );
    }
}
add_action( \'widgets_init\', \'add_widget_areas\' );
我的问题是,这会返回一个错误:Notice: Trying to get property of non-object in .../functions.php on line 752 (第752行:\'name\' => \'Filter sidebar -\' . $product_cat->name,), 大概是因为在WooCommerce初始化其产品类别之前,注册widget区域的操作就启动了。

如何在这么早的时候访问产品类别以使此循环正常工作?

2 个回复
最合适的回答,由SO网友:Jacob Peattie 整理而成

这个函数挂接在哪里?

widgets_init 连接到init 优先考虑1, 但WooCommerce在init 优先考虑5. 所以如果你使用widgets_init 作为你无法使用的钩子get_terms() 因为它返回WP_Error 如果分类法未注册。

您需要在上注册小部件init 优先级大于5 要使其工作,您仍应检查get_terms() 不是一个WP_Error, 如果WooCommerce未激活:

function wpse_295558_category_sidebars() {
    $product_cats = get_terms( array(
        \'taxonomy\'   => \'product_cat\',
        \'hide_empty\' => false,
        \'parent\'     => 0,
    );

    if ( ! is_wp_error( $product_cats ) ) {
        foreach ( $product_cats as $product_cat ) {
            register_sidebar( array(
                \'name\'          => \'Filter sidebar -\' . $product_cat->name,
                \'id\'            => \'filter_sidebar_\' . $product_cat->name,
                \'before_widget\' => \'<div class="filter-sidebar-\' . $product_cat->name . \'">\',
                \'after_widget\'  => \'</div>\',
                \'before_title\'  => \'<h2 class="filter-title">\',
                \'after_title\'   => \'</h2>\',
            ) );
        }
    }
}
add_action( \'init\', \'wpse_295558_category_sidebars\', 10 );
不过,这似乎是一种难以实现的方法。为类别设置一个侧栏,然后让小部件动态响应您正在查看的类别,不是更好吗?这已经是WooCommerce中捆绑过滤器小部件的工作方式。

SO网友:Mark Kaplun

通常,您不应假定在init 挂钩(最好等待wp_loaded).

小部件注册发生在wordpress初始化过程中,您的代码假设在此之前已经注册了分类法,这是一个非常糟糕的假设。

此外,小部件和边栏需要有一个“常量”标识符,因为它将被用作在DB中存储它们的键,因此使用用户可以轻松更改的东西,如类别名称,并不是一个好主意。

结束

相关推荐

Using add_filter() in Widgets

只需查询引用add_filter() 作用您可以在WordPress小部件类中使用此函数吗。Example我有一个带有动态创建代码的小部件,我想将其传递给插件中创建的另一个函数。这能实现吗?<?php /** * Display the actual Widget * * @param Array $args * @param Array $instance */ public function widget($args, $inst