Using action hooks inside of a shortcode

I am trying to create a modular plugin that includes action hooks for developers to add content before and after the main shortcode content. I’m having some trouble because anything I do in the function called by the action hook is always echoed out at the top of the shortcode instead of inside the shortcode where it belongs.

I’ve been searching and I did come across this response from Pippin Williams on a recent ThemeForest thread, where he recommends using output buffering. I haven’t gotten this to work properly for me, and I’ve read elsewhere that output buffering should only be used as a last resort, so I’m still looking for a clean solution.

The simplest shortcode ever:

add_shortcode('shortcode','example_shortcode');

function example_shortcode( $atts ) {

  $shortcode_output = "<p>Some shortcode content.</p>";
  $shortcode_output .= "<p>More shortcode content.</p>";

  return $shortcode_output;

}

Now lets add an action:

add_shortcode('shortcode','example_shortcode');

function example_shortcode( $atts ) {

  $shortcode_output = "<p>Some shortcode content.</p>";
  $shortcode_output .= "<p>More shortcode content.</p>";

  do_action('below_shortcode');

  return $shortcode_output;
}

add_action('below_shortcode', 'example_action_output');

function example_action_output() {
    echo "<p>This should be output at the end.</p>";
}

The contents of example_action_output() are returned above the shortcode content because of the echo statement. I tried output buffering as recommended by Pippin:

add_shortcode('shortcode','example_shortcode');

function example_shortcode( $atts ) {

  $shortcode_output = "<p>Some shortcode content.</p>";
  $shortcode_output .= "<p>More shortcode content.</p>";

  ob_start();
  do_action('below_shortcode');
  return ob_get_clean();

  return $shortcode_output;
}

add_action('below_shortcode', 'example_action_output');

function example_action_output() {
    echo "<p>This should be output at the end.</p>";
}

This returned the contents of example_action_output(), but wiped out the rest of my shortcode. Any suggestions?

Thanks,
Dalton

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

Try this:

function example_shortcode( $atts ) {

    $shortcode_output = "<p>Some shortcode content.</p>";
    $shortcode_output .= "<p>More shortcode content.</p>";

    ob_start();
        do_action('below_shortcode');
        $below_shortcode = ob_get_contents();
    ob_end_clean();

    $shortcode_output .= $below_shortcode

    return $shortcode_output;
}

Method 2

My answer would include a filter function that adds the text like this:

add_shortcode('shortcode','example_shortcode');

function example_shortcode( $atts ) {

    $shortcode_output = "<p>Some shortcode content.</p>";
    $shortcode_output .= "<p>More shortcode content.</p>";

    $shortcode_output .= apply_filter('below_shortcode', $shortcode_output);

    return $shortcode_output;
}

add_filter('below_shortcode', 'example_action_output', 10, 1);

function example_action_output( $text = '' ) {
    return $text . "<p>This should be output at the end.</p>";
}


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

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x