resource_router icon indicating copy to clipboard operation
resource_router copied to clipboard

:any/:any

Open leevigraham opened this issue 11 years ago • 3 comments

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?

leevigraham avatar Mar 17 '15 22:03 leevigraham

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.

leevigraham avatar Mar 18 '15 00:03 leevigraham

Ok found a work around which doesn't seem very intuitive is removing the / before :pagination. Example:

/surf/articles/:pagination becomes /surf/articles:pagination.

leevigraham avatar Mar 18 '15 00:03 leevigraham

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.

rsanchez avatar Mar 25 '15 13:03 rsanchez