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 Use a Cron Task to Generate Bookings.ics Automatically?

A common way to achieve this is to trigger the function directly via a cron job, without needing a p...

Fix get_the_terms Not Returning Data After Using pre_get_posts on Tax Archive Pages

When you use the pre_get_posts action in WordPress, you’re modifying the main query before it&...

CSS in WordPress: Single Stylesheet vs. Page-Specific Files – What’s Best?

WordPress developers often face the dilemma of choosing between a single consolidated CSS file or mu...

How to Retrieve and Expose Gutenberg & Theme-Generated CSS in WordPress

If you want to extract the CSS generated by Gutenberg and your WordPress theme, you can do so using ...

Recent Posts