Wasteland
Wasteland

Reputation: 5379

WordPress get_template_part pass variable

Is there a way of passing a variable to get_template_part() in wordpress:

<?php get_template_part( 'element-templates/front', 'top' ); ?>
<?php get_template_part( 'element-templates/front', 'main' ); ?>

In the front-top.php and front-main.php (which the above is calling) I need to access numeric variables (a different one for each section). Is there a way of passing a variable to each of the calls above?

Thank you

Upvotes: 60

Views: 88015

Answers (6)

thetwopct
thetwopct

Reputation: 1681

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
}
?>

Upvotes: 149

Sayed Mohamed
Sayed Mohamed

Reputation: 183

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
?>

Upvotes: 3

Luca Murante
Luca Murante

Reputation: 317

A quick and dirty workaround can be made using PHP Constants:

In your theme:

define("A_CONSTANT_FOR_TEMPLATE_PART", "foo");
get_template_part("slug", "name" );

Now in slug-name.php template file you can use the A_CONSTANT_FOR_TEMPLATE_PART constant. Be sure not override system constants by using a custom prefix for your constant name.

In your template part file:

echo A_CONSTANT_FOR_TEMPLATE_PART;

You should see "foo".

Upvotes: -3

Nadav
Nadav

Reputation: 1819

Like mentioned by thetwopct - since WP 5.5, you can pass $args to the get_template_part function like so:

$value_of_first  = 'pizza';
$value_of_second = 'hamburger';
$value_of_first  = 'milkshake';

$args = array(
  'first'  => $value_of_first,
  'second' => $value_of_second,
  'third'  => $value_of_third,
)
get_template_part( 'element-templates/front', 'top', $args );

then, in element-templates/front-top.php get the vars like so:

[
  'first'  => $value_of_first,
  'second' => $value_of_second,
  'third'  => $value_of_third,
] = $args;
echo 'I like to eat '.$value_of_first.' and '.$value_of_second.' and then drink '.$value_of_third.';
// will print "I like to eat pizza and hamburger and then drink milkshake"

Note: the method described above for getting the vars in the template file uses associative array restructuring, available only from PHP 7.1. You can also do something like:

echo 'I like to eat '.$args[value_of_first].' and ...

Upvotes: 1

WPZA
WPZA

Reputation: 931

As of WordPress 5.5, you're be able to achieve this using the following method:

<?php
get_template_part( 
    'my-template-name', 
    null, 
    array( 
        'my_data' => array(
            'var_one' => 'abc',
            'var_two' => true,
        )
    )
);

In your template, you can then parse the date and escape it in the following way:

<?php
$args = wp_parse_args(
    $args,
    array(
        'my_data' => array(
            'var_one' => 'xyz', // default value
            'var_two' => false, // default value
        )
    )
);
?>
<?php echo esc_html( $args['my_data']['var_one'] ); ?>

Upvotes: 4

Nathan Dawson
Nathan Dawson

Reputation: 19308

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.

Upvotes: 6

Related Questions