3

I've successfully created my Route using Regex. I have Several Optional Parameters in my route that I don't want displayed in the URL Helper unless the user has specified them. How can I accomplish this?

This is what I currently have

        $route = new Zend_Controller_Router_Route_Regex(
        '([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
        array(
            'controller'    => 'widget',
            'action'        => 'list',
        ),
        array(
            1 => 'color',
            2 => 'page',
            3 => 'limit'

        ),
        '%s-Widgets/'
    );

    $router->addRoute('color_widgets', $route);

I then call the URL Helper with following code

        echo $this->url(array('page' => $page), 'color_widgets', false); 

This results in /Blue-Widgets/ and does not send the Page to the URL. I can fix this by changing the reverse in the Router

    $route = new Zend_Controller_Router_Route_Regex(
        '([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
        array(
            'controller'    => 'widget',
            'action'        => 'list',
            'page'      => 1
        ),
        array(
            1 => 'color',
            2 => 'page',
            3 => 'limit'

        ),
        '%s-Widgets/page/%d'
    );

However this doesn't solve my problem say I have a Url

/Blue-Widgets/page/1/limit/10 The limit doesn't show, again I can fix that with the following

    $route = new Zend_Controller_Router_Route_Regex(
        '([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
        array(
            'controller'    => 'widget',
            'action'        => 'list',
            'page'      => 1,
            'limit'     => 10
        ),
        array(
            1 => 'color',
            2 => 'page',
            3 => 'limit'

        ),
        '%s-Widgets/page/%d/limit/%d'
    );

The problem with this is the user is at /Blue-Widgets/ and I want to take them to the next page of Blue Widgets with following code

        echo $this->url(array('page' => $page), 'color_widgets', false); 

They are actually taken to /Blue-Widgets/page/2/limit/10

When I actually want to take them to /Blue-Widgets/page/2

How can I accomplish this with the Zend Framework.

2 Answers 2

2

It is not possible to use a regex reverse route with a variable number of values. You could:

  1. Write a different route for every optional parameter (not recommended)
  2. Use a different route structure

You could, for instance change your route to:

$route = new Zend_Controller_Router_Route(
    'widgets/:color/*',
    array(
        'controller'    => 'widget',
        'action'        => 'list',
        'page'      => 1,
        'limit'     => 10
    ),
    array(
        'color' => '[a-zA-Z-_0-9-]+',
        'page' => '\d+',
        'limit' => '\d+',
    )
);

Another option would be to create your own custom route class, which can parse and build the correct uri.

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks I was trying to avoid having to write a custom route. I will try using Router_Route.
0

You've give wrong Regex match variable indexes, that's why you get weird results. Your code should look like this:

$route = new Zend_Controller_Router_Route_Regex(
'([a-zA-Z-_0-9-]+)-Widgets(?:/page/(\d+))?(?:/limit/(\d+))',
array(
    'controller'    => 'widget',
    'action'        => 'list',
),
array(
    1 => 'color',
    3 => 'page',
    5 => 'limit'
),
'%s-Widgets/'
);

$router->addRoute('color_widgets', $route);

1 Comment

I know this is old - almost as old as the code I'm working with at the moment ;) - but for anyone happening on this and unaware, I thought I'd point out the reason this isn't correct is that (?: begins a non-capturing group; stackoverflow.com/questions/3512471/…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.