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

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');

Leave a Comment