定制程序中的窗口小部件是否可以“一次性使用”(即在添加1个实例后被禁用)?


8

我每天晚上都在寻求构建自定义的一次性小部件

一旦将其一个实例添加到“定制程序”的侧边栏面板,其在“可用小部件”面板上的控件应显示为禁用(或完全消失)。

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

…

自定义窗口小部件已注册并且全部注册,但我只能使用一次。

眼镜

  • 规模不是问题。可以假设只有1个注册的侧边栏。该方法可以是将小部件的使用限制为每个侧边栏1个或所有注册的侧边栏1个-两者现在都一样好。
  • 后端上的“窗口小部件”页面不是问题。不需要在后端“ 外观 ” 下的“ 小部件”页面上同样良好地工作。它只需要在定制程序中工作。

问题

  1. 大约250年前,所有小部件都曾经是“单次使用”的。有谁知道将这些时间带回去并使自定义窗口小部件通过窗口小部件API只能使用1次的合法方法吗?
  2. 如果不是这样(我在挖掘了相当数量的核心文件后就假定),我可能会采用基于CSS的方法(指针事件,伪元素覆盖等)。任何一种灵魂都可以通过一种基本方法来帮助我非常有限的Customizer / JavaScript知识,该基本方法是,一旦所述小部件的实例具有被添加/删除到侧边栏面板?

到目前为止我尝试过的

  • 挖掘大量核心文件。
  • 阅读thisthis,但是似乎都不可行。
  • 修补了jQuery事件widget-addedwidget-updatedwidget-synced,但错过了“小部件已删除”事件。

提前感谢吨!


更新:当然,还没有将我的概念证明放在公共回购中。

我将下面由kraftner共享的解决方案包装在GitHub上的概念证明插件中


您也可以使用经典的小部件API代替WP_Widget,例如:gist.github.com/westonruter/7141599
Weston Ruter

Answers:


5

方法

所以我研究了这个,我的方法是这样的:

  1. 启动定制程序时,请遍历所有侧边栏,并在发现有任何用法后立即禁用它
  2. 每当边栏更改时,请再次执行此操作。

免责声明

这具有以下限制:

  1. 这是我第一次涉足Customizer的JS API。所以我可能在这里做效率低下的事情,但是,嘿,它有用;)
  2. 只关心定制器(如问题所述)
  3. 不执行任何类型的服务器端验证。它只是隐藏用户界面,因此,如果您担心有人绕过用户界面,这是不完整/不安全的。
  4. 禁用小部件是全局的-在任何侧边栏中的任何使用都会全局禁用小部件。

编码

现在我们已经完成了Disclaimer,让我们看一下代码:

(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操作添加脚本。


您可能会扩展它以限制它在每个侧边栏基础而不是全局基础上工作。我会说听侧边栏的激活,然后计算该侧边栏中的小部件。但是我也没有时间去研究它。


太棒了!我不知所措,这就像一种魅力,可以彻底解决我的问题。不会期望一个完整的工作示例,非常感谢!
gumckpress

1
好的问题(清晰的解释,屏幕截图,努力的证明)应该得到完整的答案。留下此评论是对其他人如何获得正确答案的提示。;)
kraftner
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.