5. URL Routing
Now that we understand the directory structure, how are the URLs created to invoke a controller to perform its function?
Let's take an example. In your browser, navigate to your Yii install (Frontend if using Advanced Template). In the top navigation bar that is shown with a default install, click on About.
The URL in your address bar should resemble the following:
http://yiisite.com/index.php?r=site%2Fabout
Notice the query string:
r=site%2Fabout
The 'r' refers to routing. The %2F
is URL encoding for the symbol '/'. Thus, decoded, it would be rendered: r=site/about
The format for routing is:
controller/action
That would mean, for this example, the specified controller is
site
and the specified action is
about
.
To decipher what this refers to, lets look at some actual code. In your code editor, navigate to your controllers directory (frontend/controllers for Advanced Template) and open the file SiteController.php.
Notice the class definition:
class SiteController extends Controller
First, take note that the class name matches the file name. The naming convention for controllers is to have the controller name, with first letter
capitalized, followed by the word Controller, also first letter capitalized (camel case). Thus, the name of this controller is 'site'. This matches the
pre-slash part of site/about. Therefore,
site/about
invokes the controller SiteController.
Now take note of the post-slash portion of site/about. In this case, it is the word 'about'. This specifies the action to call inside of the controller. If you look farther down the script, you will see a function defined as such:
public function actionAbout()
{
return $this->render('about');
}
By convention, all action functions are named using the word 'action' all lowercase, followed by the name of the action with the first letter uppercase. Thus, the route site/about invokes the function actionAbout().
5.1 Default Controller and Action
What controller and action is invoked when you navigate to the root url, in our case http://yiisite.com, with no query string parameters?
In such a case, the default controller and action will be called. By default, the default controller is
SiteController
and the default action is
actionIndex()
. Therefore, navigating to http://yiisite.com is the same as navigating to: http://yiisite.com/index.php?r=site%2Findex
Note: as is typical with most web servers, navigating to the root url,
http://yiisite.com
in this case,
defaults to the file named index.php. Thus, it is the equivalent of navigating to
http://yiisite.com/index.php
.
This behavior can be modified by adjusting the settings in the config file (config/web.php in Basic Template or frontend/config/main.php in Advanced
Template to apply to the frontend). If you would like to change the default controller from 'site' to 'foo', you would add the following
key/value to the
$config[]
array:
'defaultRoute' => 'foo'
If this were done, navigating to http://yiisite.com would be equivalent to
http://yiisite.com/index.php?r=foo%2Findex
and would invoke
actionIndex()
in the
FooController
class.
If you desire to change the default action from 'index' to something else, say 'home' as an example, you would do so simply by adding a public property to the class as such:
public $defaultAction = 'home';
Thus, with 'foo' still set as the default controller, navigating to
http://yiisite.com
would be equivalent to:
http://yiisite.com/index.php?r=foo%2Fhome
5.2 Pretty Urls
In practice, using the url format of
http://yiisite.com/index.php?r=site%2Fabout
is not common nor desirable. It is much more common to see the format:
http://yiisite.com/site/about
To make the later equivalent to the former, we need to do two things: 1. Adjust the config file and 2. Install a .htaccess file in document root.
Open the config file config/web.php (common/config/main.php for Advanced Template to apply to both frontend and backend). In the
$config[]
array, locate
the 'components' key, which itself also references an array. In the 'components' array, add the following key/value:
'urlManager' => [
// Disable index.php
'showScriptName' => false,
// Disable r= routes
'enablePrettyUrl' => true
],
Next, in the document root (the web directory, remembering there is a separate web directory for both frontend and backend if using Advanced Template), create the following file and name it: .htaccess (This is assuming you are using Apache as your web server.)
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
The Magic Dash What if you have an action in camel case, such as actionAboutYii? How would you construct the URL to access such? Simple: The dash!
To access actionAboutYii in controller Site you would use: In routing, the dash is removed and the following character is changed to upper case. |