Using Slugs/Permalinks Instead of IDs
Search engines like to see keyword phrases in the URL instead of a number for an ID. URL “slugs” can help describe your content better, which is a benefit to the visitors to your site, both human and crawl bot. When your indexed page is listed on a Google search results page, the snippet is displayed and skimmed by the reader. Also note that the keyword phrase you searched for will be highlighted, if displayed in the URL.
Luckily, you can get this up and running quickly with an extension already available for Yii, called yiibehaviorsluggable. All I had to do was add a new field for the slug into the database, drop the extension in its proper folder, and add the behavior to my model. The cool thing about this plugin, is that it can generate the slug for you when you update, based upon another field such as “title”. You may need to update the urlManager in your config. I have one of mine set to:
This means my “product” pages would be accessed through a URL like:
Since the actionView function (in the controller) was using the ID, and the generated function loadModel, I created a second function loadModelSlug, and changed the view parameter and function to use it.
Removing /index.php/ from URLs
The default generated skeleton application that you are probably working from, if you didn’t start from scratch, starts most of the URLs with /index.php/. Now that’s ugly. Much like the way CodeIgniter’s index.php works (or WordPress even), an htaccess rule will rewrite the accessed pages to the index.php.
- Grab these htaccess rules from the offical guide and place them in the .htaccess in the root directory for your project. Read more about this change on that Yii guide page.
- You’ll also want to change these options in your config file:
Force Trailing Slashes to Avoid Duplicate Content
I noticed that pages could be accessed with or without the trailing slash. Since it’s best if the page is only accessible through one URL, to avoid duplicate content issues with Google, I looked for solutions on how to force the trailing slash. While you could do this with htaccess rewrites, it can also be done via a base Yii controller fairly easily.
Have all your controllers derive from your own custom base controller, that extends the default CController. If you’re using the Gii generated application, you’ll already have one called Controller.php located in /components/. Then, add the following code to it:
Get Rid of Ugly “Page” URLs in the Site Controller
When generating a skeleton application with Yii, it creates a SiteController which has an action for displaying pages. For example, a page would be “/site/page/?view=about”, when we really want something nice and short like “/about/”.
One way is to add individual rules for each page into your urlManager options. These are located in “/protected/config/main.php”.
That works, but what if you have a lot of pages? Instead of writing a rule for each one, I thought, what if I make it the last default rule past the generic controller/action rules? I tested out the following and it works. If there is no controller with the same name as the page, the SiteController page action will be the last rule Yii attempts to match. Here are my full urlManager settings for reference. See the last line:
Good luck in your development of an SEO-friendly Yii application. If you’re launching a new site, I highly recommend checking out this massive SEO guide from SEOMoz.