10

Possible Duplicate:
problem with short code

Shortcodes are broken.

For those of you playing at home, heres an easy step by step to replicate my problem.


1) Open a fresh Wordpress install (3.4.2).

2) Go into twentyeleven/functions.php and add the following:

function test() {
echo '-TEST-';
}
add_shortcode('testshortcode', 'test');

3) Edit the 'hello world' post to say:

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging! 
[testshortcode] 
foobar

4) Save and view, my results look like the following:

-TEST-
Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
foobar

when it should look like this:

Welcome to WordPress. This is your first post. Edit or delete it, then start blogging!
-TEST-
foobar

What on earth is going on here?

1
  • Instead of "echo '-TEST-';" use "return '-TEST-';" .
    – Softmixt
    Apr 5, 2018 at 21:07

1 Answer 1

17

Shortcode callbacks have to return, not output. So use the following:

function test() {
    return '-TEST-';
}
add_shortcode( 'testshortcode', 'test' );

More info: http://codex.wordpress.org/Shortcode_API

If you have to use echo you can also do it this way(useful if there's a lot of markup & it's difficult working with strings)-

function test() {
    ob_start();
    echo '-TEST-';
    return ob_get_contents();
}
add_shortcode( 'testshortcode', 'test' );
5
  • That's interesting, it works on the clean install but doesn't work in a plugin that does the same thing, it used echo and failed like my example, but when i change it to return it still fails. Here's the plugin wordpress.org/extend/plugins/wordpress-media-tags
    – Neros
    Oct 16, 2012 at 9:37
  • I downloaded the plugin & checked it, if you replace echo with return there, it will return the content to the calling function, not to wordpress. Oct 16, 2012 at 9:50
  • I just worked that out and was about to comment, if you put another return on the function the callback calls and replace the echo, it works. Cheers.
    – Neros
    Oct 16, 2012 at 9:51
  • 7
    This displayed content twice for me (one before content, second on the place I wanted). I solved this by: function test() { ob_start(); echo '-TEST-'; $ReturnString = ob_get_contents(); ob_end_clean(); return $ReturnString; } Dec 19, 2016 at 0:33
  • 1
    For people that have the content displaying twice, instead of ob_get_contents, use ob_get_clean
    – DreamWave
    Mar 9, 2020 at 13:16

Not the answer you're looking for? Browse other questions tagged or ask your own question.