Passing a variable to get_template_part

The WP Codex says to do this:

// You wish to make $my_var available to the template part at `content-part.php`
set_query_var( 'my_var', $my_var );
get_template_part( 'content', 'part' );

But how do I echo $my_var inside the template part? get_query_var($my_var) does not work for me.

I’ve seen tons of recommendations for using locate_template instead. Is that the best way to go?

1
13

As posts get their data set up via the_post() (respectively via setup_postdata()) and are therefore accessible through the API (get_the_ID() for e.g.), let’s assume that we are looping through a set of users (as setup_userdata() fills the global variables of the currently logged in user and isn’t useful for this task) and try to display meta data per user:

<?php
get_header();

// etc.

// In the main template file
$users = new \WP_User_Query( [ ... ] );

foreach ( $users as $user )
{
    set_query_var( 'user_id', absint( $user->ID ) );
    get_template_part( 'template-parts/user', 'contact_methods' );
}

Then, in our wpse-theme/template-parts/user-contact_methods.php file, we need to access the users ID:

<?php
/** @var int $user_id */
$some_meta = get_the_author_meta( 'some_meta', $user_id );
var_dump( $some_meta );

That’s it.

Update (WP >= v5.5)

As pointed out in the comments, current versions of WP offer a third parameter for get_template_part(): array $args. So from this version on, you do not need to use set_query_var( 'foo', 'bar' ) anymore. Example:

<?php
get_header();

// etc.

// In the main template file
$users = new \WP_User_Query( [ ... ] );

foreach ( $users as $user )
{
    $args = (array) $user;
    get_template_part( 'template-parts/user', 'contact_methods', $args );
}

Then, in our wpse-theme/template-parts/user-contact_methods.php file, we need to access the users ID:

<?php
/** @var array $args */
$some_meta = get_the_author_meta( 'some_meta', $args['ID'] );
var_dump( $some_meta );

The explanation is actually exactly above the part you quoted in your question:

However, load_template(), which is called indirectly by get_template_part() extracts all of the WP_Query query variables, into the scope of the loaded template.

The native PHP extract() function “extracts” the variables (the global $wp_query->query_vars property) and puts every part into its own variable which has exactly the same name as the key. In other words:

set_query_var( 'foo', 'bar' );

$GLOBALS['wp_query'] (object)
    -> query_vars (array)
        foo => bar (string 3)

extract( $wp_query->query_vars );

var_dump( $foo );
// Result:
(string 3) 'bar'

Leave a Comment