Route (group) issue


#1

Hi All,

I am trying to figure out some options to pass params to a route or a route group.
For a route this works with: ->setArgument

But I have the same argument for 3 routes. Perhaps it also possible to group routes and fetch the name of the group.

So far i tried:

$app->group('group-name-one', function(){

	$this->map(['GET', 'POST'], '/testing', 'PageController:test');

})->add(new RouteMiddleware($container));

No I would like to ‘fetch’ the group name in the Middleware and Slim is serving me a 404 (not found). If I remove the ‘group-name-one’ it works (offcoure there is no name anymore).

Does anyone have an solution?


#2

The first argument for $app->group is not a name, but a pattern:

Each group’s route pattern is prepended to the routes or groups contained within it, and any placeholder arguments in the group pattern are ultimately made available to the nested routes

So the test action will be available at /group-name-one/testing. And if you leave the group pattern empty, it will be available at /testing, as you noticed.

Can you elaborate on what sort of parameters you want to pass the the routes in the group? Perhaps this can be solved in the route middleware instead:

// somewhere in RouteMiddleware:
$request = $request->withAttribute('foo', 'bar'); 
return $next($request, $response);
// in the route
$foo = $request->getAttribute('foo');

Giving the routes a name sounds like the possibility of tagging routes. This has been discussed in issue 1891, but has not been implemented. The discussion may contain some additional pointers on how to solve this.


#3

Hi llvl,

I would like to segments the routes depeding language. I had the idea to wrap some route in a group with a name. For example language1, language2 etc.

$app->group('language1', function(){

	$this->map(['GET', 'POST'], '/page', 'PageController:test');
	$this->map(['GET', 'POST'], '/other-page', 'PageController:test');

})->add(new RouteMiddleware($container));

$app->group('language2', function(){

	$this->map(['GET', 'POST'], '/pagina', 'PageController:test');
	$this->map(['GET', 'POST'], '/andere-pagina', 'PageController:test');

})->add(new RouteMiddleware($container));

// For some of the routes the language is very clear. For others will have to test wich language is req.
// And then I the controller check the group name. Something like if ('language 1' === .... etc)

Also tried to to set an argument to a group. This is not possible. Can I add a tag?
Something like:

$app->group('language1', function(){

	$this->map(['GET', 'POST'], '/page', 'PageController:test');
	$this->map(['GET', 'POST'], '/other-page', 'PageController:test');

})->add(new RouteMiddleware($container))->tag(tag)->setArgument(argument);

#4

Hello Koen,

I don’t think there is currently a way to set an argument or a tag for a group in Slim. Some ways to go around this are:

  • adding the language by calling setArgument on each route
  • use group middleware to set the language attribute on the request

I have added an minimal example to demonstrate both options below:

<?php

require_once __DIR__ . '/vendor/autoload.php';

$app = new Slim\App();

// example of setting the language per route
$app
    ->get('/hello', function($req, $res) { return 'hello ' . $req->getAttribute('lang'); })
    ->setArgument('lang', 'en'); // add lang attribute on route
$app
    ->get('/hola', function($req, $res) { return 'hola ' . $req->getAttribute('lang'); })
    ->setArgument('lang', 'es'); // add lang attribute on route

// example of setting the language using group middleware
$app
    ->group('', function() {
        $this->get('/hallo', function($req, $res) { return 'hallo ' . $req->getAttribute('lang'); });
        $this->get('/andere-pagina', function($req, $res) { return 'pagina in ' . $req->getAttribute('lang'); });
    })
    ->add(function($req, $res, $next) {
        // add lang argument for all routes in group using route middleware
        return $next($req->withAttribute('lang', 'nl'), $res);
    });

$app->run();

Hope that helps,

Lennaert


#5

That clears things up.
Thanks Lennaert!