当自定义小部件中的自定义设置更改时如何更新预览

时间:2017-10-06 作者:Danil Gholtsman

我决定覆盖其中的一个小部件,并决定为其添加一些自定义设置。

小部件的外观由JavaScript函数控制(我在那里使用slick slider,它应该可以通过小部件设置进行配置)

下面是widget类:(作为示例http://www.wpbeginner.com/wp-tutorials/how-to-create-a-custom-wordpress-widget/)

 <?php

// Creating the widget
class wpb_widget extends WP_Widget
{

    function __construct()
    {
        parent::__construct(
        // Base ID of your widget
        \'wpb_widget\',

        // Widget name will appear in UI
        __(\'WPBeginner Widget\', \'wpb_widget_domain\'),

        // Widget description
        array(
        \'description\' => __( \'Sample widget based on WPBeginner Tutorial\', \'wpb_widget_domain\' ),
        \'customize_selective_refresh\' => true,
        )
            );


             // Enqueue style if widget is active (appears in a sidebar) or if in Customizer preview.
        if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
            add_action( \'wp_enqueue_scripts\', array( $this, \'enqueue_scripts\' ) );
        }
    }

// Creating widget front-end

    public function widget($args, $instance)
    {
        $title = apply_filters( \'widget_title\', $instance[\'title\'] );

        // before and after widget arguments are defined by themes
        echo $args[\'before_widget\'];
        if (! empty( $title )) {
            echo $args[\'before_title\'] . $title . $args[\'after_title\'];
        }

        // This is where you run the code and display the output
        echo __( \'Hello, World!\', \'wpb_widget_domain\' );
        echo("<div id=\'customId\'>TEST</div>");
        echo $args[\'after_widget\'];

    }

// Widget Backend 
    public function form($instance)
    {
        if (isset( $instance[ \'title\' ] )) {
            $title = $instance[ \'title\' ];
        } else {
            $title = __( \'New title\', \'wpb_widget_domain\' );
        }
        // Widget admin form
        ?>
    <p>
        <label for="<?php echo $this->get_field_id( \'title\' ); ?>"><?php _e( \'Title:\' ); ?></label> 
        <input class="widefat" 
            id="<?php echo $this->get_field_id( \'title\' ); ?>" 
            name="<?php echo $this->get_field_name( \'title\' ); ?>" 
            type="text" value="<?php echo esc_attr( $title ); ?>" 
        />
    </p>
<?php

}

public function enqueue_scripts() {

    $randomParameter =  random_int(1, 100);

    $dataToBePassed = array(
        \'someParameter\' => $randomParameter
    );

    wp_enqueue_script(
        \'customjs\',
        get_template_directory_uri() . \'/js/customwidget.js\',
        array( \'jquery\',\'customize-preview\' ),
        \'\',
        true
    );

    wp_localize_script(\'customjs\', \'settings\', $dataToBePassed);
}


    // Updating widget replacing old instances with new
    public function update($new_instance, $old_instance)
    {
        $instance = array();
        $instance[\'title\'] = ( ! empty( $new_instance[\'title\'] ) ) ? strip_tags( $new_instance[\'title\'] ) : \'\';
        return $instance;
    }
} // Class wpb_widget ends here
以下是绑定js的示例:

(function ($) {
    console.log("custom widget js init");

    var configureCustomWidget = function(){
        var me = this,
            conf = settings || {someParameter:5};

        $(\'#customId\').html("<h1>"+conf.someParameter+"</h1>");
    }

    configureCustomWidget();

    // Short-circuit selective refresh events if not in customizer preview or pre-4.5.
    if (\'undefined\' === typeof wp || !wp.customize || !wp.customize.selectiveRefresh) {
        return;
    }

    // Re-load widgets when a partial is rendered.
    wp.customize.selectiveRefresh.bind(\'partial-content-rendered\', function (placement) {
        debugger;
    });

    // Refresh a moved partial containing 
    wp.customize.selectiveRefresh.bind(\'partial-content-moved\', function (placement) {
        debugger;
    });

})(jQuery);
在预览时,这一切都很好,但问题是,尽管我按照建议做了here 由于某种原因,当脚本初始化时,它无法运行wp.customize.selectiveRefresh 未定义。

就像这里:enter image description here

那么,我如何在设置更改时切换绑定的小部件JavaScript呢?

P、 S。

这只是一个简化的示例,将有一个额外的选项,我想更改,比如只更改名为“customId”的文本字段。在更改时,我希望它在HTML中进行更改,比如更改一些样式等。

UPD:

(story)

首先,我正在为WordPress网站创建主题。

这个主题应该包含一些小部件。

其中一个小部件应该从woocommerce 产品类别列表。但是默认的产品类别列表得到了输出,就像一个带有描述和照片的简单项目符号列表一样。

所以,为了让它更漂亮,我决定让它看起来像一个滑块。我决定为此使用一个小JavaScript库,名为Slick

问题是,它非常灵活,可以进行配置,例如:

$(\'.myCustomSlider\').slick({
  slidesToShow: 3,
  slidesToScroll: 1,
  autoplay: true
});
因此,我决定在我的小部件中添加一些选项,就像您在这里的JavaScript对象中看到的一样,所以Slides to show, Slides to scroll

我在想,在主题定制屏幕上,当用户更改这些选项值并可以看到这些更改是如何发生的时,这会很好。

(implementation)

为了不让这个问题变得太广泛-full code is here

因此,首先,在我的主题中,我覆盖了默认值product category widget,更改很简单-只需将自定义设置添加到已存在的中&;在挂钩处调用滑块脚本:

 public function __construct()
    {
        $extraSettings = array(
          \'slidesCount\'  => array(
              \'type\'  => \'number\',
              \'step\'  => 1,
              \'min\'   => 1,
              \'max\'   => \'\',
              \'std\'   => 3,
              \'label\' => __( \'Slides count per page\', \'woocommerce\' ),
          )
        );

        parent::__construct();

        $this->settings = array_merge($this->settings, $extraSettings);

         // To call script for the slider.
         if ( is_active_widget( false, false, $this->id_base ) || is_customize_preview() ) {
            add_action( \'wp_enqueue_scripts\', array( $this, \'enqueue_scripts\' ) );
        }
    }
此外,已更改<ul><div class="product-categories slider"> 就像那样

echo \'<div class="product-categories slider">\';

wp_list_categories( apply_filters( \'woocommerce_product_categories_widget_args\', $list_args ) );

echo \'</div>\';
我还重写了小部件的默认walker(但只是在输出方面做了更改html 东西)比如<li><div class=\'slide\'>

然后是我的自定义JavaScript,其中绑定到前面提到的事件here.

它在加载时工作。但是,当我改变一些东西时,那里没有任何反应。原因和我上面描述的一样-wp.customize.selectiveRefresh 未定义。

但主要的问题是-在我的自定义/覆盖的小部件设置更新后,如何更新客户端部件?

希望它能把一些事情说清楚:)

1 个回复
SO网友:Mark Kaplun

作为拇指的角色,您不应该扩展您不控制的小部件,除非它们的作者明确给出了如何进行扩展的指导。PHP方面的扩展稍微容易一些,但如果没有提前准备好工具,就很难用JS扩展UI。

一种更安全的方法(至少从易于开发的角度来看)是“分叉”小部件代码。获取代码,对其进行任何需要的修改,并给小部件起一个新名称,或者根据您的需要,您可以覆盖“官方”名称(注销原始名称,并在同一句柄下注册您的名称)。

这意味着,对于每一个新版本的WC,您都需要确保不需要更新代码来反映“原始”小部件中的更改,但很可能您需要这样做,即使您只是“扩展”。

结束

相关推荐

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