WordPress get_template_part pass variable
you can pass data to tempalte part via Global varible
like this $var = 'smoe data here';
<?php get_template_part( 'element-templates/front', 'top' ); ?>
then in your template part file use
<?php
global $var;
echo $var; // smoe data here
?>
The core get_template_part()
function doesn't support the passing of variables. It only accepts two parameters, slug and name. While there is no built-in solution to this problem, the best approach is to create a function that closely mimics get_template_part()
to handle it.
Normally I would create a function that just takes the name of the template file and the variables I want to pass in as an array. In your example however, you're using both arguments for get_template_part()
already which means you'll need a slightly more complex function. I'm going to post both versions below.
Simplified Version - Name (slug) and Data
function wpse_get_partial($template_name, $data = []) {
$template = locate_template($template_name . '.php', false);
if (!$template) {
return;
}
if ($data) {
extract($data);
}
include($template);
}
Usage example: wpse_get_partial('header-promotion', ['message' => 'Example message']);
This would load up a file named header-promotion.php
with $message
available inside of it. Since the second parameter is an array, you can pass in as many variables as you need.
Copy of get_template_part - adding a third parameter
If you don't need both $slug
and $name
when you call get_template_part()
, you probably want the simplified version. For those that do, here's the more complex option.
function wpse_get_template_part($slug, $name = null, $data = []) {
// here we're copying more of what get_template_part is doing.
$templates = [];
$name = (string) $name;
if ('' !== $name) {
$templates[] = "{$slug}-{$name}.php";
}
$templates[] = "{$slug}.php";
$template = locate_template($templates, false);
if (!$template) {
return;
}
if ($data) {
extract($data);
}
include($template);
}
Usage example: wpse_get_template_part('header-promotion', 'top', [$message => 'Example message']);
Neither function is a perfect copy of get_template_part()
. I've skipped all of the extra filters the core function uses for the sake of simplicity.
What about globals or query vars
- Globals are pretty commonplace in WordPress but are generally best avoided. They will work but start to get messy when you use the same template part more than once on a single page.
- Query vars (
get_query_var()
/set_query_var()
) aren't made for that purpose. It's a hacky workaround that can introduce unintended side-effects.
Using WordPress 5.5+
As of WordPress 5.5, passing variables via get_template_part is part of core.
Starting in WordPress 5.5, the template loading functions will now allow additional arguments to be passed through to the matched template file using a new $args parameter.
get_template_part( string $slug, string $name = null, array $args = null )
Example:
get_template_part( 'template-parts/featured-image', null,
array(
'class' => 'featured-home',
'data' => array(
'size' => 'large',
'is-active' => true,
)
)
);
and then in the included file (i.e. template-parts/featured-image.php
), you can either just display the variables (as per above example):
if ( $args['class'] ) {
echo $args['class'];
}
or
echo $args['data']['size'];
Alternatively, setup defaults first, using wp_parse_args
:
// Setup defaults
$array_defaults = array(
'class' => 'featured',
'data' => array(
'size' => 'medium',
'is-active' => false,
)
);
$args = wp_parse_args($args, $array_defaults );
<div class="widget <?php echo esc_html( $args['class'] ); ?>">
<?php echo esc_html( $args['data']['size'] ); ?>
</div>
To be backwards compatible in your theme, you should probably also check the current WordPress version.
Using set_query_vars
The original answer to this question was to use set_query_var
In your theme:
<?php
set_query_var( 'my_var_name', 'my_var_value' );
get_template_part( 'template-parts/contact' );
?>
In the template part:
<?php
$newValue = get_query_var( 'my_var_name' );
if ( $newValue ) {
// do something
}
?>