1

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?

2
  • if the function "bg_calculate_points" do all the work, you can directly use add_shortcode( 'comparison_points', 'bg_calculate_points' ); Commented May 15, 2018 at 9:01
  • @mmm but I need to pass a 'custom_field' attribute to it. Commented May 15, 2018 at 10:17

1 Answer 1

3

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');
2
  • Actually my top shortcode example is not working for me either, and your example seems really confusing to me (sorry, I'm new to all this). Do you know of a simple example I can copy? My shortcode just needs pass the 'custom_field' attribute to the bg_calculate_points($custom_field) function Commented May 15, 2018 at 10:48
  • @TinyTiger Please check my update. You can't use $custom_field but need to use $atts['custom_field'] or in my case $comparison_points_atts['custom_field']. Also make sure, bg_calculate_points() actually returns the output and doesn't just echo it Commented May 15, 2018 at 11:18

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.