web-dev-qa-db-de.com

Übergabe einer Variablen an get_template_part

Der WP Codex sagt dies zu tun:

// 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' );

Aber wie kann ich echo $my_var innerhalb des Vorlagenteils? get_query_var($my_var) funktioniert bei mir nicht.

Ich habe unzählige Empfehlungen für die Verwendung von locate_template gesehen. Ist das der beste Weg?

51
Florian

Da Posts ihre Daten über the_post() (bzw. über setup_postdata()) einrichten und daher über die API zugänglich sind (z. B. get_the_ID()), nehmen wir an, dass wir eine Gruppe von Benutzern durchlaufen (als setup_userdata() füllt die globalen Variablen von der momentan eingeloggt Benutzer und ist für diese Aufgabe nicht nützlich) und versuche Metadaten pro Benutzer anzuzeigen:

<?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' );
}

Dann müssen wir in unserer wpse-theme/template-parts/user-contact_methods.php-Datei auf die Benutzer-ID zugreifen:

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

Das ist es.

Die Erklärung liegt genau über dem Teil, den Sie in Ihrer Frage angegeben haben:

load_template(), das indirekt von get_template_part() aufgerufen wird, extrahiert jedoch alle WP_Query-Abfragevariablen in den Bereich der geladenen Vorlage.

Die native PHP extract() -Funktion "extrahiert" die Variablen (die Eigenschaft global $wp_query->query_vars) und fügt jeden Teil in eine eigene Variable ein, die genau den gleichen Namen wie der Schlüssel hat. Mit anderen Worten:

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'
49
kaiser

Die hm_get_template_part Funktion von humanmade ist extrem gut darin und ich benutze sie die ganze Zeit.

Du rufst an

hm_get_template_part( 'template_path', [ 'option' => 'value' ] );

und dann verwenden Sie in Ihrer Vorlage

$template_args['option'];

um den Wert zurückzugeben. Es macht Caching und alles, obwohl Sie das herausnehmen können, wenn Sie möchten.

Sie können die gerenderte Vorlage sogar als Zeichenfolge zurückgeben, indem Sie 'return' => true in das Array key/value übergeben.

/**
 * Like get_template_part() put lets you pass args to the template file
 * Args are available in the tempalte as $template_args array
 * @param string filepart
 * @param mixed wp_args style argument list
 */
function hm_get_template_part( $file, $template_args = array(), $cache_args = array() ) {
    $template_args = wp_parse_args( $template_args );
    $cache_args = wp_parse_args( $cache_args );
    if ( $cache_args ) {
        foreach ( $template_args as $key => $value ) {
            if ( is_scalar( $value ) || is_array( $value ) ) {
                $cache_args[$key] = $value;
            } else if ( is_object( $value ) && method_exists( $value, 'get_id' ) ) {
                $cache_args[$key] = call_user_method( 'get_id', $value );
            }
        }
        if ( ( $cache = wp_cache_get( $file, serialize( $cache_args ) ) ) !== false ) {
            if ( ! empty( $template_args['return'] ) )
                return $cache;
            echo $cache;
            return;
        }
    }
    $file_handle = $file;
    do_action( 'start_operation', 'hm_template_part::' . $file_handle );
    if ( file_exists( get_stylesheet_directory() . '/' . $file . '.php' ) )
        $file = get_stylesheet_directory() . '/' . $file . '.php';
    elseif ( file_exists( get_template_directory() . '/' . $file . '.php' ) )
        $file = get_template_directory() . '/' . $file . '.php';
    ob_start();
    $return = require( $file );
    $data = ob_get_clean();
    do_action( 'end_operation', 'hm_template_part::' . $file_handle );
    if ( $cache_args ) {
        wp_cache_set( $file, $data, serialize( $cache_args ), 3600 );
    }
    if ( ! empty( $template_args['return'] ) )
        if ( $return === false )
            return false;
        else
            return $data;
    echo $data;
}
23
djb

Ich habe mich umgesehen und eine Vielzahl von Antworten gefunden. Wordpress scheint auf einer nativen Ebene zu sein und ermöglicht den Zugriff auf Variablen in Template-Teilen. Ich stellte fest, dass die Verwendung des Include in Verbindung mit locate_template den Zugriff auf den Gültigkeitsbereich der Variablen in der Datei ermöglichte.

include(locate_template('your-template-name.php'));
11
Murray Chapman
// you can use any value including objects.

set_query_var( 'var_name_to_be_used_later', 'Value to be retrieved later' );
//Basically set_query_var uses PHP extract() function  to do the magic.


then later in the template.
var_dump($var_name_to_be_used_later);
//will print "Value to be retrieved later"

Ich empfehle, über die Funktion PHP Extract () zu lesen.

3
Hugo R

Ich bin auf dasselbe Problem bei einem Projekt gestoßen, an dem ich gerade arbeite. Ich habe mich dazu entschlossen, ein eigenes kleines Plugin zu erstellen, mit dem Sie Variablen mithilfe einer neuen Funktion expliziter an get_template_part übergeben können.

Für den Fall, dass Sie es nützlich finden, finden Sie hier die Seite auf GitHub: https://github.com/JolekPress/Get-Template-Part-With-Variables

Und hier ist ein Beispiel, wie es funktionieren würde:

$variables = [
    'name' => 'John',
    'class' => 'featuredAuthor',
];

jpr_get_template_part_with_vars('author', 'info', $variables);


// In author-info.php:
echo "
<div class='$class'>
    <span>$name</span>
</div>
";

// Would output:
<div class='featuredAuthor'>
    <span>John</span>
</div>
2
John O

Ich mag das Pods Plugin und deren pods_view Funktion. Es funktioniert ähnlich wie die in der Antwort von djb erwähnte Funktion hm_get_template_part. Ich verwende eine zusätzliche Funktion (findTemplate im folgenden Code), um zuerst im aktuellen Design nach einer Vorlagendatei zu suchen. Wird diese nicht gefunden, wird die Vorlage mit demselben Namen im /templates-Ordner meines Plugins zurückgegeben. Dies ist eine ungefähre Vorstellung davon, wie ich pods_view in meinem Plugin verwende:

/**
 * Helper function to find a template
 */
function findTemplate($filename) {
  // Look first in the theme folder
  $template = locate_template($filename);
  if (!$template) {
    // Otherwise, use the file in our plugin's /templates folder
    $template = dirname(__FILE__) . '/templates/' . $filename;
  }
  return $template;
}

// Output the template 'template-name.php' from either the theme
// folder *or* our plugin's '/template' folder, passing two local
// variables to be available in the template file
pods_view(
  findTemplate('template-name.php'),
  array(
    'passed_variable' => $variable_to_pass,
    'another_variable' => $another_variable,
  )
);

pods_view unterstützt auch das Cachen, aber das habe ich für meine Zwecke nicht benötigt. Weitere Informationen zu den Funktionsargumenten finden Sie auf den Pods-Dokumentationsseiten. Siehe die Seiten für pods_view und Partial Page Caching und Smart Template Parts with Pods .

1
thirdender

Basierend auf der Antwort von @djb unter Verwendung von Code von humanmade.

Dies ist eine kompakte Version von get_template_part, die Argumente akzeptieren kann. Auf diese Weise werden Variablen lokal auf diese Vorlage beschränkt. global, get_query_var, set_query_var müssen nicht vorhanden sein.

/**
 * Like get_template_part() but lets you pass args to the template file
 * Args are available in the template as $args array.
 * Args can be passed in as url parameters, e.g 'key1=value1&key2=value2'.
 * Args can be passed in as an array, e.g. ['key1' => 'value1', 'key2' => 'value2']
 * Filepath is available in the template as $file string.
 * @param string      $slug The slug name for the generic template.
 * @param string|null $name The name of the specialized template.
 * @param array       $args The arguments passed to the template
 */

function _get_template_part( $slug, $name = null, $args = array() ) {
    if ( isset( $name ) && $name !== 'none' ) $slug = "{$slug}-{$name}.php";
    else $slug = "{$slug}.php";
    $dir = get_template_directory();
    $file = "{$dir}/{$slug}";

    ob_start();
    $args = wp_parse_args( $args );
    $slug = $dir = $name = null;
    require( $file );
    echo ob_get_clean();
}

Zum Beispiel in cart.php:

<? php _get_template_part( 'components/items/Apple', null, ['color' => 'red']); ?>

In Apple.php:

<p>The Apple color is: <?php echo $args['color']; ?></p>
1
Veedka

Wie wäre es damit?

render( 'template-parts/header/header', 'desktop', 
    array( 'user_id' => 555, 'struct' => array( 'test' => array( 1,2 ) ) )
);
function render ( $slug, $name, $arguments ) {

    if ( $arguments ) {
        foreach ( $arguments as $key => $value ) {
                ${$key} = $value;
        }
    }

$name = (string) $name;
if ( '' !== $name ) {
    $templates = "{$slug}-{$name}.php";
    } else {
        $templates = "{$slug}.php";
    }

    $path = get_template_directory() . '/' . $templates;
    if ( file_exists( $path ) ) {
        ob_start();
        require( $path);
        ob_get_clean();
    }
}

Mit ${$key} können Sie die Variablen zum aktuellen Funktionsumfang hinzufügen. Funktioniert für mich schnell und einfach und es tritt nicht aus oder wird nicht im globalen Bereich gespeichert.

0
Mattijs