Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

I'm using a shortcode to pull in different loops via the loops-name.php. For some reason it is always at the top of the page. I googled it and using echo instead of return causes that problem but with my code I am not using echo. Here's the shortcode:

// setup the shortcode for use
function friendly_loop_shortcode( $atts, $content = null ) {
extract( shortcode_atts( array(
'category' => '',
'module' => ''
), $atts ) );

include(locate_template('loop-'.$module.'.php'));
 }

Any idea why this is happening?

share|improve this question
    
Shortcode for including a file? I find it a little odd. –  Rutwick Gangurde Apr 10 '12 at 12:39
1  
'with my code I am not using echo' - are the loop-module.php files echoing or returning their output? –  Michael Apr 10 '12 at 12:45
    
Not at the moment - the file just has a paragraph tag with "test" written into it so I can see how it works. –  john joe Apr 10 '12 at 13:54
    
use get_template_part('loop',$module) instead, it's prettier, quicker to type, supports parent/child themes, and it's the recommended method of including templates in wordpress ( yes locate_template may do some of those things but look how much less readable it is!) –  Tom J Nowell Apr 11 '12 at 10:00
    
possible duplicate of The result of a shortcode appear BEFORE page content –  Chip Bennett Apr 11 '12 at 12:06

2 Answers 2

up vote 4 down vote accepted

You can buffer the output like this:

ob_start();
include(locate_template('loop-'.$module.'.php'));
return ob_get_clean();

EDIT. I tried this, worked fine.

function friendly_loop_shortcode( $atts, $content = null ) {
     extract( shortcode_atts( array(
         'category' => '',
         'module' => ''
     ), $atts ) );

     ob_start();
     include(locate_template('loop-'.$module.'.php'));
     $output = ob_get_clean();
     //print $output; // debug
     return $output;
}

if (!is_admin()) {
     add_shortcode('test', 'friendly_loop_shortcode' );
}
share|improve this answer
    
+1 - nice solution :) –  Stephen Harris Apr 10 '12 at 14:51
2  
Do not use output buffering if there are other ways. –  toscho Apr 10 '12 at 19:42
    
I'm afraid that didn't work. –  john joe Apr 11 '12 at 6:38
    
what went wrong? I tried and updated the answer –  offroff Apr 11 '12 at 7:54
    
That works perfect now. Thanks :) –  john joe Apr 11 '12 at 13:03

Your included file is essentially echo-ing HTML. For instance

<?php
 //Some PHP
 echo 'test';
 //Some more PHP
 ?>

Is the same as

<?php
 //Some PHP 
 ?>
 test
<?php
 //Some more PHP
 ?>

Both get printed immediately rather than returned. Since its printed it appears before the page content. You need to return something for it be included in the content.

As @RutwickGangurde pointed out - it's unusual to include a template file in a shortcode.

share|improve this answer
1  
Thanks, I didn't know that. So I need to put the whole thing into a variable and return it? As for including a template file - well I want to make it as easy as possible for the theme users to customise the theme and having a huge shortcode file nested away from the root theme dir is not really ideal for them. –  john joe Apr 10 '12 at 14:06
    
See @offroff's answer - that should work –  Stephen Harris Apr 10 '12 at 14:50
1  
"well I want to make it as easy as possible for the theme users to customise the theme" - Just how many abstraction layers are necessary? You've got a custom template file inside of a shortcode. I don't see how that makes things any easier for users. If you want to provide the ability to add static content to all posts, just define a dynamic_sidebar() inside the Loop, and let users add Widgets. –  Chip Bennett Apr 11 '12 at 12:12
    
Most of the theme users will not appreciate having to trawl through a massive shortcode file to change a simple css class on the frontend. If I break up everything using the standard loop-name.php system then it's a lot faster for them to find what they need. Not ideal but I've got to keep them happy ;) –  john joe Apr 11 '12 at 13:10

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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