How to Create a Custom Shortcode in WordPress

How to Create a Custom Shortcode in WordPress

Ever since the release of WordPress 2.5 shortcodes have been the preferred way of adding custom features and functionalities among plugin and theme developers. By using shortcodes you can add sliders, image galleries, buttons, custom font text, contact forms, and so much more. Despite being very powerful, shortcodes weren’t known for being beginner-friendly, unless they were integrated inside some of the newer and more popular page builders, like Elementor or WPBakery. As such, we are pretty sure most of our readers have already used shortcodes but probably never ventured into creating their own.

Even though coding can seem intimidating to most, the process of creating a shortcode is a lot easier than it seems at first glance. For that reason, we decided to create this article and explain the process in depth. In the sections to come, we will clear up exactly what shortcodes are, how to create them using examples that vary in difficulty, as well as how to use them on various parts of your website. Before we start, we must mention that, depending on your previous WordPress knowledge, additional research might be needed to follow along with and understand the topics discussed. In case you want to, you can use the links below to skip to different parts of this article:

Understanding what custom shortcodes are

WordPress shortcodes are simple code shortcuts, defined with square brackets (such as [shortcode_name]), that perform a predefined function or a set of functions. Depending on the function(s) used, the purpose of a shortcode could be something as small as adding a “Hello world” text or something as substantial as building the content of an entire webpage.

You can classify shortcodes in several different ways. WordPress, by default, has six built-in shortcodes: [ caption ], [ gallery ], [ audio ], [ video ], [ playlist ] and [ embed ]. As those shortcode names are quite self-explanatory, we won’t delve into them at this time. Any other shortcode, created by plugin or theme developers, or yourself, is referred to as a custom one. Another way to classify shortcodes is based on whether the associated function accepts parameters or not. However, they are most often divided into two types: self-closing shortcodes and enclosing shortcodes, based on how you use them. The self-closing shortcodes use only the opening shortcode tag. On the other hand, the enclosing shortcodes require a closing tag as well as the opening one since they utilize the content inserted between those two tags. In practice, they look something like this:

[shortcode_name] – self-closing shortcode

[shortcode_name]Additional content used in the shortcode[/shortcode_name] – enclosing shortcode

In most cases, both types of shortcodes accept parameters defined within the corresponding functions, as you will be able to see from the examples we included in the following section.

Creating custom shortcodes

WordPress’ Shortcode API represents a set of functions that allow a shortcode to be registered, as well as to fetch and parse supplied attributes. Also, while processing a page or post, any registered shortcode tags are replaced with the corresponding output, thanks to the Shortcode API. Therefore, before we delve into creating any specific shortcodes, it is important to understand how to register a shortcode.

To register a shortcode, you have to use the add_shortcode function. The function has two parameters. The first is a unique shortcode tag that represents the name of the shortcode. The second is the name of the handler function (or callback, as it is better known) that is executed after the shortcode is registered. You can see how this code would look like in the example given below:

add_shortcode( 'shortcode_name', 'handler_function_name' );

To clarify, shortcode_name is the unique shortcode tag, while the handler_function_name is the callback function name.

However, registering a shortcode isn’t enough. You need to take one more step, and that is writing the handler function. This function gives your shortcode its purpose.

Here’s a generalized example of the registration of a shortcode and the addition of its corresponding handler function.

function handler_function_name( $atts, $content, $shortcode_tag ){
// Some code goes here
add_shortcode( 'shortcode_name', 'handler_function_name' );

Let us explain this code block in detail.

The name of the callback has to match the second argument of the add_shortcode function (handler_function_name in our example).

Additionally, the callback accepts up to three parameters. The $atts variable represents an associative array of attributes that are passed to the function. This parameter can be omitted if you choose to write a shortcode that doesn’t accept user-inserted attributes. The $content variable is reserved for enclosing type shortcodes, as it represents the content a user inserts between the opening and closing tags of a shortcode. This variable would correspond to the part with this is the user-inserted content in the example given below.

[shortcode_name]this is the user-inserted content[/shortcode_name]

Of course, if you decide to create a self-closing shortcode, this parameter should be omitted.

As for the last parameter, the $shortcode_tag variable represents the shortcode tag, which is the name of the shortcode itself. It is the part with shortcode_name in our example. Of the three parameters, because it is rarely needed, $shortcode_tag is omitted the most. It is only required when two registered shortcodes share the same callback function.

Finally, the part of the code denoted by the comment // Some code goes here is where you should add the code that enables a new feature. Simply replace the comment with your code.

Now that you know what each part of the code does, we can proceed to the examples. You can refer back to this section if at any point you need a reminder of the details of shortcode registration or handler functions and its properties. Additionally, if you want to speed up the process of creating a shortcode, you can try using a shortcode generator. It will help you get a baseline code similar to the one given in our example above so you can build on that.

Qode Themes: Top Picks
Bridge New Banner

Creative Multi-Purpose WordPress Theme

Stockholm WordPress Theme

A Genuinely Multi-Concept Theme

Startit WordPress Theme

Fresh Startup Business Theme

Examples of custom shortcodes

In the following section, we will show and carefully explain three different shortcode examples. Even though the examples vary in difficulty, the one thing they have in common is the return statement. The return tag is mandatory when creating shortcodes, as the return output is what replaces the shortcode tag ([shortcode_name]) when it is used. We will talk in more depth about the use of the shortcodes in the section that comes after this one.

What we strongly suggest, before you try to create a new shortcode, is to backup your website. Any mistake, especially one in syntax, may break your website. As soon as you’ve done that, you can turn to shortcode creation.

You can add the code shown in this section into the functions.php file of your theme. However, it is better if you place the code into a separate file or even create a custom plugin for it. We will touch upon this topic later, as part of the additional tips section.

Example 1:

The most basic example of a shortcode is a self-closing shortcode without parameters. As explained above, the name of the handler function and the second argument of the add_shortcode function have to be the same. Furthermore, the first argument of that same function determines how we use the shortcode, while the string after the return tag determines what you will see on the screen. The date function used in this example returns a date string based on the time format we inserted. The format we used is d-m-Y, standing for day-month-year, expressed numerically in the output. Finally, we have used dots(.), which are string concatenation operators, to join all three strings into one and display it on the webpage.

// Adding a basic custom shortcode that tells the current date
function custom_date_shortcode( ) {
return '<p>The current date is ' . date('d-m-Y') . '.</p>';
add_shortcode( 'current_date', 'custom_date_shortcode' );

Please note, we also used comments and indentation to improve code readability. We encourage you to do the same in any custom shortcodes you make. Having said that, here’s how our current date shortcode looks when used on a website.

Current Date

Example 2:

A slightly more challenging task is creating a self-closing shortcode that accepts arguments that a user can insert. To do so, one of the three parameters of a handler function has to be used, in this case, the $atts variable. In the example below, we chose to showcase a very simple, yet instructional shortcode that explains the various phases of shortcode creation.

// Adding a colored text shortcode
function custom_colored_text( $atts ) {
$default_atts = array(
"title" => '',
"title_color" => ''
$params = shortcode_atts( $default_atts, $atts );
$title_styles = "";
// generate color style
if( ! empty( $params['title_color'] ) ) {
$title_styles .= "color: " . $params['title_color'] . ";";
return '<div class="text-holder"><span class="text-title" style="' . $title_styles . '">' . esc_html( $params['title'] ) . '</span></div>';
add_shortcode( 'colored_text', 'custom_colored_text' );

Since we have explained the parameters of a handler function as well as how a shortcode can be registered in the previous sections, we will not go over it again here. Instead, we will focus on explaining the content of the handler function, one code block at a time. Each of the blocks concerns a different phase in the shortcode creation process, so we gave each appropriate names.

  • Extracting the attributes
$default_atts = array(
"title" => '',
"title_color" => ''
$params = shortcode_atts( $default_atts, $atts );

The first thing you might notice is the $default_atts variable, which is an associative array. We have purposely named it $default_atts, to make it a bit clearer what it refers to. This variable contains all the default values of all the attributes used in the shortcode. Then, thanks to the shortcode_atts function provided by the Shortcode API, the default values are compared with user-inserted values stored into the $atts variable. If a user omits using an attribute of a shortcode, it won’t be stored inside the $atts variable. As the $default_atts array also serves as a list of all available shortcode attributes, a default value corresponding to the omitted shortcode attribute will be used instead. Furthermore, if a user accidentally inserts an invalid shortcode attribute, that attribute will be disregarded thanks to the same function.

With the intention of keeping this example simple, we have only included two possible attributes to this shortcode, both of which have empty strings as the default values. After cross-referencing the attributes and their values using the shortcode_atts function, the result is stored inside the $params variable, which is also an associative array.

  • Interacting with the attributes

Performing certain operations or interacting with the acquired attributes is the main part of creating a shortcode. Depending on the complexity of the shortcode, the length of this section of code can vary substantially. Even so, parts of this section can sometimes be divided into and written as separate semantically-structured functions, which can later be used within the handler function. But, as those are quite advanced and complex examples, we won’t be dealing with them in this article.

Let us examine the code section used in our example.

Firstly, a reader can see that a new variable $title_styles is created and that it is set to an empty string. We will use the same variable within the if block placed below. As we mentioned before, the attributes and their corresponding values are placed within the $params associative array. You can access the corresponding value by using the $params[‘atribute_name’] line of code.

The if block simply states that if the user has added a title_color value, the corresponding CSS string rule will be added to the $title_styles variable. For example, if the title_color value was blue, the $title_styles variable would be equal to “color: blue;”.

$title_styles = "";
// generate color style
if( ! empty( $params['title_color'] ) ) {
$title_styles .= "color: " . $params['title_color'] . ";";
  • Returning the output

Finally, after interacting with the data and performing additional functions, it is time to return the shortcode output. Despite being bigger, the return statement used in this example doesn’t differ greatly from the one used in the previous example, as it also features the string concatenation operator. Nevertheless, two things are different—the mixed-use of double and single quotes as well as the use of an escaping function (esc_html in this example).

The return output string is denoted with single quotes. Therefore, if you need to use quotes within this string, you will need to use double-quotes. Since the mixed-use of single and double quotes can be quite confusing, we advise taking special care here as a misuse of quotes can break your site.

As for the escaping function, it secures the output by removing any unwanted data and prevents cross-site scripting attacks.

return '<div class="text-holder"><span class="text-title" style="' . $title_styles . '">' . esc_html( $params['title'] ) . '</span></div>';

Here’s an example of how this shortcode would look inside a page sidebar.

Text Holder

Example 3:

An even more complex task is creating an enclosing shortcode that accepts user attributes. Apart from the $atts variable, the shortcode also uses the $content variable. Additionally, you can assign a default value to the $content variable within the brackets that define the arguments of the handler function. In the example given below, the default value of the $content variable is set to null.

// Adding a custom button shortcode
function custom_button_shortcode( $atts, $content = null ) {
$default_atts = array(
'text' => '',
'link' => '#',
'target' => '_self',
'color' => '',
'background_color' => '',
'font_size' => '',
'font_weight' => '',
'padding' => '',
'custom_class' => ''
$params = shortcode_atts( $default_atts, $atts );
$button_styles = "";
$button_classes = "custom-btn";
// Creating the button styles
if( ! empty( $params['color'] ) ){
$button_styles .= 'color: '. $params['color'] .'; ';
if( ! empty( $params['background_color'] ) ){
$button_styles .= 'background-color: '. $params['background_color'] .'; ';
if( ! empty( $params['font_size'] ) ){
$button_styles .= 'font-size: '. $params['font_size'] .'; ';
if( ! empty( $params['font_weight'] ) ){
$button_styles .= 'font-weight: '. $params['font_weight'] .'; ';
if( ! empty( $params['padding'] ) ){
$button_styles .= 'padding: '. $params['padding'] .'; ';
// Adding the custom class
if ( ! empty( $params['custom_class'] ) ){
$button_classes .= $params['custom_class'];
return '<div><p>' . esc_html( $content ) . '</p><a itemprop="url" href="' . esc_url( $params['link'] ) . '" target="' . esc_attr( $params['target'] ) . '"' . ' style="' . $button_styles . '" ' . 'class="' . $button_classes . '" >' . esc_html( $params['text'] ) . '</a></div>';
add_shortcode( 'custom_button', 'custom_button_shortcode' );

By comparing the codes from examples 2 and 3, you can see the same structural pattern emerging. Apart from the amount of code, the sections differ very little. Therefore, we will not go into detail regarding each of the three sections once more, instead we will only highlight the most important things.

The same warnings mentioned towards the end of the second example still hold. Meaning, you should take special care when mixing single and double-quotes. Also, try to escape the variables you use in your output as much as possible, for security reasons. We did this in the third example by using esc_html, esc_url, and esc_attr functions. Additionally, as this is an enclosing type shortcode, including the $content variable within the output string is mandatory. We also suggest including a custom class as one of your shortcode attributes. This will allow users to further alter the shortcode by creating custom CSS or JS code snippets to target that custom class.

Here’s an example of how the same shortcode would look placed in a widget inside of a website footer.

Text Widget Inspect

Using custom shortcodes

You can use custom shortcodes in various parts of your website. The easiest way of using your shortcode is by inserting it in one of the widget areas/sidebars. To do so, you only need to add the appropriate shortcode “call” inside a text widget, placed in a widget area of your choice.

In terms of the steps you need to take, first navigate to Appearance > Widgets. Then find the Text widget from the list of Available Widgets on the left side of your screen. Click on the Text widget, select the widget area where you want to add this widget, and press the Add Widget button. Another way of performing the same task is simply by dragging and dropping the Text widget inside the whichever widget area you want.

Appearance Widgets

After inserting the Text widget, click on it to open, and add the appropriate code. Afterward, press the Save button and check the shortcode visual output on your website’s frontend.

Text Shortcode

In the screenshot above, you can see the code for using the custom button we created in our third example.

[custom_button text = 'More here' link = 'some-url-here' target = '_blank' color = 'black' background_color = 'white' font_size = '14px' font_weight = 'bold' padding = '15px 25px'] Stay motivated and succeed [/custom_button]

Since that represents an enclosing shortcode with parameters, it can be the hardest one to use. Thus, let us break down its use carefully.

Firstly, to use it, you have to insert the appropriate opening and closing shortcode tags. Those are [custom_button] and [/custom_button], respectively. Between those two tags, you can see the user-inserted content. That is the Stay motivated and succeed line. Finally, the opening shortcode tag contains the attributes, alongside their corresponding values. They are given as attribute_name = ‘attribute_value’ pairs.

Apart from including the shortcodes inside widgets, you can add them directly to your pages. The required steps depend solely on the page builder plugin you are using. We will mention a few below.

  • WPBakery

To use your shortcode in WPBakery, add a Text Block element to your page and paste the code in the Visual section of the General tab. Click the Save changes button and update the page afterward. Make sure to check the visual output on the frontend as well.

WPBakery Shortcode
  • Elementor

Similarly, you can use the same shortcode within Elementor by adding the Text Editor widget, inside your page. Insert the code in the Visual section and update the page afterward. Make sure to check the visual output on the frontend as well.

Elementor Shortcode
  • Gutenberg

Using your newly created shortcode isn’t much different in Guttenberg, compared to the other page builders. Click on the + sign to add a new block and search for the term Shortcode. Add the Shortcode block to your page and insert the code within it. Then, update the page. Make sure to check the visual output on the frontend as well.

Gutenberg Shortcode

The code we inserted into all three page builders came from our second shortcode example.

[colored_text title='About us' title_color = '#d77a61']

Since it is a self-closing shortcode, it only has an opening shortcode tag with the appropriate shortcode name (colored_text). Additionally, the attributes and their corresponding values are inserted within that tag as attribute_name = ‘attribute_value’ pairs.

Finally, you can use your custom shortcodes within your theme template files using the do_shortcode function. If you choose to do that, you will have to use a line of code in your header.php, footer.php, or any other theme template file that would be similar to this one:

<?php echo do_shortcode("[shortcode_name]"); ?>

However, this practice has fallen out of favor recently, so we suggest that you restrict the use of the do_shortcode function within a custom-made plugin.

Additional tips

Now that you’ve seen how the process of creating a shortcode goes in detail, we can share some additional tips and common practices. Even though these are mostly intended for developers, examining this section can prove useful for any reader interested in building custom shortcodes.

Firstly, we don’t advise adding code to your template files as those changes will get overridden by theme updates. On the same note, we also discourage creating the shortcode within the functions.php file. The reason being is that every time you decide to deactivate that theme, the shortcodes created within the functions.php file will stop working. At the same time, shortcode “calls” are part of your content, and as such are stored in your database. This means your site will contain unrendered shortcodes that will be visible to your users and could confuse or scare them. Therefore, it is best to create a custom plugin and include your shortcode within it.

Additionally, shortcodes will often require you to write custom CSS or JS code that helps with the stylization or provides additional features. It would be best to create separate CSS and JS stylesheet files and enqueue them within the plugin you created using the wp_enqueue_style and wp_enqueue_script functions. Furthermore, we suggest splitting the code into separate functions, if possible. And for easier organization, you should also try to create a distinct structure of files and folders within the directory of your plugin. This structure should correspond to distinct code sections found within your shortcode. Finally, you should try to follow some of the latest naming conventions for the CSS classes included in your output HTML. This will let you write the additional CSS and JS code easily and it will improve the readability of your code as a whole.

Final Thoughts

You can use shortcodes for a wide array of reasons and all across your website. If you are using a theme or plugin that is missing some features you might find useful, then creating shortcodes can supplement that. Shortcodes can add a missing or previously unavailable feature to your website and even improve its functionality substantially. As this is quite an extensive topic, we have tried to cover it in as much detail as possible in this article. We supplied you with examples of increasing difficulty in an effort to cover all the possible steps of the shortcode creation process and provide you with resources to build on. Using these examples, we are confident you will be able to create shortcodes of your own and improve them even further.

Post your comment