All articles

Building a WordPress Plugin: Frontend Display with Shortcodes

In our previous article, Implementing AJAX for Dynamic Content, we added AJAX note submissions with JavaScript, a PHP handler and server-side validation.

The admin interface can now manage notes. Next, we’ll display them on public pages using a shortcode.

This article will cover the implementation of shortcodes. A [quick_notes] shortcode will be created, allowing users to display a list of their notes anywhere in their content.

Displaying Notes with a Shortcode

The WordPress Shortcode API lets users insert dynamic content into a page. A shortcode like [quick_notes] is more intuitive for a non-technical user than embedding PHP or HTML.

 

Creating a Basic Shortcode

Registering a shortcode is done with the add_shortcode() function, which should be hooked into the init action. This function maps a shortcode tag (e.g., ‘quick_notes’) to a callback function that generates the output.


<?php
/**
 * Renders the [quick_notes] shortcode.
 *
 * @param array $atts Shortcode attributes.
 * @return string The shortcode output.
 */
function qnm_render_notes_shortcode($atts) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'quick_notes';

    $notes = $wpdb->get_results("SELECT note, created_at FROM $table_name ORDER BY created_at DESC", ARRAY_A);

    if (empty($notes)) {
        return '';
    }

    // Use output buffering to capture the HTML
    ob_start();
   ?>
    <ul class="qnm-notes-list">
        <?php foreach ($notes as $note) : ?>
            <li><?php echo esc_html($note['note']); ?></li>
        <?php endforeach; ?>
    </ul>
    <?php
    return ob_get_clean();
}

/**
 * Initializes shortcodes.
 */
function qnm_shortcodes_init() {
    add_shortcode('quick_notes', 'qnm_render_notes_shortcode');
}
add_action('init', 'qnm_shortcodes_init');

In this handler function, several key practices are followed:

  • The global $wpdb object is used to query the wp_quick_notes table for all notes.
  • Output buffering (ob_start(), ob_get_clean()) is used to build the HTML output as a string. This is crucial because shortcode handlers must return their output, not echo it directly.
  • The note content is escaped using esc_html() before being displayed. This is a critical security measure to prevent Cross-Site Scripting (XSS) attacks by ensuring any HTML within the note is displayed as text rather than being executed by the browser.

Adding Attributes to the Shortcode

Shortcodes can be made more flexible by accepting attributes. For instance, a limit attribute could control how many notes are displayed: [quick_notes limit="5"].

The shortcode_atts() function is used to parse these attributes, merging them with a set of default values. This provides sensible defaults and ensures the shortcode works even if no attributes are provided.

The handler function is modified to accept and process attributes:


function qnm_render_notes_shortcode($atts) {
    global $wpdb;
    $table_name = $wpdb->prefix . 'quick_notes';

    // 1. Define and parse attributes
    $atts = shortcode_atts(
        array(
            'limit' => -1, // Default: show all notes
        ),
        $atts,
        'quick_notes'
    );

    $limit = intval($atts['limit']);

    // 2. Build the query with the limit
    $query = "SELECT note, created_at FROM $table_name ORDER BY created_at DESC";
    if ($limit > 0) {
        $query .= $wpdb->prepare(" LIMIT %d", $limit);
    }

    $notes = $wpdb->get_results($query, ARRAY_A);
    
    //... (rest of the function remains the same)
    //...
}

This updated function now uses shortcode_atts() to process the limit attribute, validates it as an integer, and modifies the SQL query accordingly.

Next up is Security, Styling, and Distribution Best Practices. We’ll add styles, review security, test the plugin and prepare it for distribution.