Using Template Parts with Genesis

What makes Genesis so powerful are the actions and filters that allow you to customize every aspect of the framework.

Some of the actions are related to the Genesis loop. These control how posts are displayed, both on archive pages and as singular content. Sridhar has a nice introduction to the Genesis loop actions.

You can use template tags to determine what content is shown based on the page context. For instance, here’s the code in Genesis that displays the featured image on post archives.

On line 15, you’ll notice it only displays the featured image if ! is_singular(). This prevents the featured image from appearing at the top of your single posts.

add_action( 'genesis_entry_content', 'genesis_do_post_image', 8 );
add_action( 'genesis_post_content', 'genesis_do_post_image' );
/**
 * Echo the post image on archive pages.
 *
 * If this an archive page and the option is set to show thumbnail, then it gets the image size as per the theme
 * setting, wraps it in the post permalink and echoes it.
 *
 * @since 1.1.0
 */
function genesis_do_post_image() {

	if ( ! is_singular() && genesis_get_option( 'content_archive_thumbnail' ) ) {

		$img = genesis_get_image( array(
			'format'  => 'html',
			'size'    => genesis_get_option( 'image_size' ),
			'context' => 'archive',
			'attr'    => genesis_parse_attr( 'entry-image', array(
				'alt' => get_the_title(),
			) ),
		) );

		if ( ! empty( $img ) ) {

			genesis_markup( array(
 				'open'    => '<a %s>',
 				'close'   => '</a>',
 				'content' => wp_make_content_images_responsive( $img ),
 				'context' => 'entry-image-link',
 			) );

 		}

	}

}

This works for simpler sites, but as websites become more modular it presents an issue. I want to design a “post summary” module that’s used on archive pages and for related posts on the single post. Template tags aren’t sufficient because they relate to the current page type, not the specific context of the module.

What are template parts

Template parts – also referred to as template partials – are small files that hold reusable sections of code in a theme.

Here’s an example of my archive partial, used most often on archive pages to display a post summary:

<?php
/**
 * Archive partial
 *
 * @package      EAGenesisChild
 * @author       Bill Erickson
 * @since        1.0.0
 * @license      GPL-2.0+
**/

echo '<article class="post-summary">';

	echo '<a class="entry-image-link" href="' . get_permalink() . '" tabindex="-1" aria-hidden="true">' . get_the_post_thumbnail( get_the_ID(), 'medium' ) . '</a>';

	echo '<header class="entry-header">';
		echo '<h2 class="entry-title"><a href="' . get_permalink() . '">' . get_the_title() . '</a></h2>';
	echo '</header>';

	echo '<div class="entry-content">';
		the_excerpt();
		echo '<p><a class="read-more" href="' . get_permalink() . '" tabindex="-1" aria-hidden="true">Read More<span class="screen-reader-text"> of ' . get_the_title() . '</span></a></p>';
	echo '</div>';

echo '</article>';

If I want to list related posts, I loop through my custom query using the archive partial.

<?php

/**
 * Related Posts 
 * @link https://www.billerickson.net/related-posts-with-searchwp/
 *
 */
function be_related_posts() {
    
	$loop = new WP_Query( array(
		'post__in'  => ea_get_related_posts( 3 ),
		'orderby'   => 'post__in',
	) );
  
	if( $loop->have_posts() ):
		while( $loop->have_posts() ): $loop->the_post();
			get_template_part( 'partials/archive' );
		endwhile;
	endif;
	wp_reset_postdata();
}
add_action( 'genesis_after_entry', 'be_related_posts' );

Using on archive pages

In my recent Genesis child themes, we’ve replaced the default Genesis loop on archive pages with one that uses template parts. This gives us more freedom when leveraging the Genesis hooks elsewhere.

With this change, the Genesis loop hooks only run on the main post in the singular context. I know that genesis_entry_header will only run on single posts and pages, and won’t run on the related posts listed after the article.

To replace the Genesis loop on archive pages, I use the following code:

<?php
/**
 * Loop
 *
 * @package      EAGenesisChild
 * @author       Bill Erickson
 * @since        1.0.0
 * @license      GPL-2.0+
**/

/**
 * Use Archive Loop
 *
 */
function ea_use_archive_loop() {

	if( ! is_singular() ) {
		add_action( 'genesis_loop', 'ea_archive_loop' );
		remove_action( 'genesis_loop', 'genesis_do_loop' );
	}
}
add_action( 'genesis_setup', 'ea_use_archive_loop', 20 );

/**
 * Archive Loop
 * Uses template partials
 */
function ea_archive_loop() {

	if ( have_posts() ) {

		do_action( 'genesis_before_while' );

		while ( have_posts() ) {

			the_post();
			do_action( 'genesis_before_entry' );

			// Template part
			$partial = apply_filters( 'ea_loop_partial', 'archive' );
			$context = apply_filters( 'ea_loop_partial_context', is_search() ? 'search' : get_post_type() );
			get_template_part( 'partials/' . $partial, $context );

			do_action( 'genesis_after_entry' );

		}

		do_action( 'genesis_after_endwhile' );

	} else {

		do_action( 'genesis_loop_else' );

	}
}

You could place this directly in functions.php, or put it in a separate file and include that in functions.php.

For more guidance, take a look at my base Genesis theme, EA Genesis Child.

Downside

You’ll run into issues if you are using plugins that expect those actions and filters to be there. It won’t break your site, but you’ll lose the functionality those plugins were adding with the actions and filters that used to be on your archive page.

For instance, my Genesis Grid Loop plugin needs the post summaries to use post_class() so it can add column classes, and expects the Genesis featured image function so it can set the image size for “feature” posts. If you use the Genesis Grid Loop plugin with my EA Genesis Child theme, the archive pages won’t display in a grid as you’d expect. The plugin is using filters that now don’t run on the archive page.

If you use plugins for assembling your theme customizations, then this is not for you. But if you’re looking for a more modular way to develop your custom Genesis child themes, consider using template parts.

Bill Erickson

Bill Erickson is the co-founder and lead developer at CultivateWP, a WordPress agency focusing on high performance sites for web publishers.

About Me
Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk

Reader Interactions

Comments are closed. Continue the conversation with me on Twitter: @billerickson

Comments

  1. Ken Dawes says

    Great stuff Bill!!

    I have a question on Using Template Parts/ EA Genesis child…

    Is there a way to include/allow content entered on the Blog page to show above the blog excerpts?

    Thanks!!!