Unnamed WordPress shortcode attributes

Ever wished you could do something like [shortcode epic] and pass the flag as a parameter? Turns out it’s pretty easy!

WordPress and empty attributes

This method works by taking advantage of how WordPress handles shortcodes; when your shortcode function is called it gets passed one or two parameters depending on whether it is enclosing (e.g. [shortcode]Content[/shortcode]) or self-closing (e.g. [shortcode]). They always get the first parameter—the array $atts—and enclosing shortcodes also get the second parameter—the string $content—populated with whatever is between the opening and closing tag.

When an empty attribute (which I refer to as a “flag”) is added to a shortcode (e.g. [shortcode flag]Content[/shortcode]) the shortcode_atts function ignores it and it appears impossible to access the flag.

How does it work?

The $atts array does contain the flag, just not how you’d expect. Usually the attribute is stored as the array key and the value as the array value, but where there is no value the flag is stored as the array value with a numeric array key.

So we need to find the array item with an integer as the key and the flag we’re interested in as the value.

The code

function is_flag( $flag, $atts ) {
    foreach ( $atts as $key => $value )
        if ( $value === $flag && is_int( $key ) ) return true;
    return false;
}

echo ( is_flag( 'epic', $atts ) ) ? 'Is Epic' : 'Not Epic';

The is_flag function will determine whether the given flag exists for the given attributes and return true or false.

Filtering attributes

If you don’t plan on using the shortcode_atts() function, I won’t blame you because it comes with several limitations. Firstly, all attributes must be known: any attributes not specified when calling shortcode_atts() get unset. Secondly, it just won’t allow tag attributes, but that’s ok.

If all attributes are known, you can do something like foreach( $atts as $key => $val ) if ( !in_array( $key, [ 'Att1', 'Att2' ] ) ) unset( $atts[ $key ] ); and the filter that shortcode_atts() creates for you can be created manually by adding apply_filters( "shortcode_atts_$shortcode", $atts ); to the start of your shortcode’s code.

Conclusion

If you’re not namespacing and object-ing (which you should be!) it’s best to wrap this function with a function_exists() check in case any other plugins/themes use it too.

Happy flagging!

Leave a Reply

Your email address will not be published.