EE generates friendly, human readable URLs from its entry titles, templates, and template groups. However, its possible to make them even friendlier. This tutorial will show you how you can keep your URLs clean, concise and as friendly as possible. (For discussion of this tutorial, see this thread in the EE Design forum).
Goal:
Instead of: www.yoursite.com/index.php/weblog/more/some-long-title
We want: www.yoursite.com/weblog/some-long-title
We will do this two ways:
1. Removing index.php from the URL, and
2. Removing the need for a “more” template (aka “article” or “entry” template) appearing in the url when displaying an entry in full.
Both steps can be done independently of the other.
(Also as an added bonus at the end of the tutorial I’ll show you how to create a pseudo nested directory so you get www.yoursite.com/weblog/subsection/some-long-title. :)
To complete this tutorial you will need:
- Access to your .htaccess file in your root EE directory on an apache server (for part 1)
- PHP enabled on input in your templates (for part 2 - see EE docs on PHP in templates.)
Removing index.php from the URL
See the Remove index.php From URLs section of the Wiki for details.
Removing your “comments”/“more”/“article” template from the url
NB. I’m not a programmer, just a hack, so the code here is very simple, and the explanations very long :)
Please note, this half of the tutorial assumes you do not use category names in links. If you do, you still may be able to work it out, but you’re on your own :)
This half of the tutorial also presupposes you actually have a “more” template. Most sites/blogs have an index page(s) which contain entry summaries and links to the actual entries themselves. To display the actual entries, a “more” template is used (you may also call it your “comments”, “article” or “entry” template). If you don’t have a “more” template, here is an example of what you might be after. (I personally use {summary} on index pages, and {body} on individual entry pages.)
The simple trick in this part of the tutorial is to use some php in the default index template for a template group to decide whether we want to show the entries index template, or an individual entry template. Thus we use the one template for both jobs, depending on what needs to be displayed. Furthermore, because it is the default index template, only the name of the template group appears in the url, not the template itself.
(NB. I’ll use “entries index template” to refer to your ee code that says ‘show 25 entries with title and summary’ and “individual entry template” to refer to your ee code which says ‘show 1 entry with title, body and comments etc’.)
We determine what we want to display (index or an entry) by testing the url segment {segment_2}. If you’re unfamiliar with url segments or template groups/templates, then head over to the EE docs and read up. :)
To the code!
First, we’re going to assign {segment_2} to a php variable, so we can test against it. I’m going to call this variable “entry”.
<? $entry = "{segment_2}"; ?>
Segment 2 appears in the url like this: http://www.yoursite.com/templategroup/{segment_2} .
We’re going to test if in the first case our (segment_2} variable $entry is empty or contains category or pagination information. If so, we’re going to use our entries index template. If it doesn’t, we can assume it contains an entry title, which we will tell EE to display using a individual entry template.
The code for this is very simple:
<?
if (($article == "") || preg_match("^[url=PC]PC[/url][0-9]{1,}$^",$article) )
{
/* ENTRIES INDEX TMPL */
include("/path/to/entries_template.php");
}
else
{
/* [url=EXAMPLE]ONLY[/url] Change the page title */
$page_title = "my web site - {exp:weblog:entries weblog=\"". $weblog ."\" orderby=\"date\" sort=\"desc\" limit=\"1\"}{title}{/exp:weblog:entries}";
/* SINGLE ENTRY TMPL */
include("/path/to/single_entry_template.php");
}
?>
What’s the “preg_match” stuff about? That’s a regular expression that checks if pagination or category information (ie. a letter, C or P, followed by a number) is in the variable, and if so, to use the entries index template.
You can also see in the above that I use php to include my entries index and single entry templates from another directory. This way, I can keep one generic index and single entry template in one location for easy maintenance, and in my templates I can just copy and paste the above code and pass a bunch of php variables to each individual template. You can see an example of this with my $page_title variable (which you would need to declare above), where I pass the title for the entry to the single entry template, which contains the relevant html markup and EE code.
If this is too complicated for you, you can replace my included templates with straight EE code of your own, however I do suggest using php includes for easy maintenance :)
Now we have created a situation where instead of:
Instead of: www.yoursite.com/index.php/weblog/more/some-long-title
We have: www.yoursite.com/weblog/some-long-title
Cool! :)
Added bonus ;)
But before we finish I have a one more small tip. ExpressionEngine generally only allows a url structure like this: www.yoursite.com/index.php/templategroup/template/entry-title . You can’t have /templategroup/templategroup/ or /templategroup/template/template, for instance. But what if you want it to appear as though there is a subdirectory within you templategroup? I’ll give you an example. When developing sydneyanglicans.net we have an arbitrary “culture” section which has a matching “culture” template group containing templates for our movie, book and music reviews weblogs.
Using vanilla EE templates we could only have this:
www.yoursite.com/index.php/culture/movies <—“movies” index template within “culture” template group
www.yoursite.com/index.php/culture/article/some-movie-review <—movie review entry using an “article” template in the “culture” template group
Note the “movies” template no longer appears in the url, and to navigate back to the movies index template the user will find a link to get there, they can’t just delete the trailing details from the URI and hit ‘enter’. Books and other reviews would also appear with the same /culture/article/ structure, which makes the url’s less clear than they should be. I want them to specify where it’s a link to a movie, music or book review.
However, if we use the php code we looked at earlier in our “movies” template (plus the mod_rewrite code to remove index.php), as well as our “books” and “music” templates, we can now have:
www.yoursite.com/culture/movies <—“movies” index template within “culture” template group, as above
www.yoursite.com/culture/movies/some-movie-review <—move review appears within the movie section
and so on with book reviews, music reviews etc, which is much nicer ;)
Enjoy!
Luke
