The ‘No Foo’ Guide to Writing WordPress Shortcodes

Let’s get rid of the ‘foo bar’ rubbish and use real human words to learn how to make WordPress shortcodes. This guide to writing shortcodes starts with basic examples and gradually builds up to more complex ones. The example shortcodes are written to be easy to adapt to your own needs.

Code examples used in this guide are displayed first without explanatory comments then again with comments that explain the PHP code. This is so you can see the code clearly the first time you see it.

Need to brush up on your PHP? There is a quick one page human guide to PHP here.

Code examples can be used in a website by either pasting it into a custom functions plugin or by pasting it into a child theme’s functions.php file. Code added to a custom functions plugin will outlive the theme when the theme is changed. I recommend the custom functions plugin.

Looking for something more advanced? Part two is here.

The shortcode hook

The WP hook we use to make a shortcode is add_shortcode().

The add_shortcode() hook takes two arguments:

  1. The name of the shortcode, and
  2. The function to call when the shortcode is used
add_shortcode( 'shortcode_name', 'function_to_execute' );

That example usage add_shortcode() is easy to understand:

  1. It creates a shortcode called [shortcode_name]
  2. The output of function_to_execute will display wherever [shortcode_name] is used

We need to write a function or use an existing function to make the above example do something when the shortcode is used. We will start by making a function that says ‘Hello’.

The ‘Hello’ shortcode

This shortcode prints ‘Hello’ wherever it is used in a page, post or widget.

function vr_hello() {
    $output = 'Hello';
    return $output;
}
add_shortcode( 'hello', 'vr_hello');

The function add_shortcode( ‘hello’, ‘vr_hello’ ) creates a shortcode called [hello] that returns the output of the function vr_hello().

Notice that we ‘return‘ the output and do not ‘echo’ or ‘print’ the output of the function. WordPress handles the display of the output when the shortcode is used. Unexpected display behaviour could occur if we echo or print the output instead of returning the output to wherever it is called into use.

Here is the code for the [hello] shortcode again. This time there are explanatory comments.

// Write the function that will be executed when the [hello] shortcode is used
function vr_hello() {

    // Add some code to run
    $output = 'Hello';

    // Return the code to wherever it is called
    return $output;

}

// Use add_shortcode() to make a shortcode to represent the vr_hello() function
add_shortcode( 'hello', 'vr_hello');
// Whenever the [hello] shortcode is used, the shortcode tag will be replaced
// by the output of the vr_hello() function.

The ‘Hello Whoever’ shortcode

Shortcodes can accept input through attributes. A shortcode that accepts attributes looks like [shortcode attribute=”input”].

This next shortcode lets us add a person’s name after ‘Hello’. In technical jargon we might say ‘This shortcode accepts an attribute for the name of whoever we are saying hello to’.

function vr_hello_whoever( $atts ) {

    $atts = shortcode_atts(
          array(
             'name' => ''
          ), $atts
        );

    $name = $atts['name'];

    $output = 'Hello ' . $name;
    return $output;
}
add_shortcode( 'hello', 'vr_hello_whoever');

This time when [hello] is used we can add a name. Writing [hello name=’Lee’] will return ‘Hello Lee’.

The code looks more complex than it is. Here is the same code with explanatory comments

// Create a function name so we can call a block of code into add_shortcode()
// Notice the function has an argument called $atts e.g. vr_hello_whoever( $atts )
function vr_hello_whoever( $atts ) {

    // Pass the $atts into the function shortcode_atts()
    // This filters the $atts array into a new $atts array
    $atts = shortcode_atts(
          array(

             // List each attribute alongside its default value
             // e.g. 'attribute_name' => 'default value'
             'name' => ''

          // Repeat the name of the $atts array and say the name of the shortcode
          // This repopulates the $atts array with the filtered data
          ), $atts, 'hello'
        );

    // Create a variable for each item in the $atts array
    // In this instance we have one item in the array i.e. 'name'
    $name = $atts['name'];

    // This is also a good place to sanitize the data to control the output of each variable
    // If we sanitized the data we could replace the above with
    // $name = sanitize_text_field( $atts['name'] );

    // Format the output of this function
    // This is how we want the data to display
    $output = 'Hello ' . $name;

    // Send the output back to wherever it was called i.e. back to our shortcode.
    return $output;
}

// Create the [hello] shortcode to display the output of the vr_hello_whoever() function.
add_shortcode( 'hello', 'vr_hello_whoever');

Information about shortcode_atts() is here in the WordPress Codex.

WordPress input validation, sanitization and escape functions are explained here in the Codex.

Here is a version of the same shortcode that accepts 3 arguments: Name, Age and Gender. Compare the shortcode_attrs() and the list of variables with those used in the first version of the Hello Whoever shortcode.

function vr_hello_whoever( $atts ) {

    $atts = shortcode_atts(
          array(

             'name' => '', // Comma at the end
	     'age' => '', // Comma at the end
	     'gender' => '' // No comma needed for the last item

          ), $atts, 'hello'
        );

    $name = sanitize_text_field( $atts['name'] );
    $age = sanitize_text_field( $atts['age'] );
    $gender = sanitize_text_field( $atts['gender'] );

    $output = "Hello $name, $age, $gender";
    
    return $output;
}
add_shortcode( 'hello', 'vr_hello_whoever');

This shortcode is used as [hello name=”” age=”” gender=””].

The ‘Hello Anything’ shortcode

There are 4 types of shortcode:

  1. Those that accept no attributes
  2. Those that accept attributes
  3. Those that accept content placed between an opening and a closing tag
  4. Those that accept both attributes and content

This time we will make a shortcode that needs a closing tag like this [hello]some text[/hello]

// Create a function that,
// 1) accepts data entered between its opening and closing shortcode tags ($content)
function vr_hello_anything( $atts, $content='' ) {

    // Sanitize $content
    $content = sanitize_text_field( $content );

    // Format the output
    $output = "Hello! $content";
    
    return $output;
}
add_shortcode( 'hello', 'vr_hello_anything');

This shortcode will display any content put between the opening [hello] shortcode and the closing [/hello] shortcode. It will prefix the content with ‘Hello!’.

For example

[hello]What a wonderful day![/hello]

Will output

Hello! What a wonderful day!

The ‘Hello Whoever Anything’ shortcode

This time we will create a shortcode that takes a name attribute and takes whatever is written between its opening and closing tags.

// Create a function that,
// 1) accepts an attribute for 'name' ($atts)
// 2) accepts content placed between the opening and closing shortcode tags ($content)
function vr_hello_whoever_anything( $atts, $content='' ) {

    $atts = shortcode_atts(
          array(

             'name' => '' // No comma needed

          ), $atts, 'hello'
        );

    $name = sanitize_text_field( $atts['name'] );
    // Sanitize $content too
    $content = sanitize_text_field( $content );

    // Format the output
    $output = "Hello $name! $content";
    
    return $output;
}
add_shortcode( 'hello', 'vr_hello_whoever_anything');

For example, the shortcode

[hello name=’John’]What are you doing today?[/hello]

will be replaced with

Hello John! What are you doing today?

We can enhance this shortcode. We could use it to display random greetings to different visitors or we could make it display a tailored message to people who log into the site.

WordPress has functions built into its core code that can be used for retrieving information about a logged in user. WordPress conditional tags can be used to control when and to whom information is displayed.

To recap

A shortcode is exactly what it says in its name: It is a shorthand way to execute a block of code. A shortcode is a user friendly tag for a PHP code block (function).

Shortcode tags are created with the add_shortcode( $shortcode, $function ) function. This function takes two arguments: ‘Shortcode-Name’ and ‘Function-to-Call’. When a shortcode is used in a post, page or widget area, the shortcode tag is replaced by the output of the code called (executed) by that shortcode.

There are 4 types of shortcode: attributeless, attribute takers, content takers, and those that accept both attributes and content. Examples of those types are [hello], [hello name=””], [hello]data[/hello] and [hello name=””]data[/hello].

The function executed when a shortcode is can be written to accept arguments. When arguments are accepted, those arguments determine whether a shortcode will accept attributes ($atts) or content ($content). For example function vr_hello_anything( $atts, $content=” ) { // some code } would accept both attributes and content.

Shortcodes that do not require a closing tag are called ‘self closing’.

Shortcodes that accept content are the shortcodes that need a closing tag when used e.g. [shortcode]Some content[/shortcode].

Functions (code blocks) executed when shortcodes are used should ‘return’ their output and not ‘echo’ or ‘print’ their output.

When two or more shortcodes share the same name tag, the code for the shortcode that is read last by WordPress is the code that the shortcode tag will execute.

If you want the ‘foo bar’ guide to making shortcodes it is in the WordPress Codex.

Learn how to use core WordPress functions in shortcodes and how to fix misbehaving shortcode output in part two of this guide: Turn WordPress Hooks and Functions into Shortcodes.

Over to you

Any complaints, ideas or suggestions? Add them to the comments.

Sharing is caring!

3
Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
Carla

I love your tutorials. I’m using shortcodes for the first time. I’m adding a Mailchimp subscribe form to a subscribe page. It is placed between two paragraphs. The Mailchimp code is in a widget, and I created a widget function and the shortcode. I realized I don’t need add_action or a conditional to tell it where to go, since I can simply place the shortcode where ever I need it to output the subscribe form. But I can’t figure out why it insists on displaying at the top of the page content instead of between the two paragraphs. I’m not… Read more »