.htaccess Cheat Sheet

All the important Apache .htaccess web server rules and config options

http://htaccesscheatsheet.com/

Advertisements

How to configure URL rules in YII framework

Clean SEO-Friendly URLs for Yii Pages

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:

'product/<slug:[a-za-z0-9-]+>'=>'product/view'

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.

public function actionView($slug)
{
$this->render(view,array(
model=>$this->loadModelSlug($slug),
));
}
public function loadModelSlug($slug)
{
$model = Product::model()->findByAttributes(array(slug=>$slug));
if($model===null)
throw new CHttpException(404,The requested page does not exist.);
return $model;
}
view raw loadModelSlug.php hosted with ❤ by GitHub

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.

  1. 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.
  2. You’ll also want to change these options in your config file:
urlManager=>array(
urlFormat=>path,
showScriptName=>false,

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”.

about => array(site/page, defaultParams => array(view => about)),
example => array(site/page, defaultParams => array(view => example)),

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:

urlManager=>array(
urlFormat=>path,
showScriptName => false,
rules=>array(
// custom rules go first
product/<slug:[a-zA-Z0-9-]+>/=>product/view,
// default controller url setup
<controller:w+>/<id:d+>=><controller>/view,
<controller:w+>/<action:w+>/<id:d+>=><controller>/<action>,
<controller:w+>/<action:w+>=><controller>/<action>,
// defaults to a site page if not above
<view:[a-zA-Z0-9-]+>/=>site/page,
),
),

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.

 

 

How to configure URL rules in YII framework

Introduction

YII URL router is quite powerful and does two main tasks: it resolves URLs into internal routes and creates URLs from these routes. Let’s try to understand how to configure application rules by simple example.

Let’s begin

As a first step: Create a fresh Yii application and find your protected/config/main.php. It should contain the following:

// application components
'components'=>array(
...
// uncomment the following to enable URLs in path-format
/*
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'<controller:w+>/<id:d+>'=>'<controller>/view',
'<controller:w+>/<action:w+>/<id:
d+>'=>'<controller>/<action>',
'<controller:w+>/<action:w+>'=>'<controller>/<action>',
),
),

Now delete everything from rules as we are going to do from scratch.

Go to  your protected/controllers, create SiteController.php with the following code :

<?php

class SiteController extends CController
{
public function actionIndex()
{
echo "index";
}
public function actionPage($alias)
{
echo "This is $alias.";
}
}

This is the application controller we are going to customize URLs for.

Let’s configure our application server to use clean URLs. If you are using Apache with mod_rewrite and AllowOverride turned on, then add the following lines into your  .htaccess file under the root folder:

Options +FollowSymLinks
IndexIgnore */*
RewriteEngine on
# if a directory or a file exists, use it
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
# else forward it to index.php
RewriteRule . index.php

How to do this?

Our website should display the index page at /home and all other pages at /page/<alias_here>. Additionally, /about should lead to a page with alias about.

Now add the below to your rules in protected/config/main.php:
'home' => 'site/index',
'<alias:about>' => 'site/page',
'page/<alias>' => 'site/page',

Save the above changes and browse the following URLs:

  • ‰‰ /home
  • ‰‰ /about
  • ‰‰ /page/about
  • ‰‰ /page/test

When /about URL is used: You can see the following in your browser:

This is about.

What is happening!

Let’s review what we did and how it works.  Have a look at the first rule:
'home' => 'site/index',

What is site/index exactly?

In the Yii framework, a format for an internal route is moduleID/controllerID/actionID. For example, the actionPage method of SiteController corresponds to the site/page route. So, the controller ID should be its name without the Controller postfix and make its first letter lowercased. To get an action ID, you should take action method name without the action prefix and, again, make its first letter lowercased.

Now, what is home?

To have a better understanding, we need to know, at least perfunctorily, what’s happening when we access our application using different URLs.

When we are using /home, URL router checks our rules one by one starting from the top trying to match URL entered with the rule. If the match is found, then the router is getting controller and its action from an internal route assigned to the rule and is executing it. So, /home is the URL pattern that defines which URLs will be processed by the rule it belongs to.

You can create parameterized rules using a special syntax. Let’s take the third one:
'page/<alias>' => 'site/page',
Here, we are defining an alias parameter that should be specified in URL after /page/. It can be virtually anything and it will be passed as $alias parameter to
SiteController::actionPage($alias).

You can define a pattern for such a parameter:
'<alias:about>' => 'site/page',
Alias here should match about or else, the rule will not be applied.

Yii yiinfinite-scroll pagination

Creates an Infinite Scroll Pagination, like in Twitter

yiinfinite-scroll

This extension uses the infinite scroll jQuery plugin, from http://www.infinite-scroll.com/ to create an infinite scrolling pagination, like in twitter. This kind of pagination is also called Endless Scroll.

It uses javascript to load and parse the new pages, but gracefully degrade in cases where javascript is disabled and the users will still be able to access all the pages.

Demo