Create a Custom WordPress Plugin to Add Shortcodes – Complete Tutorial

Here’s a complete tutorial on how to create a custom WordPress plugin for adding shortcodes. This guide will walk you through setting up the plugin, writing the shortcode function, and activating it on your WordPress site.

Step 1: Create Your Plugin Folder and Main File

  1. Navigate to your WordPress installation’s wp-content/plugins/ directory.
  2. Create a new folder for your plugin. Choose a unique and descriptive name, preferably all lowercase with hyphens for spaces (e.g., my-custom-shortcodes).
    • Example: wp-content/plugins/my-custom-shortcodes/
  3. Inside this new folder, create a PHP file. The name of this file should ideally match your folder name (e.g., my-custom-shortcodes.php). This will be your main plugin file.
    • Example: wp-content/plugins/my-custom-shortcodes/my-custom-shortcodes.php

Step 2: Add the Plugin Header

Open your main plugin file (my-custom-shortcodes.php) and add the following comments at the very top. This header tells WordPress about your plugin and makes it appear in the Plugins list in your admin dashboard.


<?php
/*
Plugin Name: My Custom Shortcodes
Plugin URI:  https://yourwebsite.com/
Description: A simple plugin to add custom shortcodes to your WordPress site.
Version:     1.0.0
Author:      Your Name
Author URI:  https://yourwebsite.com/
License:     GPL2
License URI: https://www.gnu.org/licenses/gpl-2.0.html
Text Domain: my-custom-shortcodes
*/

// Prevent direct access to the file
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

// Your shortcode functions will go below this.

  • Plugin Name: The name that will appear in your WordPress Plugins list.
  • Plugin URI: (Optional) The URL of your plugin’s homepage or documentation.
  • Description: A brief explanation of what your plugin does.
  • Version: The current version number of your plugin.
  • Author: Your name or company name.
  • Author URI: (Optional) Your website or portfolio URL.
  • License & License URI: Standard licensing information (GPL2 is common for WordPress).
  • Text Domain: Important for internationalization (translating your plugin). It should match your plugin folder name.
  • if ( ! defined( 'ABSPATH' ) ) { exit; }: This is a crucial security measure that prevents direct access to your plugin file, ensuring it’s only loaded through WordPress.

Step 3: Define Your Shortcode Function

Now, let’s add the PHP function that will generate the content for your shortcode. This function will be called whenever WordPress encounters your shortcode.

<?php
/*
Plugin Name: My Custom Shortcodes
// ... (rest of your plugin header)
*/

// Prevent direct access to the file
if ( ! defined( 'ABSPATH' ) ) {
    exit; // Exit if accessed directly
}

/**
 * Custom shortcode to display a greeting message.
 *
 * @param array $atts Shortcode attributes.
 * @param string $content Content inside the shortcode.
 * @return string The HTML output for the shortcode.
 */
function my_greeting_shortcode( $atts, $content = null ) {
    // Define default attributes
    $a = shortcode_atts( array(
        'name' => 'Guest', // Default value for 'name' attribute
        'color' => 'blue', // Default value for 'color' attribute
    ), $atts, 'my_greeting' ); // 'my_greeting' is the shortcode tag

    // Sanitize attributes for security
    $name = esc_html( $a['name'] );
    $color = esc_attr( $a['color'] ); // Use esc_attr for HTML attributes

    // Start output buffering to capture HTML
    ob_start();
    ?>
    <div style="color: <?php echo $color; ?>; padding: 10px; border: 1px solid <?php echo $color; ?>; border-radius: 5px;">
        <p>Hello, <?php echo $name; ?>!</p>
        <?php if ( ! empty( $content ) ) : ?>
            <p><?php echo do_shortcode( $content ); ?></p>
        <?php endif; ?>
    </div>
    <?php
    return ob_get_clean(); // Return the buffered content
}

// Register the shortcode
add_shortcode( 'my_greeting', 'my_greeting_shortcode' );

Explanation of the Shortcode Function:

  • my_greeting_shortcode( $atts, $content = null ):
    • This is your custom function. Its name should be unique to avoid conflicts.
    • $atts: An array of attributes passed to the shortcode (e.g., [my_greeting name="John"]).
    • $content: The content enclosed between the opening and closing shortcode tags (e.g., [my_greeting]This is content.[/my_greeting]). If it’s a self-closing shortcode ([my_greeting /]), $content will be null.
  • shortcode_atts(): This very important function merges user-defined attributes with your default attributes. It ensures that if a user doesn’t specify an attribute, your shortcode still has a default value.
    • The third argument ('my_greeting') is the shortcode tag itself, used for filtering.
  • esc_html() and esc_attr(): ALWAYS sanitize any data that comes from user input (like shortcode attributes) before outputting it to the browser. This prevents XSS (Cross-Site Scripting) vulnerabilities.
    • esc_html() for HTML content.
    • esc_attr() for HTML attribute values.
  • ob_start() and ob_get_clean(): For shortcodes that generate a significant amount of HTML, it’s best practice to use output buffering. This captures all the HTML generated within the ob_start() and ob_get_clean() block and returns it as a single string, which is what add_shortcode expects. Without this, your HTML might be printed prematurely.
  • do_shortcode( $content ): If your shortcode allows nested shortcodes within its content, use do_shortcode() to process them.
  • add_shortcode( 'my_greeting', 'my_greeting_shortcode' );: This is the WordPress function that registers your shortcode.
    • The first argument ('my_greeting') is the actual shortcode tag you’ll use in your posts/pages (e.g., [my_greeting]).
    • The second argument ('my_greeting_shortcode') is the name of the PHP function that will handle this shortcode.

Step 4: Upload and Activate Your Plugin

  1. Upload the Plugin:
    • Using an FTP client or your hosting’s file manager, upload the entire my-custom-shortcodes folder (containing my-custom-shortcodes.php) to your wp-content/plugins/ directory.
  2. Activate in WordPress:
    • Log in to your WordPress admin dashboard.
    • Go to Plugins > Installed Plugins.
    • You should see “My Custom Shortcodes” in the list. Click Activate.

Step 5: Use Your Shortcode

Now that your plugin is active, you can use your shortcode anywhere shortcodes are supported:

  • In a Post or Page (Classic Editor): Simply type [my_greeting] or [my_greeting name="Alice" color="green"] directly into the content area.
  • In a Post or Page (Block Editor – Gutenberg):
    • Add a “Shortcode” block and type [my_greeting] or [my_greeting name="Alice" color="green"].
    • Alternatively, you can use an “HTML” block and paste the shortcode there.
  • In a Text Widget: You can also use shortcodes in text widgets.

Examples of Usage:

  • [my_greeting]
    • Output: A blue box saying “Hello, Guest!”
  • [my_greeting name="Charlie"]
    • Output: A blue box saying “Hello, Charlie!”
  • [my_greeting name="Diana" color="purple"]
    • Output: A purple box saying “Hello, Diana!”
  • [my_greeting]This is some custom content inside the shortcode.[/my_greeting]
    • Output: A blue box saying “Hello, Guest!” and “This is some custom content inside the shortcode.”

Best Practices for Custom Plugins

  • Prefix Everything: Always prefix your function names, variable names, and class names with a unique string (e.g., my_plugin_, msc_) to avoid conflicts with other plugins or themes.
  • Internationalization (i18n): If you plan for your plugin to be used by others or in different languages, use WordPress’s internationalization functions (__(), _e()) and load your text domain.
  • Security: Always sanitize and escape all user input and output.
  • Readability: Use clear variable names, comments, and proper indentation.
  • Error Handling: Consider adding basic error handling or checks for dependencies.

By following these steps, you’ll have a robust and maintainable way to extend your WordPress site with custom shortcodes.

Related Posts


How to remove admin menu pages inserted by plugins?

To remove admin menu pages inserted by plugins in WordPress, you typically use the remove_menu_page(...

Media Gallery Preview Images Not Updating After Replacing via Media Library (WPBakery Grid Fix)

Troubleshooting Guide: WPBakery Media Grid Thumbnails Not Updating This guide will help you resolve ...

Custom query filter for order by is causing issue with group by in wordpress

If your custom query filter for ORDER BY is causing issues with GROUP BY in WordPress, it’s li...

“Maximum Available Quantity Has Been Added to Cart” Error in WooCommerce

Seeing the “Maximum available quantity has been added to cart” error in WooCommerce? Thi...

Recent Posts