Wordpress - Shortcode empty attribute

WordPress does not discard attributes without values as is suggested by SethMerrick, but it does not handle it as you would expect. In your example, you would not be able to check isset($atts['last']), but "last" is passed as a value to an unnamed attribute. In this case, this would result in TRUE: ($atts[0] == 'last'). So, you could do a foreach loop to check for any attribute with a value of "last".


When [example attr1="value1" attr2 attr3="value3" attr4] is parsed, the $atts parameter yields:

$atts = array (
    'attr1' => 'value1',
          0 => 'attr2',
    'attr3' => 'value3',
          1 => 'attr4'
);

You can normalize this like so, then you can call shortcode_atts on it.

if (!function_exists('normalize_empty_atts')) {
    function normalize_empty_atts ($atts) {
        foreach ($atts as $attribute => $value) {
            if (is_int($attribute)) {
                $atts[strtolower($value)] = true;
                unset($atts[$attribute]);
            }
        }
        return $atts;
    }
}

function paragraph_shortcode ($atts, $content = null) {
    extract(shortcode_atts(
        array (
            'last' => ''
        ),
        normalize_empty_atts($atts)
    ));

    return '<p class="super-p'
        .($last ? ' last' : '')
        .'">'
        .do_shortcode($content)
        .'</p>';
}

add_shortcode('paragraph', 'paragraph_shortcode');

Other notes:

  • [paragraph last] would make $last = true. [paragraph last="1"] would make $last = '1'.
  • Attributes are case-insensitive, so [paragraph LAST] is equivalent to [paragraph last].
  • Attributes cannot be purely numeric, so the foreach loop I created is safe against integer-indexed attributes.

I know this is old, but I didn't feel any of the answers were complete, compact answers. Many people are suggesting running the $atts array through a foreach to find if your value exists. In reality, I don't feel it needs to be that complicated; array_search could be used instead to simplify things.

In the case of your example, you could use this:

[paragraph last] something [/paragraph]

then to determine if the empty attribute is provided, use a basic conditional to check and see if the key returned null or as an integer (including zero):

// Returns the array key, if empty attribute is found
$last_key = array_search('last', $atts);

// Determine if the key is an integer, zero or greater
// (In the event you're passing multiple empty attributes)
if(is_int($last_key)) {
  // Do something, your attribute is set
}

Tags:

Shortcode