Disable the Elementor Theme Builder programmatically

If for any reason you see yourself in the need to deactivate the Elementor Theme Builder, you can use the following snippet:

add_action( 'wp_loaded', 'remove_elementor_register_conditions', 1 ); // Hook with priority 1

function remove_elementor_register_conditions() {

    // Get Elementor Pro's Module instance.
    $theme_builder_module = \ElementorPro\Modules\ThemeBuilder\Module::instance();

    // Access Conditions Manager.
    $conditions_manager = $theme_builder_module->get_conditions_manager();

    // Check if not null.
    if ( $conditions_manager ) {
        remove_action( 'wp_loaded', [ $conditions_manager, 'register_conditions' ] ); // Unhook the register_conditions() method from the Theme Builder module.
}

Customize the WordPress author slug without a plugin

The author slug in WordPress is the ‘pretty link’ you can use to access the archive page of posts published by a specific user account.

To give you an example, https://obijuan.dev/author/obijuandev.

If you visit that link, you’ll get all posts created and published by my user account here on my website.

By default, WordPress gives you the author slug composed of the ‘author’ keyword followed by the account’s nicename. In most cases, this nicename can lead to a very easy guess of the actual username associated with the account, leading to potential security threats.

As a security measure, it is convenient to change this nicename to something else.

The most ‘straightforward’ method would be to change the nicename value directly in the database record for the user account.

However, in an ideal scenario, you should really not mess with the WordPress database. Even as a developer, you should keep the WordPress database intact as much as possible.

So, what other option do you have to customize the WordPress author slug?

You can leverage the power of hooks to mask the author’s nicename, hence changing the author slug with a custom name.

The main benefit of this approach is that it will protect the username from any potential attackers from knowing your account’s username.

The reasoning behind this is that attackers can use the account’s username in an attempt to crack your account’s password and gain admin access to your website.

So, how do you change the author slug in WordPress?

Let’s draw a few logical steps you can take advantage of to achieve the proposed outcome:

You need to indicate what user you will change the author slug for and the custom name you’ll replace the author slug with. You can store these in variables; please see the example below:

$specific_user = 'obijuan';
$custom_slug = 'obijuandev';

Use the author_link filter to change how WordPress links to the author’s page.

The author_link filter by default uses three parameters. For this example you only need to leverage two of those, $link and $author_id.

The first one gets the current author link value, while the other literally gets the author ID.

You also need to pass your $custom_slug and $specific_user to use the assigned values in the function’s logic.

Retrieve the user data with the get_userdata() function. This will bring the user object for a specific account.

Check if the user_login property matches the $specific_username, then build a ‘new link’ by replacing the selected account’s nicename with the $custom_slug.

add_filter('author_link', function ($link, $author_id) use ($custom_slug, $specific_username) {
    $user_info = get_userdata($author_id);
    if ($user_info->user_login == $specific_username) {
        $link = str_replace($user_info->user_nicename, $custom_slug, $link);
    }
    return $link;
}, 10, 2);

More information about the author_link filter can be found in the WordPress Code Reference: https://developer.wordpress.org/reference/hooks/author_link/.

Redirect visitors to the correct author’s page.

WordPress needs to know where to redirect the user when clicking a link with the new author slug.

You can add a rewrite rule to tell WordPress where to redirect the user.

add_rewrite_rule(
    'author/' . $custom_slug . '/?$', 
    'index.php?author_name=' . $specific_username,
    'top'
);

Lastly, ensure WordPress recognizes the new query variable.

add_filter('query_vars', function($vars) {
    $vars[] = 'author_name';
    return $vars;
});

To make the code work, wrap it around a function and hook that function into the init WordPress hook.

/*
* Snippet: Customize the WordPress author slug without a plugin.
* Author: Obi Juan.
* Author URI: https://obijuan.dev
* Explanation: https://obijuan.dev/customize-the-wordpress-author-slug-without-a-plugin/.
* Version: 1.0.0
* Publish Date: September 28th, 2023.
*/
function custom_author_slug() {
    // Set your custom slug and specific username here.
    $custom_slug = 'custom-slug';
    $specific_username = 'specific_username';

    // Customizing the author link.
    add_filter('author_link', function ($link, $author_id) use ($custom_slug, $specific_username) {
        $user_info = get_userdata($author_id);
        if ($user_info->user_login == $specific_username) {
            $link = str_replace($user_info->user_nicename, $custom_slug, $link);
        }
        return $link;
    }, 10, 2);

    // Adding a rewrite rule for the custom slug.
    add_rewrite_rule(
        'author/' . $custom_slug . '/?$', 
        'index.php?author_name=' . $specific_username,
        'top'
    );

    // Ensure WordPress recognizes the new query variable.
    add_filter('query_vars', function($vars) {
        $vars[] = 'author_name';
        return $vars;
    });
}
add_action('init', 'custom_author_slug');

Add the final version of the code to your theme’s functions.php file.

You can add it to your favorite code snippet plugin alternatively.

The third option is to create a small utility plugin to hold your code.

NOTE: The author slug will not change until you flush your Permalinks. To flush the Permalinks, in the WordPress admin go to SETTINGS > PERMALINKS, scroll down the page, and click the blue ‘Save’ button.

Over to you.

Let me know how it goes in the comments, whether you encounter any issues, if it works flawlessly on the first try (hopefully), or if you have any questions.

How to enqueue scripts or styles only if a shortcode exists on a page

In general, it is a best practice to only enqueue a script or style on your website, only where you need it.

Specifically, this helps with performance.

And in any case, why would you need yourSocialLogin.css file in every page of your website anyway, right?

So, let’s say you are adding a custom shortcode that relies on custom scripts and styles to be rendered correctly on your site’s frontend.

To enqueue the scripts and styles only on pages where the shortcode is implemented, you need to first check if the current is a page and if the page’s content has the shortcode.

For this, WordPress provides the functions is_page() and has_shortcode.

Also, remember to invoke the global $post variable so you can access the post object.

Something like this:

function check_if_page_has_my_shortcode(){

global $post; // To access the current post object.

  if(is_page() && has_shortcode($post->post_content, 'my_shortcode_tag')){
  
       return true; // The shortcode is in the page's content.
  
  } else {
  
       return false;
  
  }

}

That’s it!

Until next time.

Change the PDF certificate filename in LearnDash

The beauty of WordPress and open source is that virtually anything is customizable.

And premium plugins like LearnDash are not an exception to the rule.

In LearnDash, you can create certificates to reward your students after completing a quiz or finishing a course.

These certificates are generated as a PDF file on the fly. After earning the certificate, you can download the PDF file.

By default, LearnDash generates a file with the username, course name, certificate name and the website name.

Let’s say you are not interested in presenting this name format to your users, and you want something different instead.

For example, make the certificate name a combination of the website name, course and user ID.

You can do that with the following filter: learndash_certificate_builder_pdf_name

The filter admits three parameters, which we will use, filename, certificate ID, and course ID.

Then, you can use it as follows:

add_filter('learndash_certificate_builder_pdf_name', 'obi_custom_certificate_name', 10 , 3);

function obi_custom_certificate_name(){
     
     $course = get_post( $course_id ); // Instantiate the 'course' post object.
     $user   = wp_get_current_user(); // Instantiate the user object.
     $websiteName = get_bloginfo( 'name' ); // Retrieve the website name.

     $filename = $websiteName . ' - ' . $course->post_title . ' - ' . $user->ID . '.pdf'; // Build the filename structure.

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

Add the code to your theme’s functions.php file, or create a custom plugin for it.

Remove post types from the WordPress search feature

Edited: February 4th, 2023.

The base content type structure in WordPress are posts. Pages, Comments, Attachments, etc., are posts in WordPress.

Some plugins add their own custom post types to take advantage of the base content structure. For example, WooCommerce adds the ‘product’ custom post type. LearnDash, adds the ‘sfwd-courses’ custom post type for courses. And so on.

These custom post types, by default, are enabled to be searched. When you do a search in WordPress, the WordPress search will bring all the matching posts within the custom post types enabled to be searched.

But sometimes you may want to prevent the WordPress search from including results from certain post types.

You can remove post types from the WordPress search feature by hooking into the register_post_type_args action in WordPress.

Post types are registered with a series of arguments, that set the properties they will have. Within the arguments, you can find one called ‘exclude_from_search’.

Keep in mind, you need to know the name of the custom post type you want to exclude from the search.

Let’s say, you want to exclude WooCommerce products.

A function that exclude products would be as follows:

function obi_exclude_woocommerce_products_from_search($args, $post_type){
     if( 'product' == $post_type){
          $args['exclude_from_search'] = true;
     }
     return $args;
}

add_action('register_post_type_args', obi_exclude_woocommerce_products_from_search');

Edit:

To exclude multiple post types from the search, you can use a code like this:

/* LOOP POST TYPES */

add_action( 'register_post_type_args', 'mws_loop_post_types', 1, 2);
 
function mws_loop_post_types( $args, $post_type ) {
	
	$mws_post_types = array('sfwd-courses', 'sfwd-lessons'); // Add the slug for as many post types as you want.
	
	// EXCLUDES FROM SEARCH ONLY THE SPECIFIC POST TYPES IN THE ARRAY mws_post_types
	
	for ($i = 0; $i <= (sizeof($mws_post_types)) ; $i++) {
		if( ($mws_post_types[$i]) == $post_type ){
			$args['exclude_from_search'] = false;
		}
	}
	
	
	return $args;
}