Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling WordPress get_template_part from inside a shortcode function renders template first

I have a page where I need to allow the user to enter a paragraph of text. Then after that text, insert a shortcode that will render a list of posts, then add more free-form text after that. My thought was that they should be able to insert a shortcode which will output the posts. This way they can simply add the shortcode where they wish the posts to appear.

I currently have the logic which retrieve the posts separated in its own file. Currently I include it in a page by simply using the get_template_part() function:

get_template_part('donation', 'posts');

I looked into how to create a shortcode and included the following code into my functions.php file in order to create the shortcode:

add_shortcode('donation-posts', 'fnDonatePosts');   
function fnDonatePosts($attr, $content)
{
    get_template_part('donation', 'posts');    
}

The donation-posts.php is being properly executed and the posts are appearing, however, they are always positioned BEFORE the content and not in the location that the shortcode was placed.

I have tried removing the get_template_part() function and just output some text and that works fine. So I understand that the get_template_part() may not be the right way to do this, however, I have not been able to uncover a way to do what I am attempting to do (I am sure that there is a way... I just haven't found it).

I have tried:

include(get_template_directory(). '/donation-posts.php');
include_once(get_template_directory(). '/donation-posts.php') : 

But these stopped processing once they hit the PHP code in the included file.

I have also tried:

$file = file_get_contents(get_template_directory(). '/donation-posts.php');  
        return $file;

But this only returns the contents of the file (as the function name indicates) which means it doesn't execute the PHP script to return the posts.

Anybody out there done this before?

like image 818
Gary O. Stenstrom Avatar asked Sep 07 '12 21:09

Gary O. Stenstrom


1 Answers

Here is a more dynamic version where you can pass the path to the template.

function template_part( $atts, $content = null ){
   $tp_atts = shortcode_atts(array( 
      'path' =>  null,
   ), $atts);         
   ob_start();  
   get_template_part($tp_atts['path']);  
   $ret = ob_get_contents();  
   ob_end_clean();  
   return $ret;    
}
add_shortcode('template_part', 'template_part');  

And the shortcode:

[template_part path="includes/social-sharing"]
like image 94
Darren Cooney Avatar answered Nov 14 '22 08:11

Darren Cooney