There is a cool feature in WordPress if you working with repeaters: the template system. And I’m not talking about templates in the sense of themes, blocks or similar, but of a JavaScript feature many people might not know (or forgot about). It lets you easily display a certain template in JavaScript for a set of identical items. So if you have a list of items and want to display them in an identical way, it’s the ideal solution to use it.

It’s available as wp.template and aside of a single page in the JavaScript reference in the codex there doesn’t seem to be much documentation about it. So let’s change that.

The template

First, let’s create the template itself. This is basically HTML inside a script tag, which has a certain ID and type. To work as template, the script tag should be the type of text/html and the ID must start with tmpl-:

<script type="text/html" id="tmpl-my-item">
	<!-- HTML code -->
</script>Code language: HTML, XML (xml)

Inside your HTML code, you can use variable interpolation and logical evaluations. This is something, the reference above makes clear:

  • Interpolate (unescaped): {{{ }}}
  • Interpolate (escaped): {{ }}
  • Evaluate: <# #>

An example:

<script type="text/html" id="tmpl-my-item">
	<div>
		<h3>{{ data.title }}</h3>
		
		<code>{{{ data.code }}}</code>
	</div>
</script>Code language: HTML, XML (xml)

But where does data come from? To answer this, let’s take a look into the JavaScript part.

The JavaScript

Using the template in JavaScript is just 2 lines of code:

const template = wp.template( 'my-item' );
const html = template();Code language: JavaScript (javascript)

First, you get the template as function in the variable template (where my-item is the part of your template ID after the prefix tmpl-) and then you call the function and store it in html to get the actual HTML value. Since it’s designed to be working in jQuery, you will get the actual HTML code as string. So you can use it in jQuery by using $( element ).html( html ), where element is some element on your page. If you’re not using jQuery, you can also use insertAdjacentHTML to append the template via element.insertAdjacentHTML( 'beforeend', html ).

Parameters

But what about the data parameter above?

For each item you want to generate using the template system, you can pass an object to the template() function, which can then be used as data object:

const itemData = {
	code: '<?php \phpinfo();',
	title: 'My title',
};
const template = wp.template( 'my-item' );
const html = template( itemData );Code language: JavaScript (javascript)

By passing itemData to the template() function, you can use all its properties and data inside the template as seen in the example above.

Evaluation

If you need to have some logic in the code, e.g. displaying content only if certain criteria matches, you can use evaluation:

<script type="text/html" id="tmpl-my-item">
	<div>
		<h3>{{ data.title }}</h3>
		
		<# if ( data.code ) { #>
			<code>{{{ data.code }}}</code>
		<# } #>
	</div>
</script>Code language: HTML, XML (xml)

Here, I wrapped the <code> block to only be displayed if the property exists. Otherwise, an empty <code> block would be rendered.

Dependencies

As already mentioned, wp.template requires jQuery. Itself it’s included inside the wp-util handle, so while enqueuing your script, make sure to add wp-util as dependency. This may look something like this in your PHP code:

static function my_enqueue_scripts(): void {
	\wp_enqueue_script( 'my-handle', 'my-source.js', [ 'wp-util' ], \filemtime( 'my-source.js' ), [ 'strategy' => 'defer' ] );
}

\add_action( 'admin_enqueue_scripts', 'my_enqueue_scripts' );Code language: PHP (php)

Conclusion

wp.template is a handy tool to repeatedly output similar content in WordPress. It’s also often used with Ajax requests when you want to get a part of a page as HTML. Since it can also handle variables and even logic, is is super powerful.

One downside though is that it’s requiring jQuery to be loaded since it’s dependent on it. If you don’t like it, look in the source code, it shouldn’t be that hard to make it dependency-free.

Leave a Reply

Your email address will not be published. Required fields are marked *