Welcome to the Treehouse Community

Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.

Looking to learn something new?

Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.

Start your free trial

WordPress

Liam Maclachlan
Liam Maclachlan
22,805 Points

Why is my shortcode is causing returned value to appear at the top of the containing div?

HI all,

I have 3 different verisons of the 'same code' but I don't know why the first two either

1- don't work or

2- make the content appear above the other content in the div. Any ideas?

So my 3 attempts were:

Appears at the top of the container-

<?php
    // code snippet stylings
    function codeSnippet( $atts, $content ) { ?>
        <div>
            <?php echo $content; ?>
        </div>
    <?php }
        add_shortcode( 'CodeSnippet', 'codeSnippet' );
?>

Did not appear at all-

<?php
    // code snippet stylings
    function codeSnippet( $atts, $content ) { 
        ob_start();
        $content = '<div>' . $content . '</div>';
        $content = ob_end_clean();
        return $content;
    }
        add_shortcode( 'CodeSnippet', 'codeSnippet' );
?>

Worked as expected-

<?php
    // code snippet stylings
    function codeSnippet( $atts, $content ) { 
        $content = '<div>' . $content . '</div>';
        return $content;
    }
        add_shortcode( 'CodeSnippet', 'codeSnippet' );
?>
Liam Maclachlan
Liam Maclachlan
22,805 Points

I have a feeling that this is going to be something to do with buffering...

EDIT:...nope. It wasn't the need to buffer it -_-

2 Answers

Zac Gordon
STAFF
Zac Gordon
Treehouse Guest Teacher

Hey Liam!

You can keep using the 3rd option since it's working, but definitely try placing the widget in different locations to make sure it works in different situations.

Weird about the '1' below each error. What error is the shortcode showing?

I've been reading more about this and I had thought in general you should be buffering, although I'm seeing some folks saying it depends.

The reason the first example displays at the top is that the shortcode is actually being called into the page earlier then where it displays. However, because the function says to echo it will echo as soon as the function is read, not necessarily where you call it.

The last option is returning a value instead of doing a straight echo so the code isn't being displayed until later.

The benefit of buffering is sometime you write code in a way that would cause it to automatically echo out if it's not buffered and saved until the right time.

I would suggest trying to get the buffering option working if you can. For the future it may be more helpful to know how to do.

Liam Maclachlan
Liam Maclachlan
22,805 Points

Sorry. having a 'moment'. Meant 'area', not error =p

the $content is showing correctly but has a 1 below each AREA that the shortcode has been called. below is how the output from the DOM. The 'pre' tags are encapsulating the $content from the shortcode and the 1 is appearing just outside of that.

<pre><br>
//Input:<br>
.header {<br>
color: orange;<br>
&amp;__about {<br>
color: red;<br>
}<br>
&amp;__blog {<br>
color: green;<br>
}<br>
&amp;__contact {<br>
color: blue;<br>
}<br>
}
//Output:
.header {<br>
color: #FFA500;<br>
}<br>
.header__about {<br>
color: #ff0000;<br>
}<br>
.header__blog {<br>
color: #00ff00;<br>
}<br>
.header__contact {<br>
color: #0000ff;<br>
}</pre>
1

Thanks for clearing up the echo issue. That is really interesting to know, and kind of helps to understand buffering a bit more, too.

This is the shortcode being used:

// code snippet stylings
    function codeSnippet( $atts, $content ) { 
        ob_start();
        $content = '<div class="codesnippet"><pre>' . $content . '</pre></div>';
        $content .= ob_end_clean();
        return $content;
    }
Zac Gordon
Zac Gordon
Treehouse Guest Teacher

Hmm, sorry, looks like it's echoing out a value for ob_end_clean();

Try doing this instead:

function codeSnippet( $atts, $content ) { 
        ob_start();
        $content = '<div class="codesnippet"><pre>' . $content . '</pre></div>';
        ob_end_clean();
        return $content;
}
Liam Maclachlan
Liam Maclachlan
22,805 Points

Ah! The boolean. That makes sense. That sorted it, man. Bang on. Thanks for the help :)

Zac Gordon
Zac Gordon
Treehouse Guest Teacher

Yay! Rock on to you Liam :) have fun :)

Zac Gordon
STAFF
Zac Gordon
Treehouse Guest Teacher

I think that the problem with the second option with buffering is that you are overriding the value you assign here:

 $content = '<div>' . $content . '</div>';

with this:

$content = ob_end_clean();

Try this and see if it helps:

 $content = '<div>' . $content . '</div>';
 $content .= ob_end_clean();

You do not always need to buffer content, but sometimes it is necessary.

You might try this technical read for a bit more information:

http://www.hackingwithphp.com/13/0/0/output-buffering

Liam Maclachlan
Liam Maclachlan
22,805 Points

Hey man,

Thanks for the response. So should I be using the third option (seeing it works) or will that approach cause me problems with other types of shortcodes in the futures, and any idea why option 1 caused the content to appear at the top of the page?

FYI: you suggestion for the buffering worked. I will check out that technical doc to get a better understanding, too :)

EDIT: Ohh... Well, the suggestion did work, until I noticed it printing out a '1' below each error where the shortcode is used :/