- Yii Application Development Cookbook(Second Edition)
- Alexander Makarov
- 783字
- 2021-11-12 16:36:13
Generating URLs by path
Yii allows you to not only 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 only worry about real URLs before going live.
Getting ready
- Create a fresh Yii application using
yiic webapp
as described in the official guide and find yourprotected/config/main.php
file. Replace therules
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', ),
- In your
protected/controllers
directory, createWebsiteController
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.
- Configure your application server to use clean URLs. If you are using Apache with
mod_rewrite
andAllowOverride
turned on, then you should add the following lines to the.htaccess
file under yourwebroot
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 the 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 use CHtml::normalizeUrl
internally to resolve internal routes. Therefore, you should pass data in one of the following formats:
- URL string: In this case, the URL passed will be used as is
array(internal route, param => value, param => value, …)
: In this case, a 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, the actionPage
method of WebsiteController
corresponds to the website/page
route. To get a controller ID, you should take its name without the Controller
postfix and make its first letter lowercase. To get an action ID, you should take the action method name without the action
prefix and, again, make its first letter lowercase.
Parameters are the $_GET
variables that will be passed to an action with an internal route specified. For example, if we want to create a URL to WebsiteController::actionIndex
that passes the $_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 the 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', array('alias' => 'about')); echo '<br />'; echo $this->createAbsoluteUrl('website/page', array('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/page/test
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 a controller instance, for example, when you implement a console application, you can use the 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 internally use the CWebApplication:: createUrl
method that calls CUrlManager::createUrl
. It tries to apply routing rules one by one, starting from the top. The first matched rule is applied. If no rules are matched, then the default URL form is generated.
There's more...
For further information, refer to the following URLs:
- http://www.yiiframework.com/doc/guide/en/basics.controller
- http://www.yiiframework.com/doc/guide/en/topics.url
- http://www.yiiframework.com/doc/api/CUrlManager
- http://www.yiiframework.com/doc/api/CHtml/#normalizeUrl-detail
- http://www.yiiframework.com/doc/api/CHtml/#link-detail
- http://www.yiiframework.com/doc/api/CController/#createUrl-detail
- http://www.yiiframework.com/doc/api/CWebApplication/#createUrl-detail
See also
- The Configuring URL rules recipe
- The Creating URL rules for static pages recipe
- The Providing your own URL rules at runtime recipe