0
votes

I'm trying to setup the following routing in cakePHP 2.3:

domain/news/slug

I've followed the cookbook guidelines on routing and the route that gets created is correct. The problem I run into is that when selecting the link I get the 'Missing Method in NewsController' error message.

Here's what I've configured:

    Router::connect(
    '/news/:slug/', 
    array('controller' => 'news', 'action' => 'view'), 
    array(
        'pass' => array('slug'),
        'slug' => '[^_]+'
        )
    );

I'm passing in the slug with a regular expression (any string that does not include an underscore).

This is my link in the index page:

        <?php echo $this->Html->link(
          $news['News']['title'], 
          array(
            'controller' => 'news',
            'action' => 'view',
            'slug' => $news['News']['slug']
            )
          ); ?>

As mentioned, the URL is built correctly, and looks like this: /news/test-slug-news-story

But when I click on it I get the 'Missing Method in NewsController' error message

Is it obvious what I'm missing, cause I've looked at this too long to be able to see it.

Thanks, Paul

2
I’d use a whitelist rather than a blacklist for matching slugs.Martin Bean
thanks Martin, would this equal a whitelist, '[a-zA-Z0-9_-]+'Paul
It would, yeah. Because you’re specifying which characters should be in a pattern, and not which characters shouldn’t be (which can lead to errors in the case you forget to blacklist something). It’s better to be overly cautious than not cautious enough.Martin Bean

2 Answers

0
votes

You can try this one:

<?php
// Routing code
Router::connect('/news/:slug/', 
    array(
        'controller' => 'news', 
        'action' => 'view'
    ), 
    array(
       'slug' => '[a-zA-Z0-9_-]+'
    )
);
?>

<?php 
// HTML Link code.    
echo $this->Html->link(
    $news['News']['title'], 
    array(
        'controller' => 'news',
        'action' => 'view',
        'slug' => $news['News']['slug']
    )
); 
?>

If it is not working for you please let me know :)

Thanks

0
votes

As mentioned above, I discovered that by having a backslash after 'slug' in the route setting, the controller interprets the ':slug/' as the controller action.

One of those 'doh' moments.

Code should look like this:

    Router::connect(
    '/news/:slug', 
    array('controller' => 'news', 'action' => 'view'), 
    array(
        'pass' => array('slug'),
        'slug' => '[a-zA-Z0-9_-]+'
        )
    );