Create a Custom WordPress Shortcode

In any software project, you’ll find yourself wanting to reuse some code in multiple places. It’s the same when writing a document too – you’ll want to do something once and show it in multiple places, perhaps with a couple of small changes. Usually, in software, we’d put reusable code in a function, and then call this function whenever we want to run this bit of code. In WordPress, we can use a custom shortcode to do the same thing. WordPress and WooComemrce both include useful shortcodes, but it won’t be long before you want tocreate your own custom shortcode.

Before we start, you’ll need somewhere to put your shiny new custom shortcodes. If you haven’t created a custom child theme, then you should create one now. When you’ve got a custom child theme, you’ll have a functions.php file where you can put your shortcodes. We’re not just going to dump a bunch of cop-and-paste code into our functions.php file. We’re going to keep our functions.php clean and tidy.

What Actually is a Shortcode?

Put simply, a shortcode has a simple name, and you call it in your content by putting it between square brackets. For example, to show the top 3 features products on a website with WooCommerce installed, you can do something like this:

[featured_products limit=3]

When you’re editing content in WordPress you’ll either be using the Gutenberg Block Editor or the Classic Editor. If you’re using the Block Editor, just create a new block, search for shortcode and then create the new block.

block-editor-new-shortcode-4369195
Create a shortcode in the Gutenberg Block Editor

If you’re using the classic editor, you can just go right ahead and insert the shortcode directly in your content. There are loads of shortcodes that you can have a play with:

Create a Shortcode to Reuse a HTML Snippet

Lets say you’re building a website for a small business and you want a collection of social buttons and a call-to-action on several of the pages. Something like this.

<div class="my-call-to-action text-center mb-3">
   <a href="https://www.facebook.com/headwallhosting/" class="btn mr-2" title="Follow Headwall Hosting on Twitter" style="background-color: #3B5998; color: white;"><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
   <a href="https://twitter.com/HeadwallHosting" class="btn mr-2" title="Follow Headwall Hosting on Facebook" style="background-color: #1DA1F2; color: white;"><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
   <a href="https://wp-tutorials.tech/contact" class="btn btn-theme-primary mr-2" title="Email us at Headwall Hosting"><i class="fa fa-envelope-o mr-2" aria-hidden="true"></i>Send us an Email</a>
</div>

There’s a few things to unpick here…

  1. Don’t use inline styles. I’ve only done it here to keep the snippet simple (I’m not relying on an external stylesheet for the Facebook & Twitter colours).
  2. This snippet uses some Bootstrap CSS classes. If you’re not familiar with Bootstrap then I recommend you have a play with it. It’ll save you lots of time in the future. The W3Schools Bootstrap tutorial is a good place to start.
  3. We’re using Font Awesome for our Facebook and Twitter icons. Your parent/base theme probably already has access to Font Awesome. If not, you can add Font Awesome with a plugin.
  4. We’ve got hard-coded URLs in here. If we change the permalink for our contact page then we would need to update every place we use this snippet.
  5. If we want to add a new social button in the future, then we’d have to go to every place we use this snippet, and update it. Urgh! 🙁

Create the Template HTML File

The first thing we’re going to want to do is create a little template file that we can re-use whenever we want.

In your custom child theme’s main folder, create a subfolder called “snippets“. In this folder, create a new file called my-webs-socials-and-cta.php and paste the following code into it.

<?php

// Block direct access.
if (!defined('WPINC')) {
	exit('Do NOT access this file directly.');
}

?><div class="my-call-to-action text-center mb-3 bg-secondary">
   <a
      href="https://www.facebook.com/headwallhosting/"
      class="btn mr-2"
      title="Follow Headwall Hosting on Twitter"
      style="background-color: #3B5998; color: white;"
      ><i class="fa fa-facebook-official" aria-hidden="true"></i></a>
   <a
      href="https://twitter.com/HeadwallHosting"
      class="btn mr-2"
      title="Follow Headwall Hosting on Facebook"
      style="background-color: #1DA1F2; color: white;"
      ><i class="fa fa-twitter-square" aria-hidden="true"></i></a>
   <a
      href="<?php echo esc_url($cta_email_url) ?>"
      class="btn btn-theme-primary mr-2"
      title="Email us at Headwall Hosting"
      ><i class="fa fa-envelope-o mr-2" aria-hidden="true"></i><?php echo $cta_email_label; ?></a>
</div>

Now all we need to do is write a small PHP function to register the shortcode, which will include the the snippet where ever we want.

Register the Shortcode

Although we could just edit the functions.php file in your custom child theme, we’re going to keep things a tidier than that. Create a new file in the main folder of your custom child theme, called functions-shortcodes.php. Paste this code into this new file…

<?php

/**
 * Example shortcode to display a snippet file that has some
 * socials and a call-to-action.
 * 
 * https://wp-tutorials.tech/add-functionality/custom-wordpress-shortcode/
 */

// Block direct access.
if (!defined('WPINC')) {
	exit('Do NOT access this file directly.');
}

function do_shortcode_socials_and_cta($atts = array()) {
	$html = '';

	if (is_admin()) {
		// Don't do anything.
	} elseif (wp_doing_ajax()) {
		// Don't do anything.
	} else {
		// Replace my-website-text-domain with your child theme's text domain.
		$cta_email_label = __('Send us an Email', 'my-website-text-domain');
		$cta_email_url = site_url('contact');

		$file_name = 'snippets/my-webs-socials-and-cta.php';
		$full_path = trailingslashit(dirname(__FILE__)) . $file_name;

		if (!is_file($full_path)) {
			$html .= sprintf('Not found: <strong>%s</strong>', $full_path);
		} else {
			ob_start();
			include $full_path;
			$html .= ob_get_clean();
		}
	}

	return $html;
}
add_shortcode('socials_cta', 'do_shortcode_socials_and_cta');

Now just “include” this new PHP file from your main functions.php file. Somewhere near the top is good, like this:

// Load our custom child theme's shortcodes.
include_once 'functions-shortcodes.php';

So… The sequence of events when WordPress loads a page…

  1. WordPress loads our custom child theme’s functions.php file.
  2. Our functions.php file loads another file called functions-shortcodes.php, which registers a shortcode called “socials_cta“.
  3. If the post/page content includes the expression [socials_cta] then it’ll call our function and render the PHP/HTML.

Your new shortcode should work now. So… try it… add [socials_cta] to one of your posts or pages and make sure you can see your buttons and email link:

Adding Parameters

What we’ve done so far is a good place to start, but before long you’re going to want to pass parameters to your shortcodes. Let’s say we want to do something like this in one of our posts:

[socials_cta email_address="hello@headwall-hosting.com"]

If we pass the “email_address” parameter then we’ll render a “mailto:” URL instead of a link to our contact page.

When WordPress calls our registered shortcode function, it passes all the parameters in an associative array. So all we need to do is modify our shortcode function a bit, like this:

<?php

/**
 * Example shortcode to display a snippet file that has some
 * socials and a call-to-action.
 *
 * https://wp-tutorials.tech/add-functionality/custom-wordpress-shortcode/
 */

// Block direct access.
if (!defined('WPINC')) {
	exit('Do NOT access this file directly.');
}

function do_shortcode_socials_and_cta($atts = array()) {
	$html = '';

	if (is_admin()) {
		// Don't do anything.
	} elseif (wp_doing_ajax()) {
		// Don't do anything.
	} else {
        // Check the parameters for the email call-to-action button.
		$args = shortcode_atts(
			array(
				'email_address' => '',
				'email_label' => __('Send us an Email', 'my-website-text-domain'),
			),
			$atts
		);

		// Set the email URL as the /contact path on your site, but override
		// it if the email_address parameter is a valid email address.
		$cta_email_url = site_url('contact');
		if (filter_var($args['email_address'], FILTER_VALIDATE_EMAIL)) {
			$cta_email_url = 'mailto:' . $args['email_address'];
		}

		$cta_email_label = $args['email_label'];

		$file_name = 'snippets/my-webs-socials-and-cta.php';
		$full_path = trailingslashit(dirname(__FILE__)) . $file_name;

		if (!is_file($full_path)) {
			$html .= sprintf('Not found: <strong>%s</strong>', $full_path);
		} else {
			ob_start();
			include $full_path;
			$html .= ob_get_clean();
		}
	}

	return $html;
}
add_shortcode('socials_cta', 'do_shortcode_socials_and_cta');

Try It Out

Test test test… Make sure that it works 🙂 Go to any page or post on your site and add the new shortcode somewhere.

[socials_cta email_address="hello@headwall-hosting.com"]

We could also add a lebal for the email CTA.

[socials_cta email_address="hello@headwall-hosting.com" email_label="Say Hi!"]

That should help get you up-and-running with adding custom shortcodes to your WordPress website. You can just keep adding new custom shortcodes to your functions-shortcodes.php file, without making your main functions.php file too big and messy… and we like clean-and-tidy code 🙂

Leave a Comment

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