Site Overlay

Enable LearnDash Focus Mode conditionally on a course-by-course basis.

Focus mode is the way LearnDash allows you to provide your users with a distraction-free interface in your courses.

The Focus Mode was introduced in LearnDash 3.0, and it has been available in all subsequent versions ever since.

In your WordPress admin, go to LearnDash LMS > Settings, and under the General tab, inside the Design & Content Elements meta box, scroll down to the ‘Focus Mode’ option.

There, you can enable or disable the Focus Mode.

LearnDash Focus Mode is a global feature by design. When you turn it on, you are enabling it for all courses without exceptions.

That brings the question: How can you partially enable the Focus Mode?

It would be interesting if you could say what courses should have Focus Mode and what courses shouldn’t have it, right?

In LearnDash, there is no option to enable the Focus Mode for a specific course, though.

There is no way to enable the Focus Mode and then select what courses should be excluded from it either.

A couple of weeks ago, a member on the LearnDash LMS Tips & Tricks group on Facebook made the following question:

Is there a way to enable/disable Focus Mode on a course-by-course basis?

The answer was very clear: No, unless it involves custom development.

That question stuck with me, and I decided to take it up for a challenge.

The short answer is yes; you can enable or disable the LearnDash Focus Mode on a course-by-course basis.

So, it is possible. YEAH!

Let’s dive into how you can enable or disable the LearnDash Focus mode on a course by course basis.

You can enable or disable the Focus Mode globally from the admin, as discussed before.

Behind the scenes, the Focus Mode on/off toggle button in the LearnDash settings page is connected to a value in the wp_options table in the WordPress database.

There is an option called learndash_settings_theme_ld30 that holds as value a serialized array full of options as properties.

One of those values is focus_mode_enabled.

But it actually is not there by default. At least not when you have not enabled the Focus Mode yet.

You may ask, how the heck would you find out about focus_mode_enabled value in the first place?

Scan the LearnDash code base for focus_mode_enabled, and you’ll find a file called class-ld-settings-section-theme-ld30.php inside sfwd-lms/themes/ld30/includes, which contains the focus_mode_enabled option with a default value of zero.

Now, with that information, you can run the following experiment:

Retrieve the serialized option with the WordPress get_option() function.

$ld30_settings = get_option('learndash_settings_theme_ld30', array());

The value should be automatically unserialized and transformed into an array.

Now, select the focus_mode_enabled property in the array and assign it an empty string as a value.

$ld30_settings['focus_mode_enabled'] = '';

Lastly, change the option value with your newly assigned value. Use the WordPress update_option() function to modify the value.

update_option('learndash_settings_theme_ld30', $ld30_settings);

Place all three snippets in the functions.php file of your active theme, save the changes, and load any page.

In the WordPress admin, go to LearnDash LMS > Settings, scroll down to the Focus Mode option, and you’ll see it is turned off.

Go back to your theme’s functions.php file and set the focus_mode_enabled property to ‘yes’, and save the changes.

$ld30_settings['focus_mode_enabled'] = 'yes';

Reload the tab with the LearnDash settings, scroll down to the Focus Mode option again, and you’ll see this time it is enabled.

Brilliant. You have discovered a way to programmatically enable or disable the Focus Mode.

With that knowledge, you can create a custom button in the wpadminbar that switches the Focus Mode on and off without having to go all the way down to the LearnDash settings page.

But that’s it. You still don’t have a way to conditionally enable or disable the LearnDash Focus Mode for a specific course.

However, what you now know is that the Focus Mode feature relies entirely on the value of the focus_mode_enabled option in the database.

LearnDash has some logic in place that looks for the focus_mode_enabled option value.

If it is set to yes, display Focus Mode.

If it is set to an empty string, disable Focus Mode from the view.

You’d need to somehow change the focus_mode_enable option value to yes or an empty string when a user visits a course to either enable or disable the Focus Mode for that specific course.

But then, if you use the method above of changing the option value with update_option(), you would bring a ton of conflicts to your website as with every page load, the option would be turning on and off.

The solution you need is to make LearnDash think the Focus Mode is enabled while it is not.

But how, you ask?

In WordPress, you have actions and filters, globally called hooks. There are regular hooks, and there are also dynamic hooks.

With the option_{$option} hook, you can filter the current value of an option.

For the option holding the focus_mode_enabled property, you’d reference it as follows.

option_learndash_settings_theme_ld30

And then you’d use it like this:

add_filter('option_learndash_settings_theme_ld30', 'modify_learndash_option_value');

function modify_learndash_option_value($value) {

    $value['focus_mode_enabled'] = 'yes';

    return $value; // Always return the value.
    
}

The focus_mode_enabled option is now set to yes globally. Similar to your previous experiment above, go to the LearnDash settings page again, and you’ll see the Focus Mode toggled on.

But is the Focus Mode enabled?

To LearnDash, Focus Mode is enabled. But if you retrieve the serialized option again and do a var_dump on it, you’ll see that the focus_mode_enabled option is not really part of the array:

$ld30_settings = get_option('learndash_settings_theme_ld30', array());

echo '<pre>';
var_dump($ld30_settings);
echo '</pre>';

What you really are doing is intercepting the focus_mode_enabled option value before LearnDash logic ‘sees’ it.

Then, when LearnDash sees the value, it is set to whatever you set it to.

See that the value in the database remains intact.

This is useful in case you want to enable or disable the Focus Mode globally and then virtually enable or disable it on a course-by-course basis.

The next step is to define the condition that allows you to enable the focus mode on a specific course.

If you dive a little deeper into the dynamic filters, you’ll find another one called pre_option_{$option}.

You can use any of the two option_learndash_settings_theme_ld30 or pre_option_learndash_settings_theme_ld30.

The advantage of using pre_option_{$option} is that it is called before WordPress retrieves the option from the database. This prevents a database call and allows you to set whatever value you want for the option in a virtual sense.

The experiment examples below use the pre_option_{$option} dynamic filter.

The next advantage of using the pre_option_{$option} dynamic filter is that it loads early in the WordPress load cycle.

If you see from the details discussed previously, you need to modify the value before LearnDash even know about it.

You can prove that by building a function and hooking it into the template_redirect action.

It may be enough to play around with the post object and retrieve the post ID and the post type, then check if it belongs to a course, filter the focus_mode_enabled option.

By the time all that happens, LearnDash already retrieved the focus_mode_enabled option value from the WordPress database and is loading the course layout based on that value, either with Focus Mode enabled or disabled.

In other words, you are too late in the WordPress load cycle.

You need to stick with the pre_option_learndash_settings_theme_ld30 dynamic filter.

Returning to the condition to check for the specific course, you need to be aware that the Focus Mode in a course applies only to the steps inside that course.

When you enable Focus Mode in the LearnDash settings and go to the Single Course Page, you will only see the Focus Mode when you open any step on that course, either a Lesson, Topic, Quiz, Assignment, etc.

That means there is no straightforward way to say “Hey Focus Mode, please do not appear in this course”.

You’d need to check in the lesson if it belongs to the specific course you want to enable or disable the Focus Mode for, and then run your custom logic.

Thankfully, LearnDash provides a function called learndash_get_primary_course_for_step(), which does just that.

The function requires the step ID to be passed as a parameter. It then will return the ID of the course it belongs to.

learndash_get_primary_course_for_step($current_step_id);

You’d simply store the course ID in a variable, then evaluate the output of learndash_get_primary_course_for_step() with the course ID.

Now, you’d need a way to retrieve the current step ID to run the conditional.

That is an easy feat with get_the_ID().

The problem is that the pre_option_learndash_settings_theme_ld30 filter is ‘too early’ in the load cycle.

What this means is, on that stage of the load cycle, you cannot access the post object in WordPress as it has not loaded yet.

So, how can you use the good things of “both worlds” and put together the dynamic filter but use your custom condition to enable or disable Focus Mode?

You can extract information from the requested URL, like this

$request_uri = $_SERVER['REQUEST_URI'];

Then, you can get the post ID like this:

$post_id = url_to_postid($request_uri);

Now, you are good to make your condition. Let’s say you want to enable the Focus Mode for a course with ID 728. Your code would look something like this:

$course_with_focus_mode = '728';

$request_uri = $_SERVER['REQUEST_URI'];
$post_id = url_to_postid($request_uri);

if(learndash_get_primary_course_for_step($post_id)){
  $value['focus_mode_enabled'] = 'yes';
};

IMPORTANT: You should set the ID as a string, as the learndash_get_primary_course_for_step() function returns a string.

Every time a post is queried, the code above will check if the current post belongs to the course with ID 728.

If true, then the focus_mode_enabled option will be set to yes.

Of course, you still need to wrap the code around the pre_option_learndash_settings_theme_ld30 dynamic filter, like so:

add_filter('pre_option_learndash_settings_theme_ld30', 'virtually_enable_focus_mode_request_uri');

function virtually_enable_focus_mode_request_uri($value) {

	if (!$value) {
        $value = array();
    }

    $course_with_focus_mode = '728';

    $request_uri = $_SERVER['REQUEST_URI'];
    $post_id = url_to_postid($request_uri);


    if ( learndash_get_primary_course_for_step( $post_id ) === $course_with_focus_mode )) {
        $value['focus_mode_enabled'] = 'yes';
    }

    return $value;
}

Can you include multiple courses at once? Yes, you can.

Create an array to hold a few course IDs.

Then, evaluate if the course ID retrieved is any of the courses in the array with the function is_array().

Modify the code like this:

add_filter('pre_option_learndash_settings_theme_ld30', 'virtually_enable_focus_mode_request_uri');

function virtually_enable_focus_mode_request_uri($value) {

	if (!$value) {
        $value = array();
    }

	$courses = array('7','34');

    $request_uri = $_SERVER['REQUEST_URI'];
    $post_id = url_to_postid($request_uri);


    if ( in_array(learndash_get_primary_course_for_step( $post_id ), $courses)) {
        $value['focus_mode_enabled'] = 'yes';
    }

    return $value;
}

If you are curious like me, you may have realized that this gives you the power to enable or disable the Focus Mode on a single specific step only, let’s say, a specific lesson, topic, quiz, etc.

You’d change the condition to check if the current $post_id matches a specific ID.

You can additionally check if the current post’s post type is a lesson.

add_filter('pre_option_learndash_settings_theme_ld30', 'virtually_enable_focus_mode_request_uri');

function virtually_enable_focus_mode_request_uri($value) {
    if (!$value) {
        $value = array();
    }

    $request_uri = $_SERVER['REQUEST_URI'];
    $post_id = url_to_postid($request_uri);

    if (get_post_type($post_id) === 'sfwd-lessons' && $post_id == 2337) {
        $value['focus_mode_enabled'] = 'yes';
    }

    return $value;
}

Ok, that’s it. Now, over to you.

Remember to safely test this on a staging environment before committing changes to a live site.

I tested this on LearnDash 4.9.0.1, the latest version available.

How can you test it out too?

Go to demo.learndash.com, and spin up a new LearnDash Demo.

Then, go to LearnDash LMS > Courses and retrieve some IDs from courses and lessons.

With these IDs, go to Appearance > Theme Editor, locate the functions.php file of the active theme (Kadence), and start hacking around with the snippets on this article.

Until next time!

Leave a Reply

Your email address will not be published. Required fields are marked *