Routes - Default Route

This DefaultRoute is predefined in our project-structure project which you can download to start your own project. We named this route "default" because we think it will fit the needs for most people.

The default routing class can:
• work with rewritten URLs (requires mod_rewrite on Apache and rewrite directive on Nginx virtual host config)
• supports modules
• can be completely restful or just some controllers you define can work on restful way

Configuration

Every routing class can get its own set of configuration options. These options must be defined in routing_options key in configs/application.php. Here's the list of all possible keys and values for Default Route:


'routing_options' => array(
    
'always_restful' => true,
    
'url_namespace' => 'my-subfolder/other-folder'
)

routing_options - If you want all of your controllers to work on restful way, then set this to true. false is default.

If you don't want all of your controllers work on restful way, but you want some of them, then inside of controller class define public static property restful and set it to true. Check the RESTful example.

url_namespace - Sometimes, you'll run into situation when you won't be able to create virtual host for your app. Or you simply want to run your app in one of the public sub folders. In this case, you'll need to define url_namespace.

Example: let's say you want to run two Koldy apps on same domain. First app is running on http://domain.com/app1 and second one on http://domain.com/app2. In this case, each app must have url_namespace defined; first app for url_namespace needs to be /app1, for second /app2 and etc. This will ensure that all URIs are parsed and generated correctly.

Parsing REQUEST_URI

The default routing class is using nice structured URLs, like /some-page/some-parameter. It supports two formats of URIs because of modules support.

• First type: /controller/action/param1/param2/paramN
• Second type: /module/controller/action/param1/param2/paramN

Class will first try to lookup for the module, and then if module doesn't exists, URI will be treated like the first type. So, the flow is:

Here are some examples in case when you have defined module news:

type URI module controller action
GET / - Index indexAction
GET /news News IndexController indexAction
GET /news/archive/page/2 News ArchiveController pageAction
GET /news-list/last - NewsListController lastAction
POST/Ajax /news/article/comment News ArticleController commentAjax
GET /news/vacation-in-croatia News IndexController vacationInCroatiaAction
GET /news/article/vacation-in-croatia News ArticleController vacationInCroatiaAction
GET /archived/article/vacation-in-croatia - ArchivedController articleAction

The thing is: if framework can't find the controller, it will try to load the default IndexController. If framework can't find the action in the controller, it will fail. If you don't want it to fail, then please define the magic __call method in class so you can catch those.

Names of the actions in controller (methods names) can have two types: Action and Ajax.

Ajax type is used only if request is POST and it contains the request header HTTP_X_REQUESTED_WITH with value xmlhttprequest, OR, if request has HTTP_ACCEPT header that says that client expects the application/json response.

jQuery ajax will set the Http-X-Requested-With header by default, so the ajax request can be recognized on server.

If you're not using jQuery, then please add custom request header when making ajax requests.

Printing URLs

To print URL in your phtml files, you can use Url class that will then use the routing instance and will pass the parameters to url method.

Here are few examples of using the Url class:

usage result
Url::home() /
Url::href('index') /index
Url::href('news', 'archive') /news/archive
Url::href('news', 'archive', array('page', 2)) /news/archive/page/2
Url::href('news', 'archive', array('where' => 'page', 'index' => 2)) /news/archive?where=page&index=2
Url::href('news', 'archive', array('page', '2', 'show-menu' => 'yes')) /news/archive/page/2?show-menu=yes

Using values

The Url class is pretty powerful for this. There are several methods with which you can check the parts from URL. Check out the examples:

In case when you have module news and REQUEST_URI is:
/news/article/vacation-in-croatia/page/2
Url::isModule('news') true
Url::isAction('article') false
Url::isController('article') true
Url::is('news', 'article') false
Url::is('article', 'vacation-in-croatia') false - because vacation-in-croatia is parameter and action is indexAction
Url::is('article', 'index') true
Url::controller() article
Url::action() index
Url::getVar(3) page
Url::getVar(4) 2

Example of RESTful controller class


class ApiController {

    public static 
$restful true// this is not required if you defined always_restful=true

    /**
     * Would handle POST request to /api/auth
     */
    
public function postAuth() {
        return 
Json::create(array('success' => true));
    }

    
/**
     * Will handle GET request to /api/info?id=12345
     * And request will throw HTTP 400 if you don't add GET parameter 'id'
     */
    
public function getInfo() {
        
$id Input::requireParam('id');
    }

    
/**
     * Will handle DELETE request to /api/delete-item
     */
    
public function deleteDeleteItem() {
        
// something
    
}

}

Getting started

So, are you getting started using default routes? Cool 8-)

Lets get started by using examples only.

Contact form example

Lets assume you want to create contact form. Contact form should be something simple and it should contain the form and submit handler. Now, create the controller on application/controllers/ContactController.php


class ContactController {

    
/**
     * This handles the GET request on /contact
     */
    
public function indexAction() {
        return 
View::create('contact-form');
    }

    
/**
     * This handles the jQuery ajax POST request on /contact. Isn't it cool!?
     * I'm assuming that you'll submit contact form data with jQuery ajax.
     */
    
public function indexAjax() {
        
$params Input::requireParams('name''email''subject''message');
        
$mail Mail::create()
            ->
to('your-mail@domain.com')
            ->
subject($params->subject)
            ->
from($params->email$params->name),
            ->
body($params->message);

        if (
$mail->send()) {
            
Log::info('Mail is sent from contact form');
        } else {
            
Log::error('Failed to send mail from contact form: ' $mail->getError());
        }
    }

}

Well, that's it.