An in-depth guide on using Ajax with WordPress

Page Detection in WordPress

Page detection is easy! It’s so easy, in fact, that more plugins and themes should use it to load their scripts and styles.

Let’s say you have a WordPress site that has ninety-six (yes, I know this person) plugins installed. Each performs a specialized function, and each installs its own CSS and JavaScript. Now imagine that all of these CSS and JavaScript files are loaded for each and every single page load. Catastrophe? I think yes.

Perhaps the above scenario is a little far-fetched, but I’ve come across sites where the CSS and JavaScript overhead has approached half a megabyte per page load. All I have to say is, “Ick!”

One solution to the above dilemma is to install a caching plugin to compress the scripts and styles. While extremely helpful, this is like putting a band-aid on a recently lost limb. It’s not solving the real issue: there are too many damn scripts running! And, in reality, it’s probably not your fault. Let’s blame the plugin and theme authors, shall we?

A plugin’s (or theme’s) scripts and styles should only load where absolutely needed. Failure to do so can (and will) cause script conflicts, weird CSS bugs, and (of course) increase site loading time, which is bad for SEO and visitors to your site (especially those on mobile devices).

This is where page detection comes to the rescue. With page detection, the scripts and styles load exactly where needed and nowhere else.

The lack of proper page detection is often why plugins get a bad rap. People accuse plugins of slowing down a site considerably, and if many lack any form of page detection, these people are right. It will slow down a site. And then you’ll see yet another post on “How to do XYZ without a plugin.”

Let’s get over this hump, use some proper page detection, and get these plugins (and themes) running as efficient as possible.

The first step in page detection is learning the many WordPress conditionals, so let’s start there.

WordPress Conditionals

Let’s start with some basic starter code. We’ll be using the WordPress action wp_enqueue_scripts to load a script on the front-end.

add_action( 'wp_enqueue_scripts', function() {
	wp_enqueue_script( 'jquery' );
} );

The above code will run the jQuery library on every front-end page. If that’s the goal, then you’re done. However, what if you don’t want to load jQuery on every page? WordPress conditionals are to the rescue in this case.

What if you only want the script to run on the front page? Or perhaps only on a page with a specific post type? You can do so with WordPress conditionals. Let’s dive in!

Loading Scripts Conditionally on the Front-end

As stated before, you don’t typically want to load your scripts on every single page on the front-end. Here are a few common conditionals that will help you out.

Loading Scripts on the Blog Page

In WordPress, by default, the front page is the blog page. You can create a dedicated blog page by simply creating a page and assigning it as your blog page in Settings->Reading. You can likewise do the same for a page and make it your front page by default.

The is_home conditional will load either on your homepage (if you have a default install) or on the blog page you designate.

Here’s an example of using the is_home conditional to only load on your blog archive page.

add_action( 'wp_enqueue_scripts', function() {
	if ( is_home() ) {
		wp_enqueue_script( 'my-script-handle' );
	}
	
} );

Loading Scripts on the Front Page

If you have created a page and set it as your front page in Settings->Reading, then this next conditional is for you. It simply checks if it’s the front page of a site and loads the script there.

add_action( 'wp_enqueue_scripts', function() {
	if ( is_front_page() ) {
		wp_enqueue_script( 'my-script-handle' );
	}
} );

The is_front_page conditional is your friend if you only want to load scripts on the front page of your site.

Loading Scripts For Specific Post Types

What if you only want to load your script for a specific post type? The function get_post_type is now your best friend.

Here’s an example:

add_action( 'wp_enqueue_scripts', function() {
	if ( 'my_post_type' === get_post_type() ) {
		wp_enqueue_script( 'my-script-handle' );
	}
} );

Loading Scripts on Posts or Pages

Need a script to run on a specific post or page?  WordPress conditionals have you covered.

Here is an example of the is_single conditional, which detects if you are on a post or not (within the code are several examples of usage).

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_single() ) {
		return;
	}
	//or use: 
	if ( ! is_single( 2043 ) ) { //Checks for post ID 2043
		return;
	}
	//or use:
	if ( ! is_single( 'my-post-slug' ) ) { //checks for a post slug of my-post-slug
		return; 
	}
	//or use:
	if ( ! is_single( array( 2043, 'my-post-slug', 'my post title' ) ) ) { //Pass an array of matches you'd like to check (behaves like an "or" statement)
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

What about pages?  You would use the is_page conditional (again, this example shows several uses).

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_page() ) {
		return;
	}
	//or use: 
	if ( ! is_page( 22 ) ) { //Checks for page ID 22.
		return;
	}
	//or use:
	if ( ! is_page( 'my-page-slug' ) ) { //checks for a page slug of my-page-slug.
		return;
	}
	//or use:
	if ( ! is_page( array( 22, 'my-page-slug', 'my page title' ) ) ) {  //Pass an array of matches you'd like to check (behaves like an "or" statement).
		return;
	 }

	wp_enqueue_script( 'my-script-handle' );
} );

Loading Scripts on Singular Items

The is_singular function allows you to load a script on any existing single post of any post type. You can also pass an array of post types to limit which post types your script will run under. Here’s an example:

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_singular() ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

And here’s an example of only loading for a specific post type (we’re using pages in the example):

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_singular( array( 'page' ) ) ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

Loading Scripts for Taxonomies Only

Say you want to only load for a certain taxonomy archive or a specific term? You would use the is_tax conditional.

Here’s an example for loading for all taxonomy archives:

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_tax() ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

You can also limit which taxonomy archive is targeted:

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_tax(
		array(
			'custom_taxonomy',
		)
	) ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

You can even limit by taxonomy and/or term as both arguments are optional.

add_action( 'wp_enqueue_scripts', function() {
	if ( ! is_tax(
		array(
			'custom_taxonomy',
		),
		array(
			'custom_term',
		)
	) ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

How about loading for a specific post, page, or custom post type based on if it has the term? We’ll use has_term for this.

In the example below, the 1st, 2nd and 3rd arguments are optional. If no terms are passed, it is simply a check if an item even has terms to begin with.

Here’s an example of retrieving a post with ID 24, and that post has a few terms and a taxonomy attached. This is useful for custom post types!

add_action( 'wp_enqueue_scripts', function() {
	if ( ! has_term(
		array(
			'term1',
			'term2',
		),
		array(
			'taxonomy_name',
		),
		24
	) ) {
		return;
	}
	wp_enqueue_script( 'my-script-handle' );
} );

Loading Scripts When a Shortcode is Present

Here’s a decently hard one. How in the heck do you do page detection on a shortcode that is embedded within a post’s content?

For those not acquainted with shortcodes, they are small snippets of text (e.g., ) placed within a post’s (or page’s) content. Shortcodes are very useful for placing executable code inside what is typically non-dynamic content. However, performing page detection for a specific shortcode inside the content isn’t exactly straightforward. Or is it?

Let’s assume we’re loading a lightbox script and we only want to load our script on a page that has a gallery shortcode. We’ll use has_shortcode for this.

add_action( 'wp_enqueue_scripts', function() {
	global $post;
	if ( is_a( $post, 'WP_Post' ) && has_shortcode( $post->post_content, 'gallery' ) ) {
		wp_enqueue_script( 'my-script-handle' );
	}
} );

Loading Scripts on Comment Pages

What if we have a script that manipulates comments? For example, a script that allows front-end editing of comments. We’ll first check if comments are active:

add_action( 'wp_enqueue_scripts', function() {
	if ( comments_open() ) {
		wp_enqueue_script( 'my-script-handle' );
	}
} );

And for an added bonus, we’ll make sure there is more than one comment on the page.

add_action( 'wp_enqueue_scripts', function() {
	global $post;
	if ( is_a( $post, 'WP_Post' ) && comments_open() && 0 !== absint( $post->comment_count ) ) {
		wp_enqueue_script( 'my-script-handle' );
	}
} );

WordPress Conditionals Conclusion

WordPress conditions on the front-end are extremely useful, and I only captured a fraction of them. Head to https://wpajax.pro/conditionals to see a full and concise list with numerous code examples.

Loading Scripts in the Admin Area Only

As I previously mentioned, there are two main WordPress actions that enable you to load scripts and styles: wp_enqueue_scripts (for the front-end) and admin_enqueue_scripts (for the admin area).

Let’s change things around a bit from front-end conditionals to admin area conditionals.

Loading Scripts for your Sub-menu or Menu

The admin_enqueue_scripts action can have a hook parameter. Let’s take a look at adding a sub-menu to the Settings menu item in the WordPress admin area. We’ll be making use of add_submenu_page, which takes several arguments:

  1. Parent Slug (string)
  2. Page Title (string)
  3. Menu Title (string)
  4. Capability (string)
  5. Menu Slug (string)
  6. Callable function (string or array)
  7. Position (integer)

We’ll be using an evil global for this to work. If you were using class notation, it would be best to assign this to a class variable.

Here’s an example of loading a script only on a plugin’s settings page:

global $my_hook;
$my_hook = false;
add_action(
	'admin_menu',
	function() {
		global $my_hook;
		$my_hook = add_submenu_page(
			'options-general.php',
			'My Custom Submenu Page',
			'My Custom Submenu Page',
			'manage_options',
			'my-custom-slug',
			'my_menu_callback'
		);
	}
);
add_action(
	'admin_enqueue_scripts',
	function( $passed_hook ) {
		global $my_hook;
		if ( $passed_hook === $my_hook ) {
			die( 'test' );
			wp_enqueue_script( 'my-script-handle' );
		}
	}
);
/**
 * Menu output.
 */
function my_menu_callback() {
	echo 'Hello World';
}

Here’s an example using class notation:

/**
 * Class for adding a submenu.
 */
class My_Custom_Class {

	/**
	 * Store the admin menu hook.
	 *
	 * @var string $hook The hook name.
	 */
	private $hook = '';

	/**
	 * Class Constructor.
	 */
	public function __construct() {
		add_action( 'admin_menu', array( $this, 'init_admin_menu' ) );
		add_action( 'admin_enqueue_scripts', array( $this, 'output_scripts' ), 10, 1 );
	}

	/**
	 * Initialize the admin menu.
	 */
	public function init_admin_menu() {
		$this->hook = add_submenu_page(
			'options-general.php',
			'My Custom Submenu Page',
			'My Custom Submenu Page',
			'manage_options',
			'my-custom-slug',
			array( $this, 'menu_callback' )
		);
	}

	/**
	 * Output Scripts.
	 *
	 * @param string $hook_name The Hook name which contains an admin page or a hook.
	 */
	public function output_scripts( $hook_name ) {
		if ( $hook_name === $this->hook ) {
			wp_enqueue_script( 'my-script-handle' );
		}
	}

	/**
	 * Menu output.
	 */
	public function menu_callback() {
		echo 'Hello World';
	}
}
new My_Custom_Class();

Loading Scripts for Other Admin Pages

Here are some examples of hook names:

  1. Dashboard: ‘index.php’
  2. Posts: ‘edit.php’
  3. Media: ‘upload.php’
  4. Pages: ‘edit.php?post_type=page’
  5. Comments: ‘edit-comments.php’
  6. Custom Post Types: ‘edit.php?post_type=your_post_type’
  7. Appearance: ‘themes.php’
  8. Plugins: ‘plugins.php’
  9. Users: ‘users.php’
  10. Tools: ‘tools.php’
  11. Settings: ‘options-general.php’
  12. Network Settings: ‘settings.php’

Here’s an example of loading a script for a custom post type:

/**
 * Class for adding a script based on post type.
 */
class My_Custom_Class {

	/**
	 * Class Constructor.
	 */
	public function __construct() {
		add_action( 'admin_enqueue_scripts', array( $this, 'output_scripts' ), 10, 1 );
	}

	/**
	 * Output Scripts.
	 *
	 * @param string $hook_name The Hook name which contains an admin page or a hook.
	 */
	public function output_scripts( $hook_name ) {
		if ( 'presentation' === get_post_type() ) {
			wp_enqueue_script( 'my-script-handle' );
		}
	}
}
new My_Custom_Class();

Page Detection for Specific Admin Pages

What if you only want to load a script for a certain admin page (such as when editing a post)? 

Fortunately, admin_print_scripts takes a suffix parameter in the format of:

admin_print_scripts-suffix

The suffix can be several different things, so let’s first go over how to load a script for a specific admin page.

Say, for example, you would like a script to run when someone is creating or editing a post. There are two specific files that allow you to do this, which happen to be post.php (editing posts or pages) and post-new.php (new posts or pages). As a result, you can use post.php and post-new.php as the suffix parameter.

Here’s an example:

/**
 * Class for adding a script based on post type.
 */
class My_Custom_Class {

	/**
	 * Class Constructor.
	 */
	public function __construct() {
		add_action( 'admin_print_scripts-post.php', array( $this, 'output_scripts' ) );
		add_action( 'admin_print_scripts-post-new.php', array( $this, 'output_scripts' ) );
	}

	/**
	 * Output Scripts.
	 *
	 * @param string $hook_name The Hook name which contains an admin page or a hook.
	 */
	public function output_scripts( $hook_name ) {
		if ( 'post' === get_post_type() ) {
			wp_enqueue_script( 'my-script-handle' );
		}
	}
}
new My_Custom_Class();

In the example, our script will run for files post.php and post-new.php. Since the script would also run for pages, we do a quick type-check to make sure it’s just a post.

You can translate the above example to just about any admin page.

Need a script to run when editing a comment?  Use the suffix comment.php.  What about when adding a new user?  Use the suffix user-new.php.

There are many of these types of pages in the admin panel, and loading scripts or styles is as easy as adding the page name as a suffix (to admin_print_scripts and admin_print_styles respectively).

Page Detection Conclusion

In this chapter, you learned how to perform page detection on the front-end and admin area of a WordPress site.

Page detection allows you to load scripts and styles exactly where necessary.  Page detection also helps with page load since unnecessary files are prevented from loading.

For this next chapter, let’s move away from scripts and styles a bit, and instead concentrate on some page-loading techniques that will help you on your Ajax journey.

Leave a Comment

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

Scroll to Top