Article

Template Routes for Single Entry / Permalink URLs

by: James Mathias on: 12/10/2016 | Read in 3 minutes

Single entry permalink URLs are common on the web. We’re going to apply it to a blog here, as that’s readily understood, but the pattern will work for everything else as well.

By default ExpressionEngine’s URLs work like this https://example.com/blog/entry/url-title, where “blog” is a template group, and “entry” is a template, which is fine. But nicer would be something like https://example.com/blog/url-title, cause who needs that extra entry segment anyway? You could handle all of this in the blog template group’s index, but that’s inelegant, full of conditionals, hard to read, and hard to maintain.

Template Routes give us an easy to create and maintain implementation. What you’ll need is the following. A blog template group with the templates index and single-entry.

Inside of index you’ll put your blog listing, this will cover paginated archives, and categorized listings as well—URLs like https://example.com/blog/P15 and https://example.com/blog/category/cat-url-title.

Index might look something like this:

{exp:channel:entries channel='blog' limit='25'}
	<div class="blog-entry">
		<h2><a href="{route='blog/single-entry' url_title='{url_title}'}">{title}</a></h2>
		<p>{entry_date format='%n/%j/%Y'}</p>
		{if has_categories}
			<p><b>in</b>: {categories backspace='2'}<a href="{path='blog'}" title="View more in {category_name}">{category_name}</a>, {/categories}</p>
		{/if}
		<p>by: {author}</p>
	</div>

	{if no_results}
		{redirect='404'}
	{/if}
{/exp:channel:entries}

See that route= variable above? It’ll come into play in a moment. Next you’ll need a single-entry template that will cover your, well, single entries. And will be reached with URLs like https://example.com/blog/url-title.

Single Entry will look something like this:

{exp:channel:entries channel='blog' limit='1' require_entry='yes'}
	<h1>{title}</h1>
	<p>{entry_date format='%n/%j/%Y'}</p>
	{if has_categories}
		<p><b>in</b>: {categories backspace='2'}<a href="{path='blog'}" title="View more in {category_name}">{category_name}</a>, {/categories}</p>
	{/if}
	<p>by: {author}</p>

	{blog_content}

	{if no_results}
		{redirect='404'}
	{/if}
{/exp:channel:entries}

Now that you have those set up, you need to add your route. Go to Developer > Template Manager > Template Routes and set up a route for the template single-entry Give it a Route of /blog/{url_title:regex[(((?!(P\d+|category\/)).)+?)]} select “no” for “Segments Required?” then save. The regex may look a little complex, so let’s break it down. (((?!(P\d+|category\/)).)+?) uses a negative lookahead assertion, so the route does not match if the second URL segment is either pagination (P\d+) or category/. We want those URL patterns to still use the ExpressionEngine default routing to the blog/index template.

Now in your templates replace any path variables to your single-entry URLs to use the route= variable in the first code sample. This will make sure that when clicked the visitor is sent to the right place!

That’s it! Now go forth and clean up your ExpressionEngine URLs today!

James Mathias

Father of four, husband of one, Internet improver, gamer, fitness amateur, artist, writer + outlaw.

Have ideas on how to improve this article? .(JavaScript must be enabled to view this email address) or share your feedback with @ellislab on Twitter.

ExpressionEngine News

#eecms, #events, #releases