Does a shortcode with a single attribute have to use an array?

The question:

I want to build a shortcode that takes a single attribute.

Everything online is telling me to make it using an array:

// Add Shortcode
function bg_comparison_points_shortcode( $atts ) {
    // Attributes
    $atts = shortcode_atts(
        array(
            'custom_field' => '',
        ),
        $atts,
        'comparison_points'
    );
    return bg_calculate_points($custom_field);
}
add_shortcode( 'comparison_points', 'bg_comparison_points_shortcode' );

But in my mind something like this would be much simpler

// Add Shortcode
function bg_comparison_points_shortcode( $custom_field ) {
    return bg_calculate_points($custom_field);
}
add_shortcode( 'comparison_points', 'bg_comparison_points_shortcode' );

Is there a problem doing this simpler version?

The Solutions:

Below are the methods you can try. The first solution is probably the best. Try others if the first one doesn’t work. Senior developers aren’t just copying/pasting – they read the methods carefully & apply them wisely to each case.

Method 1

Yes, the problem is that it won’t work.

The shortcode system doesn’t know how many arguments will be passed, so it gives you an array $atts that contains the attributes. When it is only one, then the array will only have one element. When no argument is passed, the array will be empty.

Check the official documentation for a proper example:

<?php
function wporg_shortcode($atts = [], $content = null, $tag = '')
{
    // normalize attribute keys, lowercase
    $atts = array_change_key_case((array)$atts, CASE_LOWER);

    // override default attributes with user attributes
    $wporg_atts = shortcode_atts([
                                     'title' => 'WordPress.org',
                                 ], $atts, $tag);

    // [...]

    // return output
    return $o;
}

function wporg_shortcodes_init()
{
    add_shortcode('wporg', 'wporg_shortcode');
}

add_action('init', 'wporg_shortcodes_init');

Longer code doesn’t mean the code is worse.

In this case I’d say the opposite is the case: If you use the array and everything how it is intended, then it will be very easy to expand your shortcode in the future, keep working on it and other developers will better understand your code.

Given this, you could write your shortcode like so

function bg_comparison_points_shortcode($atts = [], $content = null, $tag = '')
{
    // normalize attribute keys, lowercase
    $atts = array_change_key_case((array)$atts, CASE_LOWER);

    // override default attributes with user attributes
    $comparison_points_atts = shortcode_atts([
                                                 'custom_field' => '',
                                             ], $atts, $tag);

    return bg_calculate_points( $comparison_points_atts['custom_field'] );
}

function bg_comparison_points_init()
{
    add_shortcode('comparison_points', 'bg_comparison_points_shortcode');
}

add_action('init', 'bg_comparison_points_init');


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Comment