2

I know this question is similar to other questions that have been posted. I have followed exactly what was suggested in answers to those questions but still can't figure out why the output is shown at the the top of the page.

function foo_shortcode($atts, $content = null) { 

    $datashortcode = '<div>'.(function_exists('rtb_kk') ? rtb_kk() : '').'</div>';

    return $datashortcode; 

}
add_shortcode('showfoo', 'foo_shortcode');

Any idea?

Kirk Beard
  • 9,569
  • 12
  • 43
  • 47
Arstik
  • 25
  • 4

2 Answers2

2

Without knowing how the rtb_kk() function works, I can only assume it uses echo to display content rather than using return. This is what causes the output of that function to appear at the top of the page.

To work around this issue, you can capture the output of the function with ob_start() and ob_get_clean():

function foo_shortcode($atts, $content = null) { 
    if (function_exists('rtb_kk')) {
        // Start output buffering
        ob_start();
        // Run the function
        rtb_kk();
        // Capture buffer as a string
        $output = ob_get_clean();
    } else {
        // Function doesn't exist so we return an empty string
        $output = ''; 
    }

    return '<div>' . $output . '</div>'; 
}
add_shortcode('showfoo', 'foo_shortcode');

Alternative method

If you're able to use the bcn_display() instead of the rtb_kk() method you're using, then there is no need to rely on ob_get_clean().

function foo_shortcode($atts, $content = null) { 
    if (function_exists('bcn_display')) {
        // Return the output as a string so we can control when it's displayed
        $output = bcn_display( true );
    } else {
        // Function doesn't exist so we return an empty string
        $output = ''; 
    }

    return '<div>' . $output . '</div>'; 
}
add_shortcode('showfoo', 'foo_shortcode');
Kirk Beard
  • 9,569
  • 12
  • 43
  • 47
  • Thank you for your answer, It worked well but showing dual outputs. One with wrapped in `
    ` and other without in div. Any idea why this wired output?
    – Arstik Mar 08 '17 at 14:38
  • Where does the `rtb_kk()` come from? Is it a plugin? – Kirk Beard Mar 08 '17 at 14:43
  • @Arstik I've updated my answer to use `ob_get_clean()` instead of `ob_get_flush()`. This should return the output without printing it to screen. More details are available in [this answer](http://stackoverflow.com/a/7379814/248567). – Kirk Beard Mar 08 '17 at 14:46
  • `rtb_kk()` is actually `bcn_display()` from: https://wordpress.org/plugins/breadcrumb-navxt/installation/ – Arstik Mar 08 '17 at 14:47
  • Updated question worked like charm. Thank you for helping :) – Arstik Mar 08 '17 at 14:51
  • I'm not sure how `rtb_kk()` references the `bcn_display()` function, but if you look at the [documentation](https://mtekk.us/code/breadcrumb-navxt/breadcrumb-navxt-doc/#using_bcn_display) for the `bcn_display()` function, you can see it accepts several arguments. The first of those arguments lets you force the function to `return` the value rather than `echo` it. This would let you achieve what you need without using `ob_get_clean()`. For example, `bcn_display( true )` will `return` the value as your code requires. – Kirk Beard Mar 08 '17 at 14:54
  • Can you please update your answer to make it work with `bcn_display()` without using `ob_get_clean()` as `rtb_kk()` is added mistakenly. `bcn_display() is what i am using with this shortcode. – Arstik Mar 08 '17 at 15:07
  • @Arstik I've updated my answer with an alternative method for handling your shortcode. – Kirk Beard Mar 08 '17 at 15:12
0

This will solve your problem, just try

<script type="text/javascript">
function foo_shortcode($atts, $content = null) {
    if(function_exists('rtb_kk')){
        $rtb_kk = rtb_kk();
    }else{
        $rtb_kk = '';
    }
    $datashortcode = "<div>$rtb_kk</div>";
    return $datashortcode;
}
add_shortcode('showfoo', 'foo_shortcode');
</script>
nickb
  • 59,313
  • 13
  • 108
  • 143
Umar
  • 156
  • 5