Table of Contents
But what happens when a plugin doesn’t exist for the specific, custom content you need? The answer is to create your own. This guide provides a comprehensive, 7-step process for professionals, agencies, and curious creators who want to learn how to build their own custom shortcodes. We will cover everything from the basic “Hello, World!” to advanced, attribute-driven shortcodes, all while following modern WordPress best practices.
Key Takeaways
Before we dive into the code, here are the essential takeaways you should know about creating shortcodes in WordPress:
- What a Shortcode Is: A shortcode is a WordPress-specific macro. It’s a small piece of text in brackets, like [current_year], that WordPress replaces with dynamic content (like “2025”) when the page is loaded.
- The Golden Rule: return, Don’t echo: The number one mistake beginners make is using echo inside a shortcode function. This will print the data at the top of your page, out of order. Your function must return the final HTML or text as a string.
- The Best Place for Your Code: Never add custom code snippets to your theme’s functions.php file. If you change themes, your shortcodes will break. The professional method is to use a site-specific plugin, which is a simple plugin you create to hold all your site’s custom code.
- The 7 Core Steps: The process is straightforward:
- Decide where your code will live (a site-specific plugin).
- Create that plugin file.
- Write the PHP function that generates your content.
- Register your shortcode tag with add_shortcode().
- Test it in the editor.
- Add attributes ($atts) to make it flexible.
- Handle enclosing content ($content) for wrapper shortcodes.
- Shortcodes vs. Modern Builders: For visual layout and design (like buttons, columns, or styled sections), shortcodes are an outdated, clunky method. A modern visual builder like Elementor provides a faster, more intuitive, “drag-and-drop” workflow.
- The Modern Use for Shortcodes: Shortcodes are not dead. They are perfect for embedding dynamic content or plugin functionality (like a form or a product grid) into a page.
- Elementor Loves Shortcodes: Modern page builders like Elementor fully embrace shortcodes. They provide a dedicated “Shortcode” widget, allowing you to visually place your custom shortcode (or a plugin’s shortcode) anywhere in your design.
What is a WordPress Shortcode?
At its simplest, a shortcode is a shortcut. It’s a small, human-readable tag enclosed in square brackets that WordPress is trained to recognize. When WordPress renders a page, it scans the content for these bracketed tags. When it finds one, it stops, replaces that tag with the output of a specific PHP function, and then continues.
Think of it as a mail-merge field for your website. You write [user_name] in the editor, but your visitor sees “Hello, Jane!” on the frontend. The shortcode is the bridge between that simple tag and the complex code required to find and display the user’s name.
This system is what powers thousands of plugins. When you install a contact form plugin and it tells you to add [my_contact_form] to your page, you are using its shortcode.
A Deeper Dive: How Shortcodes Actually Work
The magic behind this system is the Shortcode API. This is a set of functions built into the WordPress core that developers can use to create their own shortcuts.
The entire process works in two parts:
- Registration: A developer uses a function called add_shortcode(). This function tells WordPress, “Hey, if you ever see the tag [my_tag], I want you to run this specific PHP function.”
- Execution: When a visitor loads a page, WordPress runs the content through a filter called do_shortcode(). This filter’s job is to scan the text, find all registered shortcode tags, run their corresponding functions, and replace the tags with whatever string of HTML or text those functions return.
This is a brilliant system because it hides complexity. Your content editor remains clean, holding just the simple [my_tag], while all the messy HTML and PHP logic is tucked away in a plugin file where it belongs.
The Two Main Types of Shortcodes
You will encounter two different syntaxes for shortcodes.
1. Self-Closing Shortcodes
This is the most common type. It’s a single tag that stands on its own. It’s used to insert a self-contained piece of content.
Syntax:
[my_shortcode]
Examples:
-
[current_year] – Inserts “2025”.
-
[latest_posts_gallery] – Inserts a gallery of images.
-
[main_contact_form] – Inserts a form.
2. Enclosing Shortcodes
This type acts as a wrapper. It has an opening tag and a closing tag, and it modifies the content between them.
Syntax: [my_shortcode]This is the content.[/my_shortcode]
Examples:
- [alert_box type=”warning”]This is a warning![/alert_box] – Wraps the text in a styled warning box.
- [collapsible_text title=”Click to Read More”]This content is hidden.[/collapsible_text] – Hides the content inside a toggle.
- [private_content]This is only for members.[/private_content] – Hides the content from non-logged-in users.
We will learn how to build all of these, starting with the simplest.
Before You Start: Do You Even Need a Custom Shortcode?
As a web creation professional with years of experience, I can tell you that the most common mistake is building something you don’t need to. Before you write a single line of code, you must ask: Is a custom shortcode the right tool for this job?
The “Plugin Ecosystem” Solution
First, 90% of the time, a plugin already exists for what you want to do.
- Need a contact form? Don’t build a shortcode. Use a plugin like Contact Form 7 or WPForms.
- Need an image gallery? Use a gallery plugin or the built-in WordPress block.
- Need to sell products? WooCommerce provides a massive library of shortcodes like [products] and [add_to_cart].
Always search for an existing, well-supported plugin first. It’s faster, more secure, and maintained by other developers, saving you time.
The Modern Alternative: Visual Website Builders
Second, if your goal is to design a layout or styled element (like a custom button, a styled pricing table, or a “call to action” box), a shortcode is the wrong tool.
This was the “old way” of doing things. We used to write clunky shortcodes like this: [button link=”/contact” color=”blue” size=”large”]Click Here![/button]
This is terrible for a user. They can’t see what the button looks like. They have to remember all the attribute names. It’s slow and frustrating.
This entire workflow has been made obsolete by modern visual website builders. A platform like Elementor replaces this clunky-text-based system with a fast, intuitive, visual one.
Instead of writing that shortcode, you now:
- Drag a “Button” widget from the panel onto your page.
- Visually change the color with a color picker.
- Type the text directly on the button.
- See the final result in real-time.
This visual workflow is infinitely superior for design and layout. You get pixel-perfect control without writing a single line of code or remembering a single shortcode tag.
When to Create Your Own Shortcode
So, if plugins handle most features and builders handle most designs, when do you create your own?
You build a custom shortcode when you have a specific, custom piece of dynamic data that needs to be easily inserted into your content.
Good examples of custom shortcodes:
- [current_year] – To automatically update your copyright footer.
- [business_phone] – To display a phone number. If the number changes, you only update it in one place (the function) and it updates on all 50 pages where it’s used.
- [user_first_name] – To greet a logged-in user by their name.
- [custom_post_query type=”event” count=”3″] – To show a list of the 3 most recent “Event” custom posts.
See the pattern? Shortcodes are for dynamic content macros, not for visual design.
How to Create a Shortcode in WordPress: The 7-Step Guide
Ready to build? Let’s go through the entire process, from start to finish, using professional best practices.
Step 1: Decide Where Your Code Will Live (The Right Way)
You have three places to add PHP code to your site. Two are wrong.
- Option 1 (The Bad Way): functions.php Almost every beginner tutorial tells you to paste your code into your theme’s functions.php file. Do not do this. It’s a terrible habit. This file is theme-dependent. The moment you or your client decides to change themes, your site will break. All your custom shortcodes will vanish, and your pages will fill with ugly, un-rendered [bracket_tags].
- Option 2 (The Easy Way): A “Code Snippets” Plugin For most users, this is a great option. A plugin like “Code Snippets” gives you a simple admin menu to add and manage PHP snippets. It’s like a functions.php file that isn’t tied to your theme. It’s safe, easy, and you can toggle snippets on and off.
- Option 3 (The Best Way): A Site-Specific Plugin This is the professional method. You create a tiny, one-file plugin that exists for one reason: to hold your site’s custom code. It’s theme-independent, faster than a snippets plugin, and it’s the standard for professional WordPress development. It sounds hard, but it’s incredibly easy. We’ll do this in Step 2.
Step 2: Create Your Site-Specific Plugin
This will take you 60 seconds.
- On your computer’s desktop, create a new folder. Name it my-custom-shortcodes.
- Inside that folder, create a new file. Name it my-custom-shortcodes.php.
- Open this new file in a plain text editor (like Notepad or VS Code).
Copy and paste the following code into it:
<?php
/**
* Plugin Name: My Custom Shortcodes
* Plugin URI: [https://example.com/](https://example.com/)
* Description: Holds all custom shortcodes and functions for my site.
* Version: 1.0.0
* Author: Your Name
* Author URI: [https://example.com/](https://example.com/)
* License: GPL v2 or later
* License URI: [https://www.gnu.org/licenses/gpl-2.0.html](https://www.gnu.org/licenses/gpl-2.0.html)
*/
// Exit if accessed directly.
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
// All of our shortcode functions will go below this line
// …
- This “header comment” is what WordPress reads to understand that this file is a plugin.
- Save the file.
- Go back to your desktop. Right-click the my-custom-shortcodes folder and compress it into a .zip file.
- In your WordPress dashboard, go to Plugins > Add New > Upload Plugin.
- Upload the .zip file you just created and click “Activate”.
That’s it. You now have a custom plugin. Any code you add to that .php file will run on your site. You can edit it from Plugins > Plugin File Editor (select “My Custom Shortcodes” from the dropdown).
Step 3: Write Your Shortcode’s PHP Function
Now for the fun part. Let’s create our first shortcode: [current_year].
We need a PHP function that does one thing: get the current year and return it.
In your plugin file (my-custom-shortcodes.php), add the following code below the header:
// — [current_year] Shortcode —
/**
* 1. The Shortcode Function
*
* This is the function that will run when the [current_year] shortcode is used.
* It returns the current four-digit year as a string.
*/
function my_current_year_function() {
// Get the current year in ‘YYYY’ format
$year = date(‘Y’);
// IMPORTANT: You must return the value. Do not echo it.
return $year;
}
That’s our logic. It’s a simple function that gets the year and returns it. Notice the detailed comments. Always comment on your code.
Step 4: Register Your Shortcode with WordPress
Our function exists, but WordPress doesn’t know about it. We need to “register” it and tie it to a shortcode tag. We do this with the add_shortcode() function.
But we can’t just call this function anywhere. We need to hook it into WordPress’s initialization process to ensure it loads at the right time. We use add_action( ‘init’, … ) for this.
Add this code below the function you just wrote:
/**
* 2. The Shortcode Registration
*
* This function registers all of our shortcodes.
* We hook it into the ‘init’ action.
*/
function my_register_shortcodes() {
// add_shortcode( ‘tag’, ‘function_name’ );
add_shortcode( ‘current_year’, ‘my_current_year_function’ );
// You can register more shortcodes here
// add_shortcode( ‘business_phone’, ‘my_phone_function’ );
}
// 3. Hook the registration function into WordPress
add_action( ‘init’, ‘my_register_shortcodes’ );
Let’s review the full code for your my-custom-shortcodes.php file so far:
<?php
/**
* Plugin Name: My Custom Shortcodes
* … (rest of header) …
*/
// Exit if accessed directly.
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
// — [current_year] Shortcode —
/**
* 1. The Shortcode Function
* This function returns the current four-digit year.
*/
function my_current_year_function() {
$year = date(‘Y’);
return $year;
}
/**
* 2. The Shortcode Registration Function
* This function registers all of our shortcodes.
*/
function my_register_shortcodes() {
// [current_year]
add_shortcode( ‘current_year’, ‘my_current_year_function’ );
}
// 3. Hook into WordPress
add_action( ‘init’, ‘my_register_shortcodes’ );
Save your plugin file. The shortcode is now live.
Step 5: Test Your Shortcode
This is the easiest step.
- Go to Pages > Add New.
- In the content editor, type: This website is copyright 2010 – [current_year]. All rights reserved.
- Click “Preview”.
You will see: “This website is copyright 2010 – 2025. All rights reserved.”
It works! You’ve successfully created a dynamic, self-updating copyright date.
How to use it in different editors:
- Gutenberg (Block Editor): You can type it directly, or you can add the “Shortcode” block and paste [current_year] into it.
- Classic Editor: Type it directly into the text editor.
- Elementor: Drag the “Shortcode” widget onto your page and paste [current_year] into the settings box. You can also use the “Text Editor” widget and type it in there.
Step 6: Level Up: Adding Attributes (atts)
Our [current_year] shortcode is simple. But what if we want to make it flexible? Let’s create a new shortcode that greets a user by name.
We want it to work like this:
- [welcome] -> “Hello, Valued Visitor! Welcome.”
- [welcome user=”Itamar”] -> “Hello, Itamar! Welcome.”
The user=”Itamar” part is an attribute. WordPress passes all attributes to our function as an array, which is conventionally named $atts.
We use a core function called shortcode_atts() to merge the user’s provided attributes with a set of defaults. This is a crucial best practice.
Let’s add this new shortcode to our plugin:
// — [welcome] Shortcode —
/**
* 1. The [welcome] Shortcode Function
* Greets a user with flexible attributes.
*
* @param array $atts User-provided attributes.
* @return string The welcome message HTML.
*/
function my_welcome_message_function( $atts ) {
// 2. Set default attributes
// This merges user-provided atts with defaults.
$atts = shortcode_atts( array(
‘user’ => ‘Valued Visitor’,
‘show_icon’ => ‘false’,
), $atts, ‘welcome’ ); // 3rd param is the shortcode tag, good practice.
// 3. Sanitize and prepare variables
// ALWAYS sanitize user input for security.
$user_name = esc_html( $atts[‘user’] );
$icon = ”; // Start with an empty string
if ( $atts[‘show_icon’] === ‘true’ ) {
// You could add an <svg> or <img> tag here
$icon = ‘<span class=”welcome-icon”>👋</span> ‘;
}
// 4. Build the HTML output
$message = ‘<p class=”welcome-message”>’;
$message .= $icon;
$message .= ‘Hello, ‘ . $user_name . ‘! Welcome to our site.’;
$message .= ‘</p>’;
// 5. Return the final HTML string
return $message;
}
// Now, add it to our registration function:
function my_register_shortcodes() {
// [current_year]
add_shortcode( ‘current_year’, ‘my_current_year_function’ );
// [welcome]
add_shortcode( ‘welcome’, ‘my_welcome_message_function’ );
}
// The add_action(‘init’, …) is already at the bottom
What we did:
- The function now accepts a parameter: $atts.
- We used shortcode_atts() to define our defaults: user is ‘Valued Visitor’.
- We used esc_html() to sanitize the input. This is critical for security. It strips out any malicious HTML or scripts a user might try to pass into the attribute.
- We built an HTML string ($message) and returned it.
Now you can test it:
- [welcome] -> <p class=”welcome-message”>Hello, Valued Visitor! Welcome to our site.</p>
- [welcome user=”Itamar”] -> <p class=”welcome-message”>Hello, Itamar! Welcome to our site.</p>
- [welcome user=”Jane” show_icon=”true”] -> <p class=”welcome-message”><span class=”welcome-icon”>👋</span> Hello, Jane! Welcome to our site.</p>
Step 7: Master Class: Handling Enclosing Shortcodes
Finally, let’s create an enclosing shortcode, like [box_alert]…[/box_alert].
This type of function accepts a second parameter, conventionally named $content. This variable holds everything that’s between the opening and closing tags.
Let’s make a
[box_alert] shortcode that can be a “warning” or “info” box. Usage: [box_alert type=”warning”]This is a dangerous action.[/box_alert]
Here’s the code to add to your plugin:
// —
[box_alert] Shortcode —
/**
* 1. The [box_alert] Shortcode Function
* Wraps content in a styled alert box.
*
* @param array $atts User-provided attributes.
* @param string $content The content between the opening and closing tags.
* @return string The alert box HTML.
*/
function my_box_alert_function( $atts, $content = null ) {
// 2. Set default attributes
$atts = shortcode_atts( array(
‘type’ => ‘info’, // Default type is ‘info’
), $atts, ‘box_alert’ );
// 3. Sanitize attributes
$safe_type = esc_attr( $atts[‘type’] ); // ‘info’ or ‘warning’
// 4. Process the inner content
// This is a crucial step!
// wpautop: Adds <p> tags, just like the normal WordPress editor.
// do_shortcode: Allows other shortcodes to work INSIDE this one.
$processed_content = do_shortcode( wpautop( $content ) );
// 5. Build the HTML output
$html = ‘<div class=”alert-box alert-‘ . $safe_type . ‘”>’;
$html .= $processed_content; // Add the processed content
$html .= ‘</div>’;
// 6. Return the final HTML string
return $html;
}
// And add to registration:
function my_register_shortcodes() {
// [current_year]
add_shortcode( ‘current_year’, ‘my_current_year_function’ );
// [welcome]
add_shortcode( ‘welcome’, ‘my_welcome_message_function’ );
// [box_alert]
add_shortcode( ‘box_alert’, ‘my_box_alert_function’ );
}
// The add_action(‘init’, …) is already at the bottom
Key new concepts:
-
$content = null: The function now accepts a second parameter.
-
$processed_content = do_shortcode( wpautop( $content ) );: This line is vital.
-
wpautop( $content ) takes the plain text from the editor and adds paragraph tags, just like WordPress normally does.
-
do_shortcode( … ) scans the inner content for other shortcodes. This allows users to “nest” shortcodes, like: [box_alert type=”warning”][welcome user=”Admin”][/box_alert]
.
To make this look good, you’d need to add a bit of CSS to your site (e.g., in Appearance > Customize > Additional CSS):
.alert-box {
padding: 15px;
margin-bottom: 20px;
border: 1px solid transparent;
border-radius: 4px;
}
.alert-info {
color: #31708f;
background-color: #d9edf7;
border-color: #bce8f1;
}
.alert-warning {
color: #8a6d3b;
background-color: #fcf8e3;
border-color: #faebcc;
}
A Complete, Copy-Paste Site-Specific Plugin Template
Here is the complete, final code for your my-custom-shortcodes.php plugin file. It contains all three of our examples, fully commented and ready to go.
<?php
/**
* Plugin Name: My Custom Shortcodes
* Plugin URI: [https://example.com/](https://example.com/)
* Description: Holds all custom shortcodes and functions for my site.
* Version: 1.0.0
* Author: Your Name
* Author URI: [https://example.com/](https://example.com/)
* License: GPL v2 or later
* License URI: [https://www.gnu.org/licenses/gpl-2.0.html](https://www.gnu.org/licenses/gpl-2.0.html)
*/
// Exit if accessed directly.
if ( ! defined( ‘ABSPATH’ ) ) {
exit;
}
/**
* —————————————————————-
* Master Registration Function
* —————————————————————-
* All shortcodes are registered here.
* This is hooked into ‘init’.
*/
function my_register_all_shortcodes() {
// [current_year]
add_shortcode( ‘current_year’, ‘my_current_year_function’ );
// [welcome user=”Guest” show_icon=”false”]
add_shortcode( ‘welcome’, ‘my_welcome_message_function’ );
// [box_alert type=”info”]…[/box_alert]
add_shortcode( ‘box_alert’, ‘my_box_alert_function’ );
}
add_action( ‘init’, ‘my_register_all_shortcodes’ );
/**
* —————————————————————-
* Shortcode Function: [current_year]
* —————————————————————-
* A simple self-closing shortcode.
* Returns the current 4-digit year.
*
* @return string The current year.
*/
function my_current_year_function() {
$year = date(‘Y’);
return $year;
}
/**
* —————————————————————-
* Shortcode Function: [welcome]
* —————————————————————-
* A self-closing shortcode with attributes.
*
* @param array $atts User-provided attributes (e.g., user=”Itamar”).
* @return string The welcome message HTML.
*/
function my_welcome_message_function( $atts ) {
// 1. Merge user attributes with defaults
$atts = shortcode_atts( array(
‘user’ => ‘Valued Visitor’,
‘show_icon’ => ‘false’,
), $atts, ‘welcome’ );
// 2. Sanitize and prepare variables
$user_name = esc_html( $atts[‘user’] );
$icon = ”;
if ( $atts[‘show_icon’] === ‘true’ ) {
$icon = ‘<span class=”welcome-icon”>👋</span> ‘;
}
// 3. Build the HTML output
$message = ‘<p class=”welcome-message”>’;
$message .= $icon;
$message .= ‘Hello, ‘ . $user_name . ‘! Welcome to our site.’;
$message .= ‘</p>’;
// 4. Return the final HTML string
return $message;
}
/**
* —————————————————————-
* Shortcode Function: [box_alert]
* —————————————————————-
* An enclosing shortcode with attributes.
*
* @param array $atts User-provided attributes (e.g., type=”warning”).
* @param string $content The content between the tags.
* @return string The alert box HTML.
*/
function my_box_alert_function( $atts, $content = null ) {
// 1. Merge user attributes with defaults
$atts = shortcode_atts( array(
‘type’ => ‘info’, // ‘info’ or ‘warning’
), $atts, ‘box_alert’ );
// 2. Sanitize attributes
$safe_type = esc_attr( $atts[‘type’] );
// 3. Process the inner content
// This allows nested shortcodes and adds <p> tags.
$processed_content = do_shortcode( wpautop( $content ) );
// 4. Build the HTML output
$html = ‘<div class=”alert-box alert-‘ . $safe_type . ‘”>’;
$html .= $processed_content; // Add the processed content
$html .= ‘</div>’;
// 5. Return the final HTML string
return $html;
}
// — End of Plugin —
Debugging: What to Do When Your Shortcode Doesn’t Work
It’s going to happen. You’ll save your file, refresh the page, and… it’s broken. Here’s how to fix it.
Problem: It’s Not Working at All (It’s Just Showing the [bracket_text])
This means WordPress doesn’t recognize your shortcode.
- Check 1: Is your site-specific plugin activated in the Plugins menu? This is the most common issue.
- Check 2: Did you spell the tag correctly in add_shortcode( ‘my_tag’, … )?
- Check 3: Does the tag in your post exactly match the tag you registered? [my_tag] and [mytag] are different.
- Check 4: Is your add_shortcode() call hooked into init?
Problem: It’s Printing at the Top of the Page (Out of Order)
You are echo‘ing, not return‘ing. This is the number one mistake. Your function must collect all of its output into a single string variable (e.g., $html) and then, at the very end, have return $html;. If you use echo, PHP prints it immediately, before the rest of the page HTML is ready.
Problem: It’s Breaking the Page (White Screen of Death)
You have a fatal PHP error. This is usually a simple syntax mistake.
- Did you forget a semicolon ; at the end of a line?
- Did you forget a closing bracket } or parenthesis )?
- Did you misspell a function name? You’ll need to enable WP_DEBUG in your wp-config.php file to see the exact error message, or check your server’s error logs.
Problem: My Enclosing Shortcode Isn’t Showing Its Content
- Did you forget to add $content = null as the second parameter to your function?
- Did you forget to actually use the $content variable in your return string? (e.g., $html .= $processed_content;).
The Modern WordPress: Shortcodes vs. Blocks vs. Widgets
Understanding shortcodes is key, but it’s also crucial to know where they fit in today’s WordPress ecosystem.
- Shortcodes (The Past): These are legacy, but still vital. They are perfect for macros and dynamic data (like [current_year]). They are terrible for layout and design.
- Gutenberg Blocks (The Present): A “Block” is the modern, native WordPress version of a shortcode. It’s a “shortcode on steroids.” It has a rich visual interface right in the editor, uses JavaScript (React), and provides a much better user experience. However, building a custom block is 100x more complex than building a shortcode and requires a totally different skillset (JavaScript, Node.js, etc.).
- Elementor Pro Widgets (The Professional’s Present): For professionals, the Elementor workflow is the most efficient. Instead of writing PHP for a shortcode, you can often achieve the same result with Dynamic Tags. For example, to make a “Hello, Itamar!” welcome message, you don’t need a shortcode. You just add a Heading widget, click “Dynamic Tags,” and select “User Info” > “User First Name.” This is a “no-code” way to accomplish the same dynamic-content goal.
My Expert Recommendation
As a web creation expert, my advice is to follow a clear hierarchy. As I, Itamar Haim, often tell my clients: “First, use your visual builder’s (like Elementor) built-in widgets and dynamic features. They are the fastest, most stable solution. Second, for specialized features, find a dedicated, high-quality plugin from the repository. Only as a last resort, for truly custom, dynamic data that a plugin can’t handle, should you write your own shortcode.”
And when you do need to use a shortcode (from a plugin or one you built), the Elementor “Shortcode” widget is the perfect way to place it. You get the full visual, drag-and-drop power of Elementor to control the layout, and you can place your dynamic shortcode “macro” right where it needs to go. It’s the best of both worlds.
Conclusion: The Enduring Value of the Shortcode
Shortcodes are a fundamental part of WordPress’s DNA. While modern visual builders have (rightfully) taken over their role for layout and design, the Shortcode API remains a simple, powerful, and accessible tool for any developer.
You now have the complete, professional workflow. You know why you should (and shouldn’t) build a shortcode. You know how to build one safely in a site-specific plugin. And you understand how to create all three types: simple, attribute-based, and enclosing. This is a powerful skill that will serve you well in your WordPress journey.
Frequently Asked Questions (FAQ)
1. What’s the difference between a shortcode and a widget? A “widget” traditionally refers to a block of content you add to a sidebar or footer via the Appearance > Widgets admin screen. A “shortcode” is a tag you insert directly into your page or post content. The lines are blurred now, as builders like Elementor also call their drag-and-drop items “widgets.”
2. Can I use shortcodes in Elementor? Yes, absolutely. Elementor has a dedicated “Shortcode” widget. You can drag this widget anywhere on your page and paste any shortcode (from a plugin or your custom one) into its settings. You can also type shortcodes into the “Text Editor” or “Heading” widgets.
3. Can I use shortcodes in my theme’s header or footer? Yes, but you can’t type the [my_tag] directly into the theme’s .php files. In your PHP template files (like header.php), you must use the do_shortcode() function: <?php echo do_shortcode( [my_shortcode]’ ); ?> If you use Elementor Pro, you can build your header and footer visually with the Theme Builder and just drop the Shortcode widget in.
4. Is it safe to create my own shortcodes? It is safe if you follow two rules: 1. return your content, don’t echo it. 2. Always sanitize user-provided data from $atts using functions like esc_html() (for text) and esc_attr() (for HTML attributes) to prevent security issues.
5. Why is my shortcode showing as plain text? This means it’s not being registered correctly. Check that your plugin is active, you spelled the shortcode tag correctly in your post, and that your add_shortcode() function is spelled correctly and hooked into init.
6. Can I nest shortcodes? Yes, but only if the parent shortcode is built to support it. As we saw in Step 7, the parent function must run its $content through the do_shortcode() function (e.g., return do_shortcode( $content );).
7. What is the best way to add CSS for my shortcode? You have a few good options.
- For simple sites: Add it to Appearance > Customize > Additional CSS. This is the easiest.
- For themes: Add it to your child theme’s style.css file.
- For plugins (The “Pro” way): Your site-specific plugin can have its own stylesheet (my-shortcodes.css) and “enqueue” it, so the CSS only loads on pages where it’s needed. This is more advanced but better for performance.
8. What is shortcode_atts()? It’s a helper function from WordPress. It safely merges the user-provided attributes (the $atts array) with your array of default values. It’s the proper way to set default values for your attributes.
9. Should I put my shortcode in functions.php or a plugin? A plugin. Always a plugin. Use a “Code Snippets” plugin for an easy UI, or create your own “site-specific plugin” (as we did) for the most professional and stable solution. Never use your theme’s functions.php file for critical, theme-independent functionality.
10. Are shortcodes outdated? No. Their role has changed. They are no longer for page layout. They are for inserting dynamic data or application-like features (from plugins) into your content. The feature itself is alive and well, and a core part of the WordPress ecosystem. You can even get a free download of WordPress to start practicing.
Looking for fresh content?
By entering your email, you agree to receive Elementor emails, including marketing emails,
and agree to our Terms & Conditions and Privacy Policy.