Multi-segment routing tokens

Matching multiple segments of a URL in Runway 3

The routing system in Runway relies on matching URL segments - that is, the parts of the URL that fall between the slashes. You can either match segments literally with a string, or as a variable with a token.


Most of the time, that’s all you need to build up a flexible system of URLs. Sometimes, however, it’s useful to be able to match a pattern that goes across multiple segments but treats the result as one. Take the following blog post URL for example:


The unique identifer for the post in this case is 2017/04/26/cats-are-awesome, combining the title of the post with the date. A naive approach to writing a pattern to match the URL might look like this:


This would certainly work, and would give you integers for year, month and day, and a string for the title. In order to use those in a filter, you’d need to stick them all back together.

'filter' => 'postSlug',
'value' => perch_get('year').'/'.perch_get('month').'/'.perch_get('day').'/'.perch_get('title'),

Rather inelegant, to say the least.

One way to address this is to declare a custom routing token to match the whole thing as one atomic lump:

'blogslug' => '[1-2][0-9]{3}\/[0-9]{2}\/[0-3][0-9]\/[a-z0-9\-]+',

This would then enable us to write our route as blog/[blogslug:title] and then access the entire identifier as one item in our page with perch_get('title'). That’s better, but it’s not exactly convenient to write regular expressions for custom tokens that are just made up of simple components.

To make this much easier in Runway 3, we added multi-segment tokens.

Using multi-segment tokens

To write a route to match our blog URL using a multi-segment token couldn’t be simpler. Use multiple tokens, and separate them with slashes:


The router will now look for integer-slash-integer-slash-integer-slash-slug and call the whole thing title for us to access with perch_get('title').

This is one of those features that is easy to over-think. If the thing you want to match includes slashes, add slashes between the tokens and it should all just work as you expect.