phpcakephproutescakephp-2.0cakephp-routing

CakePHP create route for post with slug and date


Right now I have these routes for my CakePHP blog

Router::connect('/blog', array('controller' => 'posts', 'action' => 'index'));
Router::connect('/blog/:slug', array('controller' => 'posts', 'action' => 'view'), array('pass' => array('slug')));

I want to have my post URLs include the date like

/blog/2014/05/08/post-slug

how do I set up my route / action to accommodate this? Can I have it so when I create a link like this

echo $this->Html->link(
    $post['Post']['title'],
    array('action' => 'view', 'slug'=>$post['Post']['slug'])
);

it automatically adds the date parameters?

UPDATE

I got it working

I created this route

Router::connect('/blog/:year/:month/:day/:slug', array('controller'=>'posts', 'action' => 'view'),
    array(
        'year' => '[12][0-9]{3}',
        'month' => '0[1-9]|1[012]',
        'day' => '0[1-9]|[12][0-9]|3[01]',
        'pass' => array('year', 'month', 'day', 'slug')
    )

Instead of creating my own helper for this I just overrode the url method in AppHelper

class AppHelper extends Helper {
    public function url($url = null, $full = false) {
        if(is_array($url)) {
            // add dates to posts
            if(isset($url['post'])) {
                $url['slug'] = $url['post']['Post']['slug'];
                if(!empty($url['post']['Post']['published'])) {
                    $url['year'] = date('Y', strtotime($url['post']['Post']['published']));
                    $url['month'] = date('m', strtotime($url['post']['Post']['published']));
                    $url['day'] = date('d', strtotime($url['post']['Post']['published']));
                }
                unset($url['post']);
            }
        }
        return parent::url($url, $full);
    }
}

and then I create the links with

echo $this->Html->link(
    $post['Post']['title'],
    array('action' => 'view', 'post'=>$post)
);

Solution

  • In routes:

    Router::connect('/blog/*', array('controller' => 'posts', 'action' => 'view'));

    Then, in your posts controller, define the action this way:

    public function view ($year, $month, $day, $slug) {}

    As for automatically adding the date parameters to your links, I would write a helper with a function that would take in the data array for the post, and then spit out the link you want.