Customizer中的Widget可以“单机使用”(即在添加1个实例后禁用)吗?

时间:2017-11-28 作者:glueckpress

我每晚都在寻求建立一个custom single-use widget.

将其一个实例添加到侧栏面板后in the Customizer, 它在可用窗口小部件面板上的控件应为displayed as disabled (或者完全消失)。

这就是它的外观(请注意右侧的视觉“禁用”小部件):

…

自定义小部件已注册,但我仍停留在一次性使用的要求上。

规格Scale is not a problem. 可以假设只有1个已注册的侧栏。方法可以是将小部件的使用限制为每个侧栏1个,或每个注册的侧栏1个,目前这两个都可以
  • The Widgets page on the back-end is not a problem. 这并不需要在后端的外观下的小部件页面上同样有效。它只需在自定义程序中工作Would any kind soul help my very limited Customizer/JavaScript knowledge with a basic approach on how to add/remove a dedicated CSS class to the widget control in the “available” panel (the one on the right) once an instance of said widget has been added/removed to the sidebar panel?this, 和this, 但两者似乎都不切实际widget-added, widget-updated, 和widget-synced, 但错过了“小部件已删除”的事件

    更新:我还没有把概念证明放在公开回购上,当然可以

    解决方案

    我将下面kraftner善意分享的解决方案包装在proof of concept plugin on GitHub.

  • 1 个回复
    最合适的回答,由SO网友:kraftner 整理而成

    方法

    所以我已经研究过了,我的方法是:

    启动自定义程序时,检查所有侧栏,并在发现小部件的任何用法后立即禁用它,每当侧栏发生更改时,请再次执行此操作

    这是我第一次尝试使用定制器的JS API。因此,我可能在这里做一些效率低下的事情,但嘿,这很有效;)

  • 只关心定制程序(如问题中所述)
  • 不进行任何类型的服务器端验证。它只是隐藏UI,因此如果您担心有人绕过UI,这是不完整/不安全的

      代码现在我们已经完成了免责声明,让我们看看代码:

      (function() {
          wp.customize.bind( \'ready\', function() {
      
              var api = wp.customize,
                  widgetId = \'foo_widget\',
                  widget = wp.customize.Widgets.availableWidgets.findWhere( { id_base: widgetId } );
      
              /**
               * Counts how often a widget is used based on an array of Widget IDs.
               *
               * @param widgetIds
               * @returns {number}
               */
              var countWidgetUses = function( widgetIds ){
      
                  var widgetUsedCount = 0;
      
                  widgetIds.forEach(function(id){
      
                      if( id.indexOf( widgetId ) == 0 ){
                          widgetUsedCount++;
                      }
      
                  });
      
                  return widgetUsedCount;
      
              };
      
              var isSidebar = function( setting ) {
                  return (
                      0 === setting.id.indexOf( \'sidebars_widgets[\' )
                      &&
                      setting.id !== \'sidebars_widgets[wp_inactive_widgets]\'
                  );
              };
      
              var updateState = function(){
      
                  //Enable by default...
                  widget.set(\'is_disabled\', false );
      
                  api.each( function( setting ) {
                      if ( isSidebar( setting ) ) {
                          //...and disable as soon as we encounter any usage of the widget.
                          if( countWidgetUses( setting.get() ) > 0 ) widget.set(\'is_disabled\', true );
                      }
                  } );
      
              };
      
              /**
               * Listen to changes to any sidebar.
               */
              api.each( function( setting ) {
                  if ( isSidebar( setting ) ) {
                      setting.bind( updateState );
                  }
              } );
      
              updateState();
      
          });
      })( jQuery );
      
      旁注:使用customize_controls_enqueue_scripts 添加脚本的操作。

      您可以扩展它,将其限制为每个边栏基础,而不是全局基础。我要说的是,听一下侧边栏的激活,然后数一数侧边栏中的小部件。但我也没有时间去调查。

  • 结束

    相关推荐

    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