Gutenberg Sidebar – Loading a Template Based on Post Meta

Gutenberg Sidebar - Loading a Custom Template Based on Post Meta

To load in our template via post meta, we need to hook into the WordPress template loader. This assumes we have a template to begin with. Let’s create a template class and the actual template file in our plugin structure. We’ll create a class-template.php file in our includes folder and a landing-page.php file in a templates folder.

Here is our updated file structure:

. └── landing-page-gutenberg-template/ ├── landing-page-gutenberg-template.php ├── includes/ │ ├── class-enqueue.php │ ├── class-meta-boxes.php │ └── class-template.php └── templates/ ├── index.php (blank file) └── landing-page.php
Code language: AsciiDoc (asciidoc)

The Landing Page

First, we’ll output a generic “Hello World” in our landing-page.php file. We’ll be calling this in a minute and you’ll see what kind of magic we’re trying to pull with post meta.

<?php /** * Template inclusion file template. * * @package wpandajax */ if ( ! defined( 'ABSPATH' ) ) { die( 'you are way off' ); } echo "Hello World";
Code language: PHP (php)

The ABSPATH check is to make sure the file is loaded in the context of WordPress. If not, someone will see that die statement if the file is accessed directly. We’ll fill in the innards of the landing page in the next (and last post) in the series.

The Template Loader Class

In class-template.php, we’ll create a classic runner that will be initialized in the main plugin file.

<?php /** * Overrides the page/singular template. * * @package wpajax */ namespace WPAndAjax\Includes; /** * Loads in the right template file based on the post meta options. */ class Template { /** * Class runner. * * @since 1.0.0 */ public function run() { add_filter( 'template_include', array( $this, 'maybe_load_template' ) ); } /** * Load a custom full-screen template for the twentty twenty one theme. * * @param string $template Template to be loaded from theme. */ public function maybe_load_template( $template ) { return $template; } }
Code language: PHP (php)

The above class, when instantiated and run, will filter the WordPress template via the template_include filter. It has a callback method of maybe_load_template, which at this point just returns the original template and has no internal logic yet.

And finally we wire it up in the main plugin class in landing-page-gutenberg-template.php:

/** * Fired when the plugins for WordPress have finished loading. */ public function plugins_loaded() { // Admin enqueue actions. $this->admin_enqueue = new \WPAndAjax\Includes\Enqueue(); $this->admin_enqueue->run(); $this->meta_boxes = new \WPAndAjax\Includes\Meta_Boxes(); $this->meta_boxes->run(); $this->template = new \WPAndAjax\Includes\Template(); $this->template->run(); }
Code language: PHP (php)

Reading in the Meta in the Template Loader

Let’s concentrate on editing the class-template file to point to our “Hello World” landing page in the templates folder.

. └── landing-page-gutenberg-template/ ├── landing-page-gutenberg-template.php ├── includes/ │ ├── class-enqueue.php │ ├── class-meta-boxes.php │ └── class-template.php └── templates/ ├── index.php (blank file) └── landing-page.php
Code language: AsciiDoc (asciidoc)

I’ll go ahead and post the full code and dissect the tricky parts.

/** * Load a custom full-screen template for the twentty twenty one theme. * * @param string $template Template to be loaded from theme. */ public function maybe_load_template( $template ) { if ( is_admin() || is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) { return $template; } // Make sure we're at the right level of content. if ( ! is_page() && ! is_singular() ) { return $template; } // Get the post ID. Could also use get_queried_object_id? Less reliable IMO. global $post; if ( ! isset( $post->ID ) ) { return $template; } $post_id = $post->ID; // Try to get post meta. False so we expect an array. $maybe_enable_landing_page_template = get_post_meta( $post_id, '_wpajax_enable_landing_template', false ); // If post ID is invalid, get_post_meta should return false. Return. if ( ! $maybe_enable_landing_page_template && ! is_array( $maybe_enable_landing_page_template ) ) { return $template; } // Array check. if ( ! is_array( $maybe_enable_landing_page_template ) ) { return $template; } // Now lets get the first value of the array. $maybe_post_meta_value = false; if ( isset( $maybe_enable_landing_page_template[0] ) ) { $maybe_post_meta_value = current( $maybe_enable_landing_page_template ); } // Validate boolean. $maybe_post_meta_value = filter_var( $maybe_post_meta_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); if ( is_null( $maybe_post_meta_value ) || false === $maybe_post_meta_value ) { return $template; } $maybe_template = WPAJAX_LANDING_DIR . 'templates/landing-page.php'; if ( file_exists( $maybe_template ) ) { return $maybe_template; } return $template; }
Code language: PHP (php)

Conditional Checks to Bail Early

First we do some conditionals to make sure we’re in the right place to be running our template inclusion code, which will be very processor intensive if we were to run a meta check on every single template being loaded via WordPress.

First, we make sure we’re not in the admin panel, are not running when an Ajax request is going on, and that we’re on a singular post or page, which pretty much covers most of our bases.

if ( is_admin() || is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) { return $template; } // Make sure we're at the right level of content. if ( ! is_page() && ! is_singular() ) { return $template; }
Code language: PHP (php)

Ensuring We’re On a Post or Page

Next is a sanity check to make sure that we’re again in the context of a single post.

// Get the post ID. Could also use get_queried_object_id? Less reliable IMO. global $post; if ( ! isset( $post->ID ) ) { return $template; } $post_id = $post->ID;
Code language: PHP (php)

Checking Post Meta Validity

Next we try to get the post meta. If it’s not set, we return the original template.

// Try to get post meta. False so we expect an array. $maybe_enable_landing_page_template = get_post_meta( $post_id, '_wpajax_enable_landing_template', false ); // If post ID is invalid, get_post_meta should return false. Return. if ( ! $maybe_enable_landing_page_template && ! is_array( $maybe_enable_landing_page_template ) ) { return $template; }
Code language: PHP (php)

Next up is a possibly redundant array check. I guess we can never be too careful.

// Array check. if ( ! is_array( $maybe_enable_landing_page_template ) ) { return $template; }
Code language: PHP (php)

Testing the Retrieved Meta Value

Up next is getting the boolean value of the meta key and determining if it is set to true. If our meta key value is not true, that means the user has not selected the landing page option and we are to return the template. If it is true, then we need to start loading up our template.

// Now lets get the first value of the array. $maybe_post_meta_value = false; if ( isset( $maybe_enable_landing_page_template[0] ) ) { $maybe_post_meta_value = current( $maybe_enable_landing_page_template ); } // Validate boolean. $maybe_post_meta_value = filter_var( $maybe_post_meta_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); if ( is_null( $maybe_post_meta_value ) || false === $maybe_post_meta_value ) { return $template; }
Code language: PHP (php)

Loading the Landing Page Template

And finally, we set up a path to the landing page template path, see if it exists, and return it. By default, if all else fails, we just return the regular template.

$maybe_template = WPAJAX_LANDING_DIR . 'templates/landing-page.php'; if ( file_exists( $maybe_template ) ) { return $maybe_template; } return $template;
Code language: PHP (php)

The Full File

Scan it again at your leisure (syntax highlighting is free on the web):

<?php /** * Overrides the page/singular template. * * @package wpajax */ namespace WPAndAjax\Includes; /** * Loads in the right template file based on the post meta options. */ class Template { /** * Class runner. * * @since 1.0.0 */ public function run() { add_filter( 'template_include', array( $this, 'maybe_load_template' ) ); } /** * Load a custom full-screen template for the twentty twenty one theme. * * @param string $template Template to be loaded from theme. */ public function maybe_load_template( $template ) { if ( is_admin() || is_admin() && defined( 'DOING_AJAX' ) && DOING_AJAX ) { return $template; } // Make sure we're at the right level of content. if ( ! is_page() && ! is_singular() ) { return $template; } // Get the post ID. Could also use get_queried_object_id? Less reliable IMO. global $post; if ( ! isset( $post->ID ) ) { return $template; } $post_id = $post->ID; // Try to get post meta. False so we expect an array. $maybe_enable_landing_page_template = get_post_meta( $post_id, '_wpajax_enable_landing_template', false ); // If post ID is invalid, get_post_meta should return false. Return. if ( ! $maybe_enable_landing_page_template && ! is_array( $maybe_enable_landing_page_template ) ) { return $template; } // Array check. if ( ! is_array( $maybe_enable_landing_page_template ) ) { return $template; } // Now lets get the first value of the array. $maybe_post_meta_value = false; if ( isset( $maybe_enable_landing_page_template[0] ) ) { $maybe_post_meta_value = current( $maybe_enable_landing_page_template ); } // Validate boolean. $maybe_post_meta_value = filter_var( $maybe_post_meta_value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE ); if ( is_null( $maybe_post_meta_value ) || false === $maybe_post_meta_value ) { return $template; } $maybe_template = WPAJAX_LANDING_DIR . 'templates/landing-page.php'; if ( file_exists( $maybe_template ) ) { return $maybe_template; } return $template; } }
Code language: PHP (php)

Conclusion

At this point, if you enable the sidebar, you should see a Hello World when viewing the post. Here’s a demo in animated gif form.

Hello World Landing Page Template
Hello World Landing Page Template

Next up is loading all the blocks in the template.