Are shortcodes case-sensitive?

Short Answer

Yes, shortcodes are case sensitive

Longer Answer

It’s really easy to build a test case for this and see.

<?php
add_shortcode('sOme_ShOrTcOdE', 'wpse102375_shortcode');
function wpse102375_shortcode($args, $content=null)
{
    return 'yep';
}

Longest Answer

Read the source.

The “magic” with shortcodes happens in do_shortcode, so let’s take a look at that.

<?php
// wp-includes/shortcode.php
function do_shortcode($content) {
    global $shortcode_tags;

    if (empty($shortcode_tags) || !is_array($shortcode_tags))
        return $content;

    $pattern = get_shortcode_regex();
    return preg_replace_callback( "/$pattern/s", 'do_shortcode_tag', $content );
}

Hmmm, $shortcode_tags — probably get’s set up in add_shortcode:

<?php
// wp-includes/shortcodes.php
function add_shortcode($tag, $func) {
    global $shortcode_tags;

    if ( is_callable($func) )
        $shortcode_tags[$tag] = $func;
}

So that’s just a key value part of $shortcode_name => $a_callablle. Makes sense.

Looks like most of the magic of do_shortcode takes place in building the regular expression to match shortcodes themselves. All that happens in get_shortcode_regex, so let’s take a look there:

<?php
// wp-includes/shortcode.php
function get_shortcode_regex() {
    global $shortcode_tags;
    $tagnames = array_keys($shortcode_tags);
    $tagregexp = join( '|', array_map('preg_quote', $tagnames) );

    // WARNING! Do not change this regex without changing do_shortcode_tag() and strip_shortcode_tag()
    // Also, see shortcode_unautop() and shortcode.js.
    return
          '\\['                              // Opening bracket
        . '(\\[?)'                           // 1: Optional second opening bracket for escaping shortcodes: [[tag]]
        . "($tagregexp)"                     // 2: Shortcode name
        . '(?![\\w-])'                       // Not followed by word character or hyphen
        . '('                                // 3: Unroll the loop: Inside the opening shortcode tag
        .     '[^\\]\\/]*'                   // Not a closing bracket or forward slash
        .     '(?:'
        .         '\\/(?!\\])'               // A forward slash not followed by a closing bracket
        .         '[^\\]\\/]*'               // Not a closing bracket or forward slash
        .     ')*?'
        . ')'
        . '(?:'
        .     '(\\/)'                        // 4: Self closing tag ...
        .     '\\]'                          // ... and closing bracket
        . '|'
        .     '\\]'                          // Closing bracket
        .     '(?:'
        .         '('                        // 5: Unroll the loop: Optionally, anything between the opening and closing shortcode tags
        .             '[^\\[]*+'             // Not an opening bracket
        .             '(?:'
        .                 '\\[(?!\\/\\2\\])' // An opening bracket not followed by the closing shortcode tag
        .                 '[^\\[]*+'         // Not an opening bracket
        .             ')*+'
        .         ')'
        .         '\\[\\/\\2\\]'             // Closing shortcode tag
        .     ')?'
        . ')'
        . '(\\]?)';                          // 6: Optional second closing brocket for escaping shortcodes: [[tag]]
}

Very well commented in the core, so not much to explain here. The key part is here:

global $shortcode_tags;
$tagnames = array_keys($shortcode_tags);
$tagregexp = join( '|', array_map('preg_quote', $tagnames) );

Which essentially will get used later to explicitly match any of the registered shortcode names. Notice that no text processing is done other than preg_quote, so WP will only try to match the explicit values passed in to add_shortcode as the shortcode name. It’s looking like shortcodes are case sensitive so far.

Next we need to take a look at the flags where the regular expression built in get_shortcode_regex is used. The relevant bit of do_shortcode.

"/$pattern/s"

The slashes delimit the regular expression, letters after the closing slash are PRCE flags or modifiers.

If we saw an i there it would be case insensitive. We only have an s (meaning a . matches all characters including the newline).

So, yes, shortcodes are case sensitive.

Leave a Comment