0

I've recently been trying to create a 'Popular Products' widget for for WP e-Commerce. Since there isn't built-in functionality, I referred to Dave Mackintosh's post here and gave it a shot.

Still no success. But since there's a shortcode, I decided to use the 'Shortcodes in Widgets' plugin and place the shortcode in a text widget. It works now, but the issue now is the product list appears outside the widget area, just floating in the sidebar.

1

This behavior is being caused most likely because something in the shortcode function that is causing unstable behavior. I recently just had the same issue with something I was working on.

From the WordPress Codex for "Add ShortCode" there's a note tucked down near the bottom of the page:

Note that the function called by the shortcode should never produce output of any kind. Shortcode functions should return the text that is to be used to replace the shortcode. Producing the output directly will lead to unexpected results. This is similar to the way filter functions should behave, in that they should not produce expected side effects from the call, since you cannot control when and where they are called from.

From the example hack that you referenced there are echo calls within the shortcode function. Basically what's happening is that those echo commands are being called before the Widget header script.

The way to fix this is to pass all echo calls in the function to a variable and then add a return statement at the very end of the function.

return $html;

  • Wonderful! Thanks Brent! One line was all it took, overlooked it I guess. It works now. – nouptime Aug 28 '12 at 1:42
0

Passing everything to a variable by concatenation can be really boring and inconvenient, if you are wring a large amount of HTML. In that case, I would suggest using "Object Buffering". So, you can write ob_start() function from where you want to start buffering and get buffered contents using $content = ob_get_clean()

Let me give an example to make things clear.

As WordPress says, you shouldn't output directly, if you are writing a shortcode. So, the code below shouldn't be written in case of a shortcode.

<div id="my-wrapper">

  <?php 
   $name = 'John Doe';
   echo 'Hello '.$name;
  ?>
</div>

To fix the problem appeard (contents are displayed before title), you can put everying to a variable like below:

<?php

$content ='<div id="my-wrapper">';

$name = 'John Doe';

$content .= 'Hello '.$name;

echo '</div>';

return $content;

?>

As you can imagine, it going to be extremely annoying to write a large amount of code in this way. In this case I shall use php object buffering like below:

<?php ob_start();?>

<!-- start your code here -->

<div id="my-wrapper">

  <?php 
   $name = 'John Doe';
   echo 'Hello '.$name;
  ?>
</div>

<!-- code finished -->

<?php 

$content = ob_get_clean();
return $content; 

?>

You now don't need to change your code. Just put everything in between and This approach can be extremely useful in case of writing a large bit of code and also enhances visibility.

Note: What ob_start() does is, it starts saving everything after it (instead of letting it being outputted). On the otherhand, ob_get_clean() stops saving things and return the saved contents.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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