Routes

Routes are defined within a controller by overriding its static route method. Saturn passes a RouteSet object, on which you can call the get method to handle GET requests and the post method for POST requests. Parameters required to create routes are the desired URI, and the name of the public method within the controller to call.

Defining a custom route for a method will remove said method's default route. Any other default routes are left untouched.
application/about/about.php
public static function route($router) 
{
    $router->get('about-us','about');     // Call the "about" method every time the about-us URI is requested
    $router->get('about-us/team','team'); // Call the "team" method every time the about-us/team URI is requested
}

In the above example the team page's URI is a descendant of the about page. If we ever need to change the about page's URI, we'd have to manually change those of the descendants as well. We can avoid this by stacking our routes.

The get and post methods both return a new Route object. This object itself can accept underlying routes through the same get and post methods.

application/about/about.php
public static function route($router)
{
    $about_route = $router->get('about-us','about');
    $team_route = $about_route->get('team','team'); // We no longer need to add the about-us segment
}

For multilingual sites you can just use the l() function like everywhere else. Saturn will then only match the URI that corresponds to the active language.

application/about/about.php
public static function route($router)
{
    $about_route = $router->get(l([
        'en' => 'about-us', 
        'nl' => 'over-ons'
    ]), 'about');

    // Optionally, you can pass the associative array directly to improve readability
    $team_route = $about_route->get([
        'en' => 'team',
        'nl' => 'medewerkers'
    ], 'team');
}

It's acceptable to have multiple routes that match the same URI. You can reject a request from within the called method by simply returning false. The router will then proceed to the next matching route.

Saturn might reorder the route index to maximise performance. Relying on order of execution will lead to unexpected results.

Dynamic routes

You can add placeholders to your route URI's to handle requests for dynamically created content. Add the desired placeholder name contained within curly braces, and Saturn will pass matching values to the method as parameters. Function arguments can be in any order, as long as the placeholder and argument names correspond.

application/about/blog.php
public static function route($router)
{
    $router->get('blog/tag-{tag}','tagged');
    $router->get('blog-archive/{year}/{month}','archive');
}

public function tagged($tag)
{
    // $tag would contain whatever {tag} matches with
}

public function archive($year, $month)
{
    // $year and $month would contain whatever {year} and {month} match with
}

Matching database records

For information on how to define database entities, check schema.

To create routes that match attributes of specific database objects you can use one or more placeholders that correspond to the attribute's name, prefixed with the name of the object. Saturn will query the database whenever a matching URI is requested and check if a specific object exists with the supplied attributes. The various attribute placeholders you defined for the object will not be passed. Instead, only the queried object will be passed as the value for a parameter that matches the object's name. The method will not be called if no object exists.

application/about/blog.php
public static function route($router)
{
    $router->get('blog/{blogitem.slug}/{blogitem.id}', 'item');
}

public function item($blogitem)
{
    // $blogitem would contain the blog item model
}

Optional segments

Optional segments can be defined through the optional() method. Placeholders can be used as long as the corresponding attribute has a default value.

Optionals accept only a single segment. On the other hand, whenever a single segment matches multiple optionals they are processed in order of addition.

application/about/blog.php
public static function route($router)
{
    // This route will match both "/blog-archive/2016/01" and "/blog-archive/2016/01/page-2"
    $router->get('blog-archive/{year}/{month}', 'archive')->optional('page-{page}');
}

public function archive($year, $month, $page=1)
{
    // $page defaults to 1 if the optional segment is missing
}

Accepting recurring segments

Call the multiple() method on a route to define an optional segment that can occur multiple times in a URL. This accepts the same parameter as the optional() method, but passes the value to your controller as an array.

application/about/blog.php
public static function route($router)
{
    // Corresponds to for example /blog/tag-foo/tag-bar
    $router->get('blog', 'index')->multiple('tag-{tag}');
}

public function index($tag = [])
{
    // $tag is always an array
}

Language independent routes

When using multiple languages, call the unilingual() method on a route to make it language independent.

application/about/blog.php
public static function route($router)
{
    // Corresponds to /en/blog
    $router->get('blog', 'index');
    
    // Corresponds to /blog
    $router->get('blog', 'index')->unilingual();
}
Edit this page on GitHub Updated at Mon, Feb 14, 2022