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 returntrue
orfalse
.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 callingshortcode_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 thatshortcode_atts()
creates for you can be created manually by addingapply_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!