Using PHP in Patterns

One of the biggest advantages of patterns over features like templates and template parts is that you can use PHP in them, which opens a world of possibilities for what you can accomplish. However, there are limits on what functionality is available to your patterns.

In this article, you will learn the limitations of the patterns system, when and how you can use PHP, and some of the most common use cases for dynamic functionality.

Patterns are registered on init

When using PHP in patterns, it’s important to understand when the pattern’s block markup is actually compiled versus when it is rendered.

Pattern registration happens on the init hook. At this point, WordPress compiles the content of the pattern and saves a copy of it as HTML-based block markup. This allows it to be used in both the editor and the front end. It’s during this registration process where the pattern can execute PHP code.

A pattern’s block markup is not actually rendered until it is used either in the editor or on the front end. However, the block markup is plain HTML at the time it is rendered.

At a practical level, this means that a lot of data is unavailable during the registration process on init. Your patterns cannot access things like the global query or post. They also cannot use functions associated with that data. So this means that WordPress functions like is_home(), is_single(), get_post(), and others are simply not ready yet.

For example, this PHP wouldn’t execute correctly in a pattern:

<?php if ( is_page() ) : ?>
	<!-- wp:paragraph -->
	<p><?php the_title(); ?></p>
	<!-- /wp:paragraph -->
<?php endif; ?>

Neither the is_page() nor the the_title() functions have the global data they need when a pattern is registered, so they won’t work.

If you’re accustomed to building classic themes, this can feel very unintuitive, especially if you’ve been equating PHP-based patterns to classic, PHP-based template parts.

There are other methods for executing PHP at the time of render, such as using the Block Bindings API. But those methods are outside the scope of pattern documentation.

You still have a wide and wonderful range of PHP functions and many WordPress functions available to you. And you’ll learn more about what you can use in the upcoming sections of this article.

An example pattern

For the rest of this article, let’s use a single pattern that begins as mostly HTML. Then, you’ll walk through adding PHP to dynamically handle some portions of it. 

Create a new file named patterns/hero.php in your theme and put this code into it:

<?php
/**
 * Title: Hero
 * Slug: themeslug/hero
 * Categories: featured
 */
?>
<!-- wp:cover {"overlayColor":"contrast","isUserOverlayColor":true,"align":"full"} -->
<div class="wp-block-cover alignfull">
	<span aria-hidden="true" class="wp-block-cover__background has-contrast-background-color has-background-dim-100 has-background-dim"></span>
	<div class="wp-block-cover__inner-container">
		
		<!-- wp:heading {"textAlign":"center"} -->
		<h2 class="wp-block-heading has-text-align-center">Welcome to My Site</h2>
		<!-- /wp:heading -->

		<!-- wp:paragraph {"align":"center"} -->
		<p class="has-text-align-center">This is my little home away from home.</p>
		<!-- /wp:paragraph -->

		<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
		<div class="wp-block-buttons">
			<!-- wp:button {"className":"wp-block-button is-style-outline"} -->
			<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button">Button A</a></div>
			<!-- /wp:button -->
			<!-- wp:button {"className":"wp-block-button is-style-outline"} -->
			<div class="wp-block-button is-style-outline"><a class="wp-block-button__link wp-element-button">Button B</a></div>
			<!-- /wp:button -->
		</div>
		<!-- /wp:buttons -->

	</div>
</div>
<!-- /wp:cover -->

If you insert it the pattern into the editor, it should look like this: