Microrouter

As you already know, the controller microrouter is a Jet\MVC_Controller_Router class that is supposed to help you to implement the decision logic of the resolv() method. Recall that the purpose of this method is to resolve what the request is and what controller action will be performed in the final step. Thus, this method can handle the raw part of the URL, GET parameters and possibly other aspects.

Let's look at this in a very concrete way and take a simple situation as an example.

The sample application contains the Content.Articles.Browser application module. As the name suggests, the module is used to browse and read articles. This application module, as content, is placed on one of the pages and must be able to display a list of articles, with respect to pagination, with each page of the list having its own URL. If a user/visitor clicks on an article in the list, they must be taken to a page that again has a specific URL, where they can find the article details. So we have two actions of the list and detail checker and they are distinguished by the URL.

How to find out which controller action to call based on a URL? That is, what is the user looking at and what exactly should the module do? The controller has to decide for itself and the resolv() method is used for this.

That is, it is the implementation of some decision logic. And this logic can be sometimes trivial, but sometimes let's say "more complicated". However, in practice, it turns out that it is often the same thing over and over again, and it's not exactly fun programming. And sometimes the result is not the clearest code. The point of a microcontroller is to make the development of this logic easier and, most importantly, clearer.

The default controller Jet\MVC_Controller_Default in Jet MVC already assumes the use of a microrouter. So in practice, you just need to implement the getControllerRouter method in your controller, create an instance of Jet\MVC_Controller_Router in it, and define all the decision logic. Let's demonstrate this in practice using the example of the aforementioned Content.Articles.Browser sample module and its controller:

public function getControllerRouter(): MVC_Controller_Router
{
    if( !
$this->router ) {
        
$this->router = new MVC_Controller_Router$this );

        
$path MVC::getRouter()->getUrlPath();

        
$this->router->addAction'list' )
            ->
setResolver( function() use ( $path ) : bool {
                if( 
$path == '' ) {
                    return 
true;
                }

                if( 
preg_match'/^page:([0-9]+)$/'$path$matches ) ) {
                    
$this->page_no $matches[1];
                    
MVC::getRouter()->setUsedUrlPath$path );
                    return 
true;
                }

                return 
false;
            } );

        
$this->router->addAction'detail' )
            ->
setResolver( function() use ( $path ) : bool {
                if( 
$path == '' ) {
                    return 
false;
                }

                
$current_article Content_Article::resolveArticleByURL$pathMVC::getLocale() );
                
                if( !
$current_article ) {
                    return 
false;
                }

                
$this->article $current_article;
                
MVC::getRouter()->setUsedUrlPath$path );

                return 
true;

            } );
    }

    return 
$this->router;
}

This is the most basic situation, but it completely clarifies the purpose of the microrouter and the principle of its function.

We'll highlight a few things:

  • The microrouter instance is a property of the controller. This is not a necessity, but a good habit, because as we will show, the microrouter can be useful elsewhere (for example, for URL creation).
  • Actions are passed to the microrouter by the addAction method. The name of the action corresponds to the controller action - more precisely to one of the controller methods. Thus, the 'list' action points to the list_Action method, the 'detail' action to the detail_Action method.
  • Each action should have a resolver (set by the setResolver method), which is an anonymous function that decides whether the action is relevant to the request (returns true) or not (returns false). The goal is to clearly see what and how the decision to direct the request to the action is based on and to avoid code spaghettification.
  • The above example is only a very basic one. In fact, microrouter can do even more: check permissions and generate action URLs.

This is the basic principle. I highly recommend you check out the detailed descriptions of the Jet\MVC_Controller_Router and Jet\MVC_Controller_Router_Action classes. There you will find more useful details.

Previous chapter
Jet\MVC_Controller_REST
Next chapter
Jet\MVC_Controller_Router