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

Creating URL rules for static pages

A website typically contains some static pages. Usually, they are /about, /contact, /tos, and so on, and it is common to handle these pages in a single controller action. Let's find a way to create URL rules for these types of pages.

Getting ready

  1. Create a fresh Yii application using yiic webapp as described in the official 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 with the following code:
    class WebsiteController extends CController
    {
      public function actionPage($alias)
      {
          echo "Page is $alias.";
      }
    }
  4. Configure your application server to use clean URLs. If you are using Apache with mod_rewrite and AllowOverride turned on 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...

The most straightforward way is defining a rule for each page:

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

Using regular expressions, we can compact it to a single rule:

'<alias:(about|contact|tos)>' => 'website/page',

Now, what if we want the URL to be /tos and an alias parameter to be terms_of_service?

No problem, we can use default parameters to achieve it:

'tos' => array('website/page', 'defaultParams' => array('alias' => 'terms_of_service')),

OK. What if we have many pages and want to be able to dynamically create pages without adding more rules or changing existing ones?

We can achieve this with the following rule:

'<alias>' => 'website/page'

As this rule matches everything, we need to place it last, so it won't affect all other rules. In addition, default rules with one slug, such as controller name will stop working. To overcome this issue, we need to add default rules which we deleted in the Getting ready section of this recipe.

How it works...

Let's read rules we just wrote.

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

If the URL is /about, then pass it as the alias parameter to website/page.

'<alias:(about|contact|tos)>' => 'website/page',

If the URL is /about or /contact or /tos, then pass it as the alias parameter to website/page.

'tos' => array('website/page', 'defaultParams' => array('alias' => 'terms_of_service')),

When the URL is /tos, pass terms_of_service as the alias parameter value.

This rule is a bit special because it uses default parameter option. Default parameter allows you to set a value that will be used if parameter with name specified is omitted. When you need to specify an option for the rule, you should use an array notation:

'pattern' => array('internal/route', 'option' => 'value', 'option' => 'value', …),

Note

For a list of options you can set, refer to the following API page:

http://www.yiiframework.com/doc/api/1.1/CUrlRule

See also

  • The recipe named Configuring URL rules in this chapter
  • The recipe named Using regular expressions in URL rules in this chapter