How to Create Custom WordPress Shortcodes for Your Editors

Craig Buckler
Share

WordPress Custom Shortcodes

This article is part of a series created in partnership with SiteGround. Thank you for supporting the partners who make SitePoint possible.

Ideally, WordPress authors should never need to edit raw HTML. You should enable plugins and custom meta boxes which allow the user to configure the page as necessary. Unfortunately, there are situations when it’s difficult or impractical to provide UI tools, e.g.:

  • a widget provides numerous configuration options
  • similar widgets can appear multiple times in the page at any location
  • widgets can be nested inside each other, such as a button overlaying a video within a sidebar
  • a widget’s implementation changes, e.g. you switch from one video hosting platform to another.

WordPress shortcodes are ideal for these situations. A shortcode allows the author to use text snippets such as [mywidget] which places an HTML component in the rendered page without the need for coding.

Where to Create Shortcodes

Shortcodes are often created to aid custom plugin usage so you should place those within the plugin code itself. However, you can also place shortcode definitions within a theme’s functions.php file. It’s possibly more practical to create a separate shortcodes.php file then include that within functions.php using the statement:

include('shortcodes.php');

Your First “Hello World” Shortcode

A shortcode definition consists:

  1. a function which returns a string of HTML code, and
  2. a call to the WordPress add_shortcode() hook which binds a the shortcode text definition to that function.

The most basic example:

<?php
// "Hello World" shortcode
function shortcode_HelloWorld() {
  return '<p>Hello World!</p>';
}
add_shortcode('helloworld', 'shortcode_HelloWorld');

(You can omit the <?php line if one is already present at the top of your file.)

Save the file then enter [helloworld] somewhere within a page or post. Visit that page and you’ll see it’s been replaced with a “Hello World!” paragraph.

Shortcode Parameters

Shortcodes can have optional parameters, e.g.

[sitemap title='Web pages', depth=3]

Parameters are passed as an array to the shortcode function as the first argument. The full code to generate a page hierarchy sitemap:

// sitemap shortcode
function shortcode_GenerateSitemap($params = array()) {

  // default parameters
  extract(shortcode_atts(array(
    'title' => 'Site map',
    'id'    => 'sitemap',
    'depth' => 2
  ), $params));

  // create sitemap
  $sitemap = wp_list_pages("title_li=&depth=$depth&sort_column=menu_order&echo=0");
  if ($sitemap) {
    $sitemap =
      ($title ? "<h2>$title</h2>" : '') .
      '<ul' . ($id? '' : " id="$id"") . ">$sitemap</ul>";
  }

  return $sitemap;
}
add_shortcode('sitemap', 'shortcode_GenerateSitemap');

The shortcode_atts() function assigns default values to parameters when required. The PHP extract() function then converts each array value into the real variables $title, $id and $depth.

(Note array(...) can be replaced with the shorter [...] syntax if you are using PHP5.4 or above.)

Add a [sitemap] shortcode to any post or page and optionally change the parameters, e.g. [sitemap depth=5].

Nested BBCode Shortcodes

BBCode (Bulletin Board Code) is a lightweight markup format which, like standard shortcodes, uses [square brackets] to denote commands. This permits shortcodes to contain text content or be nested within each other.

Presume your pages require pull quotes and general purpose call-to-action buttons. It would be impractical to create a single shortcode especially when a button could be used on its own or embedded within a quote. We could require HTML such as:

<blockquote>
  <p>Everything we do is amazing!</p>
  <p><a href="/contact-us/" class="cta button main">Call us today</a></p>
</blockquote>

It would could get this wrong when the editor was intimately familiar with HTML. Fortunately, shortcodes provide an easier route, e.g.

[quote]
  Everything we do is amazing!
  [cta type='main']Call us today[/cta]
[/quote]

The content between the tags is passed to the shortcode function as the second argument. We can create two shortcodes functions:

// [quote] shortcode
function shortcode_Quote($params = array(), $content) {

  // default parameters
  extract(shortcode_atts(array(
    'type' => ''
  ), $params));

  // create quote
  return
    '<blockquote' .
    ($type ? " class=\"$type\"" : '') .
    '>' .
    do_shortcode($content) .
    '</blockquote>';
}
add_shortcode('quote', 'shortcode_Quote');


// [cta] shortcode
function shortcode_CallToAction($params = array(), $content) {

  // default parameters
  extract(shortcode_atts(array(
    'href' => '/contact-us/',
    'type' => ''
  ), $params));

  // create link in button style
  return
    '<a class="cta button' .
    ($type ? " $type" : '') .
    '">' .
    do_shortcode($content) .
    '</a>';
}
add_shortcode('cta', 'shortcode_CallToAction');

Note the use of do_shortcode($content) function which applies further shortcodes to the content when they exist.

Shortcodes are easy to implement and can be changed or enhanced quickly. I recommend creating a shortcode cheatsheet with examples so editors have a reference when complex functionality is required.

If you’re looking for somewhere to host your WordPress site after you’ve got your shortcodes all figured out, take a look at our partner, SiteGround. They offer managed WordPress hosting, with one-click installation, staging environments, a WP-CLI interface, pre-installed Git, autoupdates, and more!