Support » Developing with WordPress » Enable/Disable Widget instance function

  • diplatis

    (@diplatis)


    Hi,
    I want to build two functions to enable and disable a specific widget instance. I have this but doesn’t work.

    function test_disable_widget_func() {
    	wp_unregister_sidebar_widget('text-58');
    }
    function test_enable_widget_func() {
    	//TBA
    }
Viewing 6 replies - 1 through 6 (of 6 total)
  • Moderator bcworkz

    (@bcworkz)

    You do not mention in what context your attempt is tried. Things need to occur in the right order. You cannot unregister something before it’s registered. While that is patently obvious, in practice it’s not so simple. Success depends on when the widget was registered in the loading process and when you try to unregister it. For example, unregistering in plugin code something that is registered by your theme will not work because plugin code runs before theme code.

    The solution is to hook an action that fires after the widget is registered, or if the widget itself was registered as an action callback, hook the same action with a larger priority argument so your callback runs after the register callback.

    diplatis

    (@diplatis)

    I want to deactivate a widget from the blog sidebar through a custom JSON API endpoint and reactivate it through another, something like that:

    add_action( 'rest_api_init', 'register_disable_widget_route' );
     
    function register_disable_widget_route() {
       register_rest_route( 'wp/v2', 'disablewidget', array(
           'methods'  => POST,
           'callback' => 'thes_disable_widget_func',
    	   'permission_callback' => function($request){
    			return is_user_logged_in();}
       ) );
    }
    
    function thes_disable_widget_func() {
    	wp_unregister_sidebar_widget('text-58');
      	return('OK');
    }
    Moderator bcworkz

    (@bcworkz)

    That cannot work. It may be hard to believe but all widget registrations are re-done for every single request. An API request is an independent request, so your code would have no effect on any other request. To do something like you want, you need to store a value somewhere that is persistent and check that value before doing anything else with widgets.

    For example, you API code could alter a certain option table value which contains an array of disabled widgets. Then hook “widgets_init” with a very large priority argument so your callback runs last. The callback gets that option value and unregisters any widget names in the returned array. Or better yet, check the option value before registering the widgets to begin with.

    As I’m not an coding expert, could you, please, elaborate on this?
    Thank you very much in advance.

    Moderator bcworkz

    (@bcworkz)

    The API callback to save the option:

    function thes_disable_widget_func() {
    	$return = update_option('thes_disabled_widgets', ['text-58', 'another_id',]) ?'OK':'Error. Could not update option';
      	return( json_encode( $return ));
    }

    Get the option and disable listed widgets:

    add_action('widget_init', 'thes_widget_disable_hook', PHP_INT_MAX );
    function thes_widget_disable_hook() {
      $disable = get_option('thes_disabled_widgets', ['']);
      foreach ( $disable as $widget_id ) {
        wp_unregister_sidebar_widget( $widget_id );
      }
    }

    Untested, from memory. The API callback needs more work so that you can add/remove values from the saved option array. Right now it just disables widgets without offering any control. It’s enough for a proof of concept test though.

    • This reply was modified 1 month, 4 weeks ago by bcworkz.

    I tried it, didn’t work.

Viewing 6 replies - 1 through 6 (of 6 total)
  • You must be logged in to reply to this topic.