Learning Vue.js as a WordPress Developer Part 5 – Decoupled Page Template


This post is part of a series called “Learning Vue.js as a WordPress Developer”

Creating a custom page template is an easy way to start building something with Vue.js mixed with WordPress data. However this setup comes with a big disadvantage. That is having to deal with CSS conflicts that happen between Vue.js and the rest of the WordPress header wp_head(). This is especially true when using a component framework like Vuetify.js.

Removing wp_head() from the custom page template allows for a clean break however that also means WordPress specific things like authentication and favicons will stop working. The following approach allows you to remove wp_head() from a custom page template while keeping similar functionality.

There’s a Regex for that.

So this is by no means a clean solution. In fact it’s really quite messy. It involves running the output of wp_head() through a pattern match in order to pull out a few lines in order to keep specific WordPress functionality working. Before getting into that, take a look at the following regular expressions I created using regexr.com and the output of my WordPress header.

Regular expression targeting Javascript variable wpApiSettings
Regular expression targeting favicons

Custom header with lines extracted from wp_head action.

For this method to work, you first need to get the output of wp_head() into a variable. You can use some fancy PHP to do the trick as shown here.

function captaincore_head_content() {
    ob_start();
    do_action('wp_head');
    return ob_get_clean();
}

Now we can assign that function to a variable like so $head = captaincore_head_content(); and extract various lines using the regular expressions that were created above. Check that here.

function captaincore_header_content_extracted() {
	$output = "<script type='text/javascript'>\n/* <![CDATA[ */\n";
	$head = captaincore_head_content();
	preg_match_all('/(var wpApiSettings.+)/', $head, $results );
	if ( isset( $results ) && $results[0] ) {
		foreach( $results[0] as $match ) {
			$output = $output . $match . "\n";
		}
	}
	$output = $output . "</script>\n";
	preg_match_all('/(<link rel="(icon|apple-touch-icon).+)/', $head, $results );
	if ( isset( $results ) && $results[0] ) {
		foreach( $results[0] as $match ) {
			$output = $output . $match . "\n";
		}
	}
	echo $output;
}

Finally this new captaincore_header_content_extracted() can be inserted at the top of our custom page template as a replacement for wp_head().

<?php
/**
* Template Name: Vue.JS custom template
*/
?><!DOCTYPE html>
<html>
<head>
  <title>Single page Vue.JS custom template</title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1, user-scalable=no, minimal-ui">
  <meta charset="utf-8">
<?php
// Load favicons and wpApiSettings from normal WordPress header
captaincore_header_content_extracted();
?>