3

I'd like to use the asterisk token functionality that is available in the CP in my plugin. This way I can have an infinite amount of 'pages' under certain routes. In the CP, it looks like myroute/*

Is it possible for me to get the same functionality in my plugin routes?

Routes have been working amazing for me via the standard:

public function registerSiteRoutes()
{
    return array(
    'myroute' => array('action' => 'myPlugin/myAction')
  );    
}

Though when I try the asterisk trick, it doesn't work:

public function registerSiteRoutes()
{
    return array(
    'myroute/*' => array('action' => 'myPlugin/myAction')
  );    
}

Does anyone know if this is possible and/or the way to accomplish this?

Thanks!

6

You can't have tokens in your plugin routes, but you can easily add a segment variable that recreates the asterisk token's functionality with some regex. According to the the official docs on routing, the asterisk represents

(...) any string of characters, except for a forward slash (/)

Here's what the defintion for a route with a "asterisk-like" segment could look like:

public function registerSiteRoutes()
{
    return array(
        'myroute/(?P<asteriskToken>[-\w]+)' => array('action' => 'myPlugin/myAction')
    );    
}

Note that the string "asteriskToken" will be the variable name for this route segment's value when it is passed to your controller. It could be named anything.

The above route will match any URIs such as

/myroute/whatever (asterisk token will be "whatever")
/myroute/123 (asterisk token will be "123")
/myroute//foobar (asterisk token will be "foobar")

Coming to your controller, here's how you could look up the asterisk token variable's value:

public function actionMyAction( array $variables = array() )
{
   $asteriskToken = $variables[ 'asteriskToken' ];
}

Be aware that any calls to /myroute (i.e. without the second segment) will now 404. If this is unwanted – or if you want to define a default value for your asterisk variable – you can make the asterisk token segment optional. This is done by wrapping the segment variable in parentheses and appending a question mark at the end (kudos to @carlcs for this trick, originally given as an answer to my question here:

'myroute(/(?P<asteriskToken>[-\w]+))?' => array('action' => 'myPlugin/myAction')

With the latter regex, your route will now also match the following:

/myroute (asterisk token will be undefined)

...and in your controller, here's how you could define a default value for the asterisk token variable:

$asteriskToken = isset( $variables[ 'asteriskToken' ] ) ? $variables[ 'asteriskToken' ] : 'myDefaultAsteriskValue';
  • Worked like a charm. Thanks for both answering it and also answering what I probably would've run into afterwards. You're the man! – taylor Mar 19 '15 at 5:33
  • Happy to be able to help out, @ZackTaylor :) – Mats Mikkel Rummelhoff Mar 19 '15 at 14:59
  • So I did run into one issue, which is when the route has special characters in it (even when running through url_encode() first.) For example, route 'myroute/check-this-out' works fine, but if it's 'myroute/check-this-out%21', it leads to a 404. When using the "asterisk token" in CP, this is not an issue and does not lead to a 404. Any ideas how to get around this? – taylor Mar 19 '15 at 19:30
  • Hi @ZackTaylor, I notice you've created a new thread for the question in your above comment. Here's the link, as a followup: craftcms.stackexchange.com/questions/8754/… – Mats Mikkel Rummelhoff Mar 19 '15 at 23:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.