Will
Will

Reputation: 1933

CakePHP Routing - [home]/slug as URL

I'm trying to get to grips with Cake's routing, but I'm having no luck finding a solution to my particular problem.

I want to map www.example.com/slug to www.example.com/venues/view/slug, where slug is the URL friendly name of a record for a particular venue.

I also want to then map www.example.com/slug/events to www.example.com/events/index/venue:slug.

After reading the CakePHP documentation on Routing, a few times over, I'm none the wiser. I understand how I would create these routes for each individual venue, but I'm not sure how to get Cake to generate the routes on the fly.

Upvotes: 2

Views: 6723

Answers (2)

Scott Harwell
Scott Harwell

Reputation: 7465

You want to be careful mapping something to the first path after the domain name. This means that you would be breaking the controller/action/param/param paradigm. You can do this, but it may mean that you need to define every url for your site in your routes file rather than using Cake's routing magic.

An alternative may be to use /v/ for venues and /e/ for events to keep your url short but break up the url for the normal paradigm.

If you still want to do what you requested here, you could do something like the following. It limits the slug to letters, numbers, dashes, and underscores.

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

In your controller, you would then access the slug with the following (using the first route as an example).

function view(){
    if(isset($this->params['slug'])){
        //Do something with your code here.
    }
}

Upvotes: 10

deceze
deceze

Reputation: 522091

First off, you're not connecting www.example.com/slug to www.example.com/venues/view/slug, you're connecting /slug to a controller action. Like this:

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

To generate the appropriate link, you'd do the same in reverse:

$this->Html->link('Foo',
        array('controller' => 'venues', 'action' => 'view', 'slug' => 'bar'))

That should result in the link /bar.

The problem with routing a /:slug URL is that it's a catch-all route. You need to carefully define all other routes you may want to use before this one.

Upvotes: 3

Related Questions