Yii 1.1 Application Development Cookbook
上QQ阅读APP看书,第一时间看更新

Configuring URL rules

Yii URL router is quite powerful and does two main tasks: it resolves URLs into internal routes and creates URLs from these routes. Router rules description is scattered over the official Yii guide and API docs. Let's try to understand how to configure application rules by example.

Getting ready

  1. Create a fresh Yii application using yiic webapp as described in the official guide (http://www.yiiframework.com/doc/guide/) 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>',
          ),
       ),
  2. Delete everything from rules as we are going to start from scratch.
  3. In your protected/controllers, create WebsiteController.php with the following code inside:
    class WebsiteController extends CController
    {
       public function actionIndex()
       {
          echo "index";
       }
    
       public function actionPage($alias)
       {
          echo "Page is $alias.";
       }
    }

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

  4. Configure your application server to use clean URLs. If you are using Apache with mod_rewrite and AllowOverride turned on, then you should add the following lines to the .htaccess file under your webroot folder:
    Options +FollowSymLinks
    IndexIgnore */*
    RewriteEngine on
    
    # if a directory or a file exists, use it directly
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    
    # otherwise forward it to index.php
    RewriteRule . index.php

How to do it...

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.

  1. Add the following to your rules in protected/config/main.php:
    'home' => 'website/index',
    '<alias:about>' => 'website/page',
    'page/<alias>' => 'website/page',
  2. After saving your changes, you should be able to browse the following URLs:
    • /home
    • /about
    • /page/about
    • /page/test

The following screenshot shows part of a page that opens when /about URL is used:

How it works...

Let's review what was done and why it works. We'll start with the right part of the first rule:

'home' => 'website/index',

What is website/index exactly?

In the Yii application, each controller and its actions have corresponding internal routes. A format for an internal route is moduleID/controllerID/actionID. For example, the actionPage method of WebsiteController corresponds to the website/page route. So, in order to get the controller ID, you should take 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 understand it in a better way, 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.

Tip

The fewer rules you have, the fewer checks are needed if URL does not match. Less URLs means more performance.

There's more...

You can create parameterized rules using a special syntax. Let's review the third rule:

'page/<alias>' => 'website/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 WebsiteController::actionPage($alias).

You can define a pattern for such a parameter. We did it for the second rule:

'<alias:about>' => 'website/page',

Alias here should match about or else, the rule will not be applied.

See also

  • The recipe named Generating URLs by path in this chapter
  • The recipe named Using regular expressions in URL rules in this chapter
  • The recipe named Creating URL rules for static pages in this chapter
  • The recipe named Providing your own URL rules at runtime in this chapter