• Skip to primary navigation
  • Skip to main content
Sal Ferrarello
  • About Sal Ferrarello
  • Speaking
  • Connect
    Mastodon GitHub Twitter (inactive)
You are here: Home / Programming / WordPress Shortcode
A puzzle with a missing piece

WordPress Shortcode

Last updated on October 30, 2017 by Sal Ferrarello

A WordPress shortcode allows you to define PHP to be executed somewhere in your post content.

jump to resources

The Letter of the Day

Imagine you maintain a WordPress website that includes a letter of the day. One way to maintain such a website would be to log in each day and update the letter. However, I’m a programmer and programmers are lazy so we’re going to find another way.

Display the Letter with PHP

We could certainly write some PHP to determine and echo the letter of the day, as a matter of fact here is my code to do just that.

$alphabet        = range( 'A', 'Z' );     // [ 'A', 'B', ..., 'Z' ].
$day_of_the_year = (int) date( 'z' );     // Day of year from 0 to 365.
$position        = $day_of_the_year % 26; // A digit somewhere from 0 to 25.
echo $alphabet[ $position ];

There are some interesting things going on in this code but since they’re outside of the scope of this article, I’ll just provide you with links to range(), date(), and the modulo operator (%).

I Want it in the Middle

While we could include this code in a WordPress template somewhere before or after our content, if we want it in the middle of our content we have a problem.

The letter of the day is Q. Can you think of some words that start with this letter ?

While we could put this whole line of text in our code, imagine if we had two paragraphs before this and two paragraphs after this. We’re losing the value of a content management system when we’re hard coding all of this information.

A Shortcode to the Rescue

What we really want is to mark a place in our content, where the PHP code should be executed. We want a placeholder like [letter_of_the_day]. We use the square brackets ([ ]) to mark this special area (our shortcode).

The letter of the day is [letter_of_the_day]. Can you think of some words that start with this letter ?

While this is great, it doesn’t do anything yet. We need to add some code to our WordPress install to make this work.

For example adding this code somewhere (e.g. in your theme’s functions.php or in a mu-plugin), associates our shortcode [letter_of_the_day] with our function fe_letter_of_the_day().

add_shortcode( 'letter_of_the_day', 'fe_letter_of_the_day' );
function fe_letter_of_the_day() {
    $alphabet        = range( 'A', 'Z' );     // [ 'A', 'B', ..., 'Z' ].
    $day_of_the_year = (int) date( 'z' );     // Day of year from 0 to 365.
    $position        = $day_of_the_year % 26; // A digit somewhere from 0 to 25.
    return $alphabet[ $position ];
}

and then we get our desired result. Each time WordPress displays this content it will replace [letter_of_the_day] with the result of fe_letter_of_the_day().

Shortcode Function Parameters

When our function is called, it is actually passed three values that we can use: $atts, $content, and $tag.

add_shortcode( 'btn_link', 'fe_btn_link');

function fe_btn_link( $atts, $content = '', $tag ) {
    return '<a href="https://salcode.com/"
        class="btn btn-primary">salcode</a>';
}

This allows us to include [btn_link] in our code and display the markup for a Bootstrap link styled as a button.

$content

When called with a single shortcode tag (e.g. [btn_link] the parameter $content does not have a value). However, we can use shortcode tags in a way similar to HTML tags.

There is lots to see at [btn_link]my website[/btn_link]. Enjoy the view.

Now, the value inside the [btn_link] tags is passed into the $content variable. We can modify our function like the following, defining the text in the button with the content.

function fe_btn_link( $atts, $content = '', $tag ) {
    return '<a href="https://salcode.com/"
        class="btn btn-primary">' . $content . '</a>';
}

my website

sprintf()

We can improve our return statement by using sprintf(), this allows us to insert the $content in place of %s. Using sprintf() is almost like using a shortcode in PHP.

function fe_btn_link( $atts, $content = '', $tag ) {
    return sprintf(
        '<a href="https://salcode.com/" class="btn btn-primary">%s</a>',
        $content
    );
}

$tag

The tag parameter contains the name of the shortcode. In our case, this is btn_link. I generally do not do much with this value other than use it with $atts, which we will look at next.

$atts

The $atts parameter is empty by default. We can pass values into it by including them in the opening shortcode,
e.g. [btn_link href="http://ironco.de"]

In this case, $atts would have a value of

array(
    'href' => 'http://ironco.de',
)

We can pass multiple values in using this method
e.g. [btn_link href="http://ironco.de" class="btn-danger btn-large"]

array(
    'href'  => 'http://ironco.de',
    'class' => 'btn-danger btn-large',
)

Now we can use these values in our function

function fe_btn_link( $atts, $content = '', $tag ) {
    return sprintf(
        '<a href="%s" class="btn %s">%s</a>',
        esc_attr( $atts['href'] ),
        esc_attr( $atts['class'] ),
        $content
    );
}

Notice we’ve wrapped our attributes in esc_attr() before including them in our output for security reasons.

Undefined $atts

The problem that arises here is if the $atts are undefined. However, WordPress gives us a way to define default values with the function shortcode_atts(). This function allows us to define default values that can be overridden by passing them in the shortcode.

function fe_btn_link( $atts, $content = '', $tag ) {

    $atts = shortcode_atts( array(
        'href'  => 'https://salcode.com',
        'class' => 'btn-primary',
    ), $atts, $tag );

    return sprintf(
        '<a href="%s" class="btn %s">%s</a>',
        esc_attr( $atts['href'] ),
        esc_attr( $atts['class'] ),
        $content
    );
}

This code allows us to use https://salcode.com as a default for href, unless it is overwritten with a parameter in the opening shortcode. The same applies for class.

shortcode_atts()

The shortcode_atts() function does a number of cool things.

The first parameter is a key/value array of acceptable keys and their default values. If $atts contains a key that does not appear in this default list, the value is discarded. This allows us to work with a known set of keys in $atts.

The second parameter is the $atts variable received by the function. These are the key/value pairs set in the opening shortcode
(e.g. [btn_link href="http://ironco.de" class="btn-danger btn-large"]).

The third parameter is the shortcode name (a.k.a. tag). This is included because WordPress allows separate code to be written that can modify these values. Including this third parameter is a great way to make your code extensible. For more on extensible code, see Make Your WordPress Plugin Easy to Extend.

Shortcode Tips

When defining your shortcode name (a.k.a. tag) use: lower-case letters, numbers, and underscores (_). The first character should be a letter.

A long time ago it was popular to use extract() in a shortcode – it is now frowned upon. Don’t use it.

Shortcodes should never echo anything. They should always return a string.

Resources

  • Slides to my talk Create Your First Shortcode
  • PHP Code for Letter of the Day
  • add_shortcode() documentation
  • sprintf() documentation
  • shortcode_atts() documentation
  • esc_attr() documentation
  • do_shortcode() documentation
  • My Anchor Shortcode Plugin for WordPress

Photo Credit

Pixabay

Sal Ferrarello
Sal Ferrarello (@salcode)
Sal is a PHP developer with a focus on the WordPress platform. He is a conference speaker with a background including Piano Player, Radio DJ, Magician/Juggler, Beach Photographer, and High School Math Teacher. Sal can be found professionally at WebDevStudios, where he works as a senior backend engineer.

Share this post:

Share on TwitterShare on FacebookShare on LinkedInShare on EmailShare on Reddit

Filed Under: Programming Tagged With: shortcode, WordPress

Reader Interactions

Leave a Reply Cancel reply

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

Copyright © 2023 · Bootstrap4 Genesis on Genesis Framework · WordPress · Log in