The Slim Framework support forum has moved to http://discourse.slimframework.com. This Tender forum is no longer maintained or monitored.

Dynamic routing

maartendings's Avatar

maartendings

23 Feb, 2013 01:42 PM

Hi all,

Would it be possible to create routes that are loaded from a database? For example when I have 3 pages (home, blog, contact) and I want the following routes to be created dynamically:

$app->get("/home", function(){
  ...
})

$app->get("/blog", function(){
  ...
})

$app->get("/contact", function(){
  ...
})

I know that it is possible to create dynamic routes, but when each route does something specific it would be good to separate them, hence the question.

Kind regards,

Maarten

  1. 1 Posted by David Rodger on 24 Feb, 2013 11:36 AM

    David Rodger's Avatar

    Do you mean that you'd like to have one "catch-all" function which evaluates the requested URI and load the appropriate function? Or do you mean that you'd like to separate the code involved in fulfilling one route be kept separate from the code which fulfils another?

    If you mean the latter, I'd recommend looking at Brian's post about using Pimple. He links to an earlier discussion here as well.

    Using his approach it would be possible to place "controllers" containing the relevant code in separate files.

  2. 2 Posted by maartendings on 24 Feb, 2013 12:06 PM

    maartendings's Avatar

    Hi David,

    Thanx for your reply but actually I meant neither of them :) (Although the approach using pimple is very elegant).

    Moreover what I am looking for is some kind of API call to create a route dynamically. CodeIgniter for example has something like that. (http://osvaldas.info/smart-database-driven-routing-in-codeigniter) I am just wondering if this is possible with Slim as well.

    Thanks again!

  3. 3 Posted by David Rodger on 25 Feb, 2013 02:00 AM

    David Rodger's Avatar

    Oh, I get it now. How about something like...

    $app->get('/:controller(/:params+)', function($controller) use ($app) {
        $args = func_get_args();
        $controllerClass = '\My\Controller\'.ucfirst(strtolower($controller));
        $action = array_shift($args);
        $controller = new $controllerClass($app);
        return call_user_func_array(array($controller, $action), $args);
    });
    

    This is speculative. While I have tried wild card params and optional params, I've never tried them together. But perhaps if you know how many URL segments you will have you can specify the optional ones as separate segments in the route pattern.

    You may not use a "controller", but you will appreciate that in my code above, the class that is loaded is based on the first URL segment and the method on the second. With some sort of autoloading mechanism, this doesn't require hitting a database, though you may have other reasons for doing so.

    Also, if you a need '/' route, the :controller part would have to be optional too.

  4. 4 Posted by maartendings on 25 Feb, 2013 01:44 PM

    maartendings's Avatar

    I am not sure if this will do what I intend but I will give it a try. Let me explain what I want to achieve here:

    In my CMS a user is able to create pages. I want them to be able to use the wildcards in the same way we can use within Slim. So for example a user could create a page entry with url /blog, and then one level below that, /blog/:any for when an actual blog post is viewed.

    The idea is to serve different templates depending on the slug. The /blog url should serve a different template then /blog/:any. (Templates can be set in the CMS for the specific page). But it should also be possible for /contact to load an entirely different template.

    Maybe I am over-complicating stuff here but that's the basic idea and imo is a good way to keep templating logic within the CMS. Do you agree?

    Regards

  5. Support Staff 5 Posted by Brian Nesbitt on 25 Feb, 2013 07:03 PM

    Brian Nesbitt's Avatar

    You just need to make sure you have all the routes mapped by the time you hit the $app->run();

    Here are a few other options...

    Option 1 is doable but you might end up with too many routes

    Option 2 is better.

    $app->get('/userpages/:userId', function($userId) use ($app) {
        // serve user home page
    });
    
    // Option 1
    foreach($users as $user) {
       foreach($user->getPages as $page) {
          $app->get('/userpages/:userId/' . $page->url .  ', function($controller) use ($app, $page) {
              // serve $page for $userId
          });
       }
    }
    
    // Option 2
    $app->get('/userpages/:userId/:urlParts+' . $page->url .  ', function($userId, $urlParts) use ($app) {
        // serve $page for $userId
        $page = db::getPageForUser($userId, $urlParts);
    
        if (!$page) {
          $app->notFound();
        }
    
        // serve $page using $page->template, $page->content or whatever...
    });
    
    $app->run();
    
  6. 6 Posted by maartendings on 26 Feb, 2013 02:11 PM

    maartendings's Avatar

    So it's definitely possible to create routes based on variables coming from a db? That's very good to know. Thanx Brian.

    Regards,

    Maarten

  7. Support Staff 7 Posted by Brian Nesbitt on 26 Feb, 2013 02:31 PM

    Brian Nesbitt's Avatar

    Yes. Whether you do

    $app->get('/hello/:name', function ($name) {
        echo "Hello, $name";
    });
    

    or

    $uriFromDb = '/hello/:name';
    $app->get($uriFromDb, function ($name) {
        echo "Hello, $name";
    });
    

    ... slim doesn't care as long as its mapped before $app->run();

  8. 8 Posted by Vanita on 20 Feb, 2014 11:04 PM

    Vanita's Avatar

    Will autism just appear in ppl's adulthood? or they must have . . developed in the childhood? Plus, how do u define autism and . . social disorder?.

  9. 9 Posted by Splug on 27 Sep, 2014 07:53 PM

    Splug's Avatar

    i define it like:

    $app->get('/cure/:ailment', function($ailment) use ($app){});
    

    This way you can cure anything, even spam.

  10. 10 Posted by Pierre-André Vu... on 07 Dec, 2014 07:43 PM

    Pierre-André Vullioud's Avatar

    Hi,
    i have done a dynamic router for a project. You can have a look to the code :
    https://github.com/pvullioud/japi/blob/master/api/v1/routes.php

  11. 11 Posted by Erhan Kayar on 26 Feb, 2017 12:30 AM

    Erhan Kayar's Avatar

    Hi Guys,

    my question is how can i read args in Controller file? @David Rodger or somebody can enlighten me?

Reply to this discussion

Internal reply

Formatting help / Preview (switch to plain text) No formatting (switch to Markdown)

Attaching KB article:

»

Attached Files

You can attach files up to 10MB

If you don't have an account yet, we need to confirm you're human and not a machine trying to post spam.

Keyboard shortcuts

Generic

? Show this help
ESC Blurs the current field

Comment Form

r Focus the comment reply box
^ + ↩ Submit the comment

You can use Command ⌘ instead of Control ^ on Mac