Query Vars, Post Titles, and Yoast SEO

How to customize your post titles with query variables and Yoast SEO.

Most people who use WordPress use query vars every single day without knowing. Back in the old days, we used to have websites with URLs like example.com/?p=123 and we called those ‘ugly’ permalinks. This encouraged everyone to make pretty ones, like example.com/2018/post-name/ instead. What many people don’t realize is that those ?p=123 calls are query variables.

WordPress, and most modern CMS tools, take that pretty permalink, translate it back to a query variable, and go get the post ID with 123. The variable p (which stands for post) has a value of 123. It makes sense.

And you can make your own.

Pretty URLs Are Better

If you have a choice of telling people to visit example.com/?p=123 or example.com/2018/post-name/, I feel confident most of you will pick the latter. And if you’re writing code and you need a consistent location to call, would you rather try to assume that everyone’s using wp-content and look for example.com/wp-content/plugins/myplugin/my-file.php or would you rather use example.com/myplugin/?

Now. This post is not about how to make those awesome virtual pages. There are some good tutorials like Metabox.io’s to get you started there. This is about when you have a slightly different scenario.

Using Query Variables in Titles

For a number of reasons, I have a page built out to manage my custom query calls. This allows me to edit the content of the page like it was, well, a page! Anyone can edit the page content, change the information, and then everything else is magically generated, it can be easily tweaked to fit my theme, and it basically works for me.

What doesn’t work well is that all the pages have the same title. And that, as we all know, is bad SEO. I don’t want all my pages to have the same title, and it’s confusing for users because they go to example.com/my-thing/sub-thing/ and example.com/my-thing/other-thing/ so logically the page title should be different, right?

Changing the display title on the page isn’t too terrible. I have this code at the top of the page to grab the query variable:

$my_thing = ( isset($wp_query->query['my_thing'] ) )? $wp_query->query['my_thing'] : 'main' ;

And then when I echo the title, I do this:

<h1 class="entry-title">My Thing
	<?php 
		$title = ( 'main' !== $my_thing )? ' on ' . ucfirst( $my_thing ) : 's';
		echo $title;
	?>
</h1>

Which means my titles are either “My Things” or “My Thing on That”. If I had multiple ‘words’ in my query variables (separated by a – of course) then I’d use a string replace and capitalize each word with ucwords().

But Page Titles aren’t Title Titles

The problem is the page title isn’t the … well … title title. Have you ever looked at your browser bar? Assuming you don’t have 94 tabs open at once…

A browser with a lot of tabs open, to the point you may have no idea what's in any of them...

Then your browser would look a little like this:

A sane number of tabs open, where you can read the title of each tab

Imagine if they all said “My Things | Half-Elf on Tech”? Well that would suck. It sucks for you reading, it sucks for screenreaders, and if you have Yoast SEO, it’s quite easy to fix.

Custom Yoasty Variables and Titles

Step one is to revisit something I did two years ago, making a custom Yoast SEO variable. This time I want to make a variable for %%mything%%:

wpseo_register_var_replacement( '%%mything%%', array( $this, 'yoast_retrieve_mything_replacement' ), 'basic', 'The type of thing page we\'re on.' );

And the code will be to grab the query variable and parse it:

function yoast_retrieve_mything_replacement( ) {
	$my_thing = get_query_var( 'my_thing', 'none' );
	$return   = ( 'none' !== $my_thing )? 'on ' . ucfirst( $my_thing ) : '';
	return $return;
}

Step 2 is going into the page, popping open the snippet editor, and making the title this:

The Yoast Snippet

And then? Pour a beer and watch some sports.

%d bloggers like this: