The question:
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
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
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