0

I've created my own shortcode. I'm unable to share the code unfortunately ;/

When I use it on my pages it behaves strange. It always has the highest priority. I mean something like that in page editor:

Text
[shortcode]

Outputs on the page:

< shortcode contents > 
Text

And this in page editor:

[shortcode]
Text
[shortcode]

Gives:

< shortcode contents >
< shortcode contents >
Text

So I'm unable to put anything before and between my shortcodes.

To say more, my shortcodes use a few ifs, foreachs and a loop (they're grabbing and displaying data from custom post type).

Any ideas why it happnes?

[edit]

OK, so I've been using echoes instead of return. My bad. Is there any way of return my whole function without editing every single line and adding $output etc.?

3
  • very hard to tell without looking at the code but maybe you have a content filter other then your shortcode, try adding remove_all_filters("the_content",2);
    – Bainternet
    Commented Mar 1, 2011 at 1:49
  • 1
    Check to make sure that your shortcodes are returning their content, rather than echoing. An "echo" in a shortcode will always appear at the very top of your content, because the shortcodes are processed before the content is output. Commented Mar 1, 2011 at 2:20
  • @goldenapple Oops, only read your comment after posting.
    – wyrfel
    Commented Mar 1, 2011 at 5:13

1 Answer 1

2

I think your problem is that your shortcode echos it's output rather than returning it.

So in your shortcode function, remove any direct output (that is stuff between ?>.....<?php and any echos and rather gather your output in a variable and return that:

function my_shortcode_cb($atts) {
    ....
    $output = ....
    $output .= ....
    return $output;
}

More detail:

So instead of

while ($a != $b) {
    echo "<ul>";
    if ($c == $d) {
        foreach ($e as $k => $v) {
            ?>
            <li class="item-<?php echo $k; ?>"><?php echo $v; ?></li>
            <?php
        }
    }
    echo "</ul>";
}

you do:

$output = '';
while ($a != $b) {
    $output .= "<ul>"
    if ($c == $d) {
        foreach ($e as $k => $v) {
            $output .= "<li class=\"item-".$k."\">".$v."</li>";
        }
    }
    $output .= "</ul>";
}
return $output;

Or, if you wanna be cheap ;-), you can do this:

ob_start();
while ($a != $b) {
    echo "<ul>";
    if ($c == $d) {
        foreach ($e as $k => $v) {
            ?>
            <li class="item-<?php echo $k; ?>"><?php echo $v; ?></li>
            <?php
        }
    }
    echo "</ul>";
}
return ob_get_clean();

BTW: If your shortcode callback is really really long, then chances are that it's got lots of potential for refactoring. And if you'd do that, chances are that you'd assemble your output from strings returned by function calls, anyways.

11
  • @wyrfel, oh my God. You may be right BUT this is going to make serious mess in my code. My shortcode is very very long, full of loops and if statements... Is returning it all as one variable/set of variables the only way? :( Not intuitive at all. Commented Mar 1, 2011 at 11:53
  • @Wordpressor: You can keep all your code with all the supersecret loops and eventualities as is, just whereever you use an echo or escape back out of php mode and into html mode, append it to your output variable instead. It's really not that much difference.
    – wyrfel
    Commented Mar 1, 2011 at 11:55
  • @Wordpressor: see edits.
    – wyrfel
    Commented Mar 1, 2011 at 12:01
  • @wyrfel return ob_get_clean(); outputs [myshortcode] instead of it contents ;/ I'm unable to fit EVERY single echo line in $output. It'd take around 10 years and will destroy whitespace completely, in addition as I said before there are tons of nested and complicated statements and loops. HOLY COW :/ Commented Mar 1, 2011 at 13:46
  • The shortcode API gives clear examples of returning data(no echoes in those examples). Did you not check the documentation before you wrote the numerous shortcode functions you have?
    – t31os
    Commented Mar 1, 2011 at 14:06

Your Answer

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

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