:any/:any
Ran into an interesting situation today. I have the following dynamic-ish routes:
- /surf/articles
- /surf/videos
- /surf/tutorials
- /skate/articles
- /skate/videos
- /skate/tutorials
- /snow/articles
- /snow/videos
- /snow/tutorials
I tried to clean up my routing with:
/**
* Check for topic / content type combos like:
*
* - surf/articles
* - skate/brands
* - surf/promotions
*/
':any/:any' => function (\rsanchez\ResourceRouter\Router $router, $topicWildcard, $contentTypeWildcard) {
$topics = array('surf', 'skate', 'snow');
$contentTypes = array('articles', 'brands', 'places', 'promotions', 'tutorials');
$topic = (string) $topicWildcard;
$contentType = (string) $contentTypeWildcard;
if(true === in_array($topic, $topics)
&& true === in_array($contentType, $contentTypes)) {
return $router->setTemplate("topics/" . $contentType);
}
},
Unfortunately this didn't work in practice because :any is added to the query string here: https://github.com/rsanchez/resource_router/blob/master/system/expressionengine/third_party/resource_router/libraries/ResourceRouter/Router.php#L247
I'm wondering if the query string should only be build from segment_3 onwards?
I refactored this an wildcards are still proving an issue:
/**
* Topic based routing
*/
$topics = array('surf', 'skate', 'snow');
$contentTypes = array('articles', 'brands', 'places', 'promotions', 'tutorials');
$topicRoutes = array();
foreach($topics as $topic) {
// Create and index topic route
$topicRoutes[$topic] = function (\rsanchez\ResourceRouter\Router $router) use ($topic) {
$router->setTemplate('topics/index');
$router->setVariable('page_topic', $topic);
};
// Create routes for each topic / content type combo
foreach($contentTypes as $contentType) {
$topicRoutes[$topic . "/" . $contentType . "/:pagination"] = function (\rsanchez\ResourceRouter\Router $router) use ($topic, $contentType) {
$router->setTemplate('topics/' . $contentType);
$router->setVariable('page_content_type', $contentType);
$router->setVariable('page_topic', $topic);
};
}
}
$routes = array_merge($routes, $topicRoutes);
return $routes;
In the case of snow/articles/:pagination:
$query_string = preg_replace('#^'.preg_quote(str_replace(array('(', ')'), '', substr($rule, 0, $wildcard))).'#', '', $uri_string);
$query_string is being set to snow/articles. The regexp evaluates to: #^snow/articles/# and the $uri_string is snow/articles. It looks like the regexp has an extra slash which means it's not matching.
Ok found a work around which doesn't seem very intuitive is removing the / before :pagination. Example:
/surf/articles/:pagination becomes /surf/articles:pagination.
Sounds like a bug to me. I have to re-factor some things to make this easier to test before I can address the underlying issue, though.