官术网_书友最值得收藏!

Generating URLs by path

Yii allows you not only to route your URLs to different controller actions but also to generate a URL by specifying a proper internal route and its parameters. This is really useful because you can focus on internal routes while developing your application and care about real URLs only before going live.

Tip

Never specify URLs directly and use the Yii URL toolset. It will allow you to change URLs without rewriting a lot of application code.

Getting ready

  1. Create a fresh Yii application using yiic webapp as described in the official guide and find your protected/config/main.php. Replace rules array as follows:
    // application components
    'components'=>array(
       …
       // uncomment the following to enable URLs in path-format
       /*
       'urlManager'=>array(
          'urlFormat'=>'path',
          'rules'=>array(
          '<alias:about>' => 'website/page',
          'page/about/<alias:authors>' => 'website/page',
          'page/<alias>' => 'website/page',
       ),
  2. In your protected/controllers, create WebsiteController with the following code inside:
    class WebsiteController extends CController
    {
       public function actionIndex()
       {
          echo "index";
       }
    
       public function actionPage($alias)
       {
          echo "Page is $alias.";
       }
    }

    This is our application controller that we are going to generate custom URLs for.

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

We need to generate URLs pointing to index and page actions of WebsiteController. Depending on where we need it, there are different ways for doing it, but the basics are the same. Let's list some methods that generate URLs.

CHtml::link() and some other CHtml methods such as form, refresh, and ajaxLink all accept URLs and are typically used in views. These are using CHtml::normalizeUrl internally to resolve internal routes. Therefore, you should pass data in one of the following formats:

  • URL string: In this case, URL passed will be used as is.
  • array(internal route, param => value, param => value, …). In this case, URL will be generated.

What is internal route? Each controller and its actions have corresponding routes. A format for a route is moduleID/controllerID/actionID. For example, actionPage method of WebsiteController corresponds to website/page route. To get a controller ID, you should take its name without Controller postfix and make its first letter lowercased. To get an action ID, you should take action method name without action prefix and, again, make its first letter lowercased.

Parameters are $_GET variables that will be passed to an action with internal route specified. For example, if we want to create a URL to WebsiteController::actionIndex that passes $_GET['name'] parameter to it, it can be done like this:

echo CHtml::link('Click me!', array('website/index', 'name' => 'Qiang'));

URLs are also helpful when using controller. Inside the controller, you can use createUrl and createAbsoluteUrl to get both relative and absolute URLs:

class WebsiteController extends CController
{
   public function actionTest()
   {
      echo $this->createUrl('website/page', 'alias' => 'about');
      echo $this->createAbsoluteUrl('website/page', 'alias' => 'test');
   }

   // the rest of the methods

}

As we have URL rules defined in the router configuration, we will get the following URLs:

  • /about
  • http://example.com/about

Relative URLs can be used inside your application while absolute ones should be used for pointing to locations outside of your website (like other websites) or for linking to resources meant to be accessed from outside (RSS feeds, e-mails, and so on).

When you cannot get controller instance, for example, when you implement a console application, you can use application's methods:

echo Yii::app()->createUrl('website/page', 'alias' => 'about');
echo Yii::app()->createAbsoluteUrl('website/page', 'alias' => 'test');

The difference is that when using controller-specific methods, you can omit both controller and module names. In this case, the current module name and the current controller name are used:

class MyController extends CController
{
  public function actionIndex()
  {
    // As we're inside of controller, createUrl will assume that URL
    // is for current controller
    echo $this->createUrl('index');
  }
}

How it works...

All URL building tools we have reviewed are internally using the CWebApplication:: createUrl method that is calling CUrlManager::createUrl. It tries to apply routing rules one by one starting from the top. If no rules are matched, then the default URL form is generated.

See also

  • The recipe named Configuring URL rules 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
主站蜘蛛池模板: 太白县| 涿鹿县| 金山区| 花莲市| 景泰县| 扶风县| 旌德县| 安新县| 玛纳斯县| 大同县| 同德县| 武夷山市| 慈利县| 仙桃市| 广东省| 大渡口区| 无锡市| 陇川县| 平利县| 兴化市| 鄄城县| 英德市| 安塞县| 蛟河市| 教育| 铁岭县| 高雄市| 紫金县| 义乌市| 漯河市| 抚远县| 罗源县| 冀州市| 虞城县| 泽州县| 凤阳县| 沧源| 商城县| 班戈县| 石楼县| 墨竹工卡县|