Passing variables to WordPress get_template_part() function

Passing variables to WordPress get_template_part() function

Similar to native include() or require() PHP functions, WordPress introduces its own get_template_part() function to load templates (PHP files) on the website front-end (WordPress theme).

While using get_template_part is good in many cases, there are also some points where get_template_part() function makes things harder for developers. Precisely, there is not a possibility to pass PHP variables to a template which is included via get_template_part(). Let’s take a look at some basic examples and an elegant workaround.

Why using get_template_part()?

One word (actually two) – Child Themes. Yes, if you want to change some of the theme files (templates) via child theme, calling get_template_part() is a way to go.

Basically, when you call get_template_part(‘some-file’) WordPress will first check if the file with the same path and name exists in the child theme. If the file exists, it will load the file from the child theme instead of parent and this is really a neat solution to override some template which you want to change without touching the original (parent) theme files. Here is a basic example:

And here is a basic example of content.php file.

The problem with get_template_part() variables

Now, what if we have a custom variable in loop.php file which we want to use in content.php file as well. Take a look:

When we try to use $example variable in content.php it becomes unrecognized.

Usual workaround is to use global statement before defining or calling variable each time in each of the templates and that way it will be recognized. It may be ok for one variable in just one place but for many variables and complex template structure it’s not so elegant, right? We want to avoid calling global multiple times.

A workaround – using include() and locate_template()

If you dig deeper into WordPress code you will see that get_template_part() actually uses another function called locate_template() which is basically used to detect if a template exists in child theme. Optionally, locate_template() may load template (and clear all variables as get_template_part) or it may just return the path to an actual file without loading it.

Combining locate_template() and native PHP include() function, we get exactly what we need. See:

Now, when we try to use $example variable in content.php, everything is fine!

Feel free to try and let us know if this helps!

Bojan Petrovic

Co-founder and WordPress developer at Meks. He has been involved in the business since 2009. creating themes, plugins and services on top of WordPress, continuously aiming to choose best approaches and work smarter, not harder.

11 comments

Leave a comment
    • Sure, but since “include” call is detected as “info” and not a “requirement”, it’s not the real problem, even with theme check, right?

  • include and locate_template doesn’t work for parent and child theme. get_template_part function understands which template to pick but if you use include and locate_template, it will fail to pick right template.

    • Hey Mike,

      Locate template will work fine, that is the whole point of our article. If you dig deeper into WordPress code you will notice that get_template_part function actually uses locate_template internally 😉

  • Hi,

    With this solution I’m getting “Fatal error: Maximum execution time of 30 seconds exceeded”. When I return to get_template_part no problems (except that the variable isn’t acessable).

  • First Remark the false, false – they MUST be false otherwise the locate_template will jump to include the template itself, and also other empty results will occur.

    I can see some confusing like “sharing variable between templates”.

    Maybe I would add that:
    The scope or the relationship is of importance between set and available get.

    To make it easy to understand:
    Only declared variables in the same scope, normally declared just before get_template_part… or locate_template.. or load_template… will automatic be accessible in the “next” scope, eg only directly inside the called template file.

    The example in this post works fine with that, cause we are not in a next scope.

    So, Your variable will get lost if that template call another template. And, It will not exists within a custom template function/ hook like my_filter_the_title().

    This can be done by remain within the core methods, not use include “yourself” directly.

    At the end, all built in WordPress methods are just wrappers for the final “load_template” that includes (requires) the file from the server. Before that function, “locate_template” is just a checker that & where the intended file exists, and first in the chain, get_template_part “just” starts building the filename a more easy way than PHP way. (very hypo speaking here)

    So: include( locate_template( ‘content.php’, false, false ) ) is just a bypass to use the PHP native way to include more code “at the same spot” you are for the moment. And naturally, all your variables are there.

    BUT, WordPress built in load_template() has another action before it requires the template-file from the server. It extracts arguments to the following scope. Therefore, Bypassing load_template() removes all arguments that might be needed in a shared template file. This is selldom a final problem, INSTEAD it is an opportunity for this task.

    Another way of solving: The problem with get_template_part() variables

    Step one is to choose your variables you need to pass before you template call like in this post example:
    set_query_var(‘example’, $example);
    while( have_posts() ): the_post(); get_template_part( ‘content’ );
    $example is now avaible in the loaded template, thanks to native get_template_part() that uses load_template() at the end

    Inside any filter in use by the current temaple, you can retrieve the variable(s) like:
    add_filter(‘the_title’, ‘my_content_template_tilte’)
    function my_content_template_tilte($title){
    $example = get_query_var(‘example’);
    return $title.’ added with ‘.$example;
    }

    You can actually pass the variable to the next template scope by set the custom query variable again, cause load_template will extract new arguments and your first set_query_var will be at no existance.

    Just do it in the SAME scope where the load_template is in use. A smart way to do this “passing” is another thread.

Leave a Reply

Your email address will not be published. Required fields are marked *