jdsteinbach
8/31/2015 - 4:12 PM

Including PHP partials

Including PHP partials

We're already great with breaking giant template files into multiple smaller files in an /includes/ or /partials/ directory. I'd to talk about how we call those files in our bigger templates. The three options are include, require, and get_template_part(). The first 2 are normal PHP functions, the 3rd is a WP function. (I'm only going to really compare include and get_template_part() though: require is basically include + fatal error, so no real reason to use that by default in our own themes.)

PHP include 'file-path/file-name.php PHP docs

The include function is our default right now. It's got a couple pros over the other options: unlike require, it only generates a warning if the file isn't found, not a fatal error. Unlike get_template_part(), it respects the current file's variables.

WP get_template_part() WP Codex

This is the preferred "WP Way" to get content from a partial/modular file. It's a function that takes 2 arguments: the "slug" for the included file (which can include a directory name & /) and the "name" to require a file that matches the $slug-$name.php pattern:

get_template_part( 'content', 'page' );
// ^ looks for `content-page.php`, falls back to `content.php`

get_template_part( 'partials/section', 'cptslug' );
// ^ looks for `partials/section-cptslug.php`, falls back to `partials/section.php`

The WP reason to use this function is its fallback methods. I don't consider that a strong reason for us to use it, since we control the names of our files and don't rely on fallbacks. This function is also recommended for the sake of dynamically generating the slug or name:

get_template_part( 'content', get_post_format() );

… but that can be accomplished with PHP too (though arguably, it's not as "clean" looking):

include 'content-' . get_post_format() . '.php;

My biggest concern with get_template_part() is its lack of respect for current variables. Even though the Codex says that this function is a wrapper around require, it doesn't respect variable declarations like I'd expect require to do:

$page_meta = get_fields();
// ACF function
echo '<h1 class="page-title">' . $page_meta['custom_title'] . '</h1>';

get_template_part( 'partials/section', 'first' );
get_template_part( 'partials/section', 'second' );

echo '<div class="page-sub-text">' . $page_meta['page_sub_text'] . '</div>';

In this scenario, partials/section-first.php and partials/section-second.php will not have access to the $page_meta array unless we explicitly declare it a global variable and reference that global variable in those partials. That's a major flaw, IMO, and more than enough reason to stick with include until WP changes this (if it's even possible within the current 3+-layered PW function (get_template_part() -> locate_template() -> load_template() -> require_once()).

All that to say, if you see any "why/how you should use get_template_part() posts (and a few have been published recently), feel free to disregard them. We're doing what's best for us.