Get it All
Together

I’ve discovered an interesting behavior in CakePHP that, as far as I know, is not documented in the book. I’d rather not attempt to edit the book – I’m not sure I’m right and anyway, they’ve just changed the book in some rather annoying way that I’d like to observe a bit before using – so instead I’ll just note it here for now.

The behavior in question concerns the pass array that exists in the Controller $this->params array and also the one that exists in the Router::connect function. Apparently, these two are connected in at least one very specific way. Namely: the order of elements in the Router::connect pass array overrides the order of elements in the URL model. Consider the following:

[php]

/rating_events/ny/east_rochester/12

/**
* Entry in routes.php:
*/
Router::connect(
‘/rating_events/:location/:city/:company’,
array(‘controller’ =>; ‘rating_events’, ‘action’ =>; ‘index’),
array( ‘pass’ => array(‘company’, ‘location’, ‘city’),
<– Insert regular expressions here –>
)
);
[/php]

In the above code, if the pass array was not set,we would expect that the pass array in $this->params[‘pass’] would follow the natural order in the URL:
[php]
array(‘ny’, ‘east_rochester’, 12);
[/php]
But with the ‘pass’ array set in Router::connect, the array actually comes out like this:
[php]
array(12, ‘ny’, ‘east_rochester’);
[/php]

You can therefore define the exact order of elements in that resulting params array. I can see this being handy as in the development process I’m currently going through, where the order and number of parameters passed in this way might be different from Controller to Controller, but always referring to much of the same data and using a lot of shared functions. Being able to organize the order of this array – for example, always having city and location appear in the same order and at the same numeric position – lowers the cost of processing and developing later when you don’t need to make exceptions in your code for Controller A versus Controller B.

I happened upon this when reorganizing my URL structure to try to make it universal. I couldn’t get the params[‘pass’] array to work, so I printed it out. Imagine my surprise when it was a completely different order than I expected!

Only a very small handful of people from Rochester and the surrounding areas – those who like local music – will get the reference in the title of this post. Maybe a few people outside of the Rochester area. That’s OK. It’s a small homage to a favourite local band…

By now, most of us who are committed to social web development take it as a given that URLs should be as clean as possible for as much content on your site as possible[2. For a good discussion of clean URLs, their meaning and their use, see this article.]. Clean, clear URLs provide your audience with an intuitive way to understand the structure of your website, provide an easy method to return to favourite topics or sections of your site and not least-importantly, provide search engines with easily keyword-associated URLs to log and serve to their customers.

With CakePHP, clean URLs are part of the normal process of building pages, rather than an imposition. A URL to a given resource on your CakePHP website will have a format of domain.com/:controller/:action/:param/:param…[1. If you’re not familiar with this format, have a look at this page, which is our topic of discussion, anyway.] Without knowing how your site will be organized, this is a fairly intuitive way of organizing URLs. Your controller name should be fairly descriptive of what it works with, “posts,” or “teeshirts”; your action will probably be fairly descriptive of what its meant to do, “edit,” “view,” “index,” and so forth.

But not in all cases does the standard formatting work. In the case of the site that I’m in the process of developing, PotholePatrol.org, I needed to make some changes to the way CakePHP structured it’s URLs to make things slightly more intuitive to the layout of the website. For example, since the organization of data revolves around Metro areas containing one or more Towns having many Potholes, using /metros, /towns/ and /potholes didn’t make sense and wouldn’t have accurately reflected that organization.
Continue reading