Kamal
Kamal

Reputation: 363

Routing in SilverStripe using regex

In SilverStripe I want to create dynamic routing. What I am trying to route is every url that matches the following pattern: some numbers and text separated with dashes and at the end "-tx-i-numberid"

Example: http://example.com/some-text-and-numbers-separated-with-dashes-tx-i1654766

I've read this documentation and I couldn't figure it out.

I would like to have some rule like the following

'$Slug-tx-i$ID' : 'TeamController'

I wonder if I can do it using regex, or some other way.

Upvotes: 2

Views: 274

Answers (2)

Dan Hensby
Dan Hensby

Reputation: 1143

You can do something like this:

public function index($request)
{
    $url = $request->param('Slug');
    $matches = array();
    if (strpos($url, '/') === false && preg_match('/^[a-z\-]+\-i([0-9]+)/i', $url, $matches)) {
        return "matched " . var_export($matches, true);
    }
    return ContentController::create()->handleRequest($request, $this->model);
}

But you have to change the routing rules and I haven't figured out how to get that working without hijacking ALL URLs.

Can you explain a bit more about what you're trying to do? Perhaps could solve this another way.

What about:

RewriteRule ^[a-zA-Z\-]+\-i([0-9]+) /custom/$1

in the .htaccess? (It's untestested, but means you can more accurately target the pages).

Perhaps it's a 301 map and you're really looking for instead?

Upvotes: 1

Mark Guinn
Mark Guinn

Reputation: 619

I don't know of a way to do this with regex from within the routing system. Your best bet is to match '$Slug' and then parse it in the controller.

If your controller action instantiates a second controller and passes on the request, you can actually nest controllers (See for a more in depth example https://vimeo.com/album/3629143/video/143149869).

For example:

class Controller1 extends Controller
{
    private static $allowed_actions = ['index'];
    public function index($req) {
        if (preg_match('/myregex/', $req->param('Slug'))) {
            return Controller2::create()->handleAction($request, $this->model);
        } else {
            return Controller3::create()->handleAction($request, $this->model);
        }
    }
}

Upvotes: 1

Related Questions