Using Active Callback on a Control

An Active Callback allows us to show or hide a particular Control based on a Condition. 

For example, It is a good Idea to hide a Control when viewing a particular page where it is not relevant. When I said “page”, I am talking about a particular page that is being viewed on the Site Preview part of the Customize Panel.

The Site Preview section allows you to navigate around all the pages on the site when playing around with the Customize Panel settings. The navigation links inside the site preview work just fine like they do on the actual frontend.

Alright! This is better shown than explained.

Go back to the customize.php file and add the following active_callback argument to the “nd_dosth_readmore_text” Control’s configuration array.

'active_callback' => 'is_archive'

Here is the updated “nd_dosth_readmore_text” Control

// Control for Read More text
$wp_customize->add_control( 'nd_dosth_readmore_text', 
    array(
        'type'        => 'text',
        'priority'    => 10,
        'section'     => 'nd_dosth_text_options',
        'label'       => 'Read More text',
        'description' => 'Text put here will be as the text for Read More link in the archives',
        'active_callback' => 'is_archive'
    ) 
);

We have to use active_callback argument on a Control which we want to contextually show or hide and the active_callback argument accepts a function as a callback. When WordPress tries to render a Control, it will execute this callback function to determine whether to show the Control or not!

So, the callback function we have provided for the active_callback argument must return a boolean True or False. Nothing else. The idea is If the callback function returns True, WordPress will show the Control. Otherwise, it will hide it. 

We can provide any function that returns a boolean. Usually, we provide a WordPress conditional tag to determine whether we are viewing a particular WordPress page and then show the Control if it is relevant to that particular page.

Remember the following conditional tags?

  • is_page()
  • is_archive()
  • is_front_page()

All the Conditional Tags works just fine with the active_callback argument.

But we shouldn’t put function call brackets “()” at the end. We are not executing these functions right away. We are providing these conditional tags as a callback function.

So, coming back to the above code, When WordPress renders the “nd_dosth_readmore_text” Control in the “Text Options” Section, WordPress will execute the is_archive() function and the is_archive() function returns True only if we are viewing an archive page. 

That means if we are viewing the “Text Options” Section with the Homepage in the Site Preview, the “Read More Text” Control will be hidden.

But, if we are viewing the “Text Options” Section with an Archive page, the “Read More Text” Control will indeed show up.

However, the existing WordPress Conditional tags are not enough sometimes. 

We are showing Blog posts on the Homepage and Blog posts Index page as well, right? What if you want to show “Read More Text” Control while previewing these pages and hide it for the rest of the pages?

This is where Custom Active Callbacks come in.

Introducing Custom Active Callbacks

Go back to the customize.php file and replace the current active_callback argument of “nd_dosth_readmore_text” Control with:

'active_callback' => 'nd_dosth_hide_readmore_on_condition'

Here is the updated “nd_dosth_readmore_text” Control

// Control for Read More text
$wp_customize->add_control( 'nd_dosth_readmore_text', 
    array(
        'type'        => 'text',
        'priority'    => 10,
        'section'     => 'nd_dosth_text_options',
        'label'       => 'Read More text',
        'description' => 'Text put here will be as the text for Read More link in the archives',
        'active_callback' => 'nd_dosth_hide_readmore_on_condition'
    ) 
);

And put the following Custom Active Callback definition at the end of the nd_dosth_customize_register action:


/**
 * Show "Read More Text" Control only if a condition is met.
 *
 * @param WP_Customize_Manager object
 * @return bool
 */
function nd_dosth_hide_readmore_on_condition( $control ) {
    if( is_archive() || is_front_page() || is_home() ){
        return true;
    } else{
        return false;
    }
}

In the above Custom Active Callback definition, we are just checking whether the current page on the site preview is one of these pages:

  1. Archive page
  2. Static Homepage
  3. Blog posts Index 

If so, we are returning True and the “nd_dosth_readmore_text” Control will be shown. If not, we are returning false and the Control will be hidden.

That’s all!

If you now go ahead and test out our Custom Active Callback, it indeed works like a charm.

Just like Sanitization Callbacks, the place of Custom Active Callbacks doesn’t matter as longs as they are within the scope of the functions.php file.

Taking it a step further

An Active Callback also allows us to show or hide the Control based on the value of another Control. 

For example, we can hide the “Read More Text” setting if the “Show Read More Link” setting is set to false.

It makes sense, right?

If “Show Read More Link” setting is set to false, it means the client is not interested in modifying the “Read More text” setting at all.

So, hiding it makes total sense.

Common, let’s do this!

Go back to the customize.php file and update the nd_dosth_hide_readmore_on_condition function definition like this:

function nd_dosth_hide_readmore_on_condition( $control ) {
    $setting = $control->manager->get_setting( 'nd_dosth_show_readmore' );
    if( false == $setting->value() ){
        return false;
    }

    if( is_archive() || is_front_page() || is_home() ){
        return true;
    } else{
        return false;
    }
}

Active Callbacks receive WP_Customize_Manager object. And using this object, we can retrieve the value of a particular Setting.


$control->manager->get_setting( 'nd_dosth_show_readmore' );

So, first, we are getting the value of the “nd_dosth_show_readmore” Setting. If it is false, we are hiding the “Read More Text” Control right away by returning False. We are not interested in any further checks.

But if the “nd_dosth_show_readmore” Setting is True, then we are checking if it is a certain page.

Makes sense?

You can also combine the above IF CONDITIONS in the following way:

function nd_dosth_hide_readmore_on_condition( $control ) {
    $setting = $control->manager->get_setting( 'nd_dosth_show_readmore' );
    if( ( true == $setting->value() ) and ( is_archive() || is_front_page() || is_home() ) ){
        return true;
    } else{
        return false;
    }
}

Also, remember, there are two things happening at the same time when you turn off the “Show Read More Link” setting. 

  1. Because of our custom active callback, The “Read More Text” Control is getting hidden.
  2. And because of the IF CONDITION inside the blog-index.php template file, the “Continue Reading” link is also getting hidden.

These both are two separate things. The active callback is only responsible for hiding the Control. It has nothing to do with the “Continue Reading” link on the Site Preview side.

Taking it even further

Everything is working fine but currently, the User Experience is a bit clunky, isn’t it?

We will fix it in the next lesson.