A while ago Jonathan Snook showed in the article Easier static pages with CakePHP 1.2 how you can easily create static pages by creating view files without corresponding controller actions. For this purpose he wrote a custom error handler. The “problem” of this approach is that an error handler is meant to show error messages, and not static pages…

And so I looked for a different approach and ended up with a modified PagesController, combined with a route. The idea is to use the convention that each file in app/views/pages can be accessed like example.com/file (i.e. about.ctp is accessed as example.com/about and about/company.ctp as example.com/about/company).

Here is the PagesController:

// app/controllers/pages_controller.php
class PagesController extends AppController{
    public $uses = array();

    public function display() {
        $viewFilename = array_pop($this->params['pass']) . '.ctp';
        $viewFilename = str_replace('-', '_', $viewFilename);

        $viewPath =  DS . $viewFilename;
        if ($this->params['pass']) {
            $viewPath = DS . implode(DS, $this->params['pass']) . $viewPath;
        }

        if (file_exists(VIEWS.'pages'.$viewPath)) {
            $this->render(null, null, VIEWS.'pages'.$viewPath);
        } else {
            $this->cakeError('error404');
        }
    }
}

To get the aforementioned URL scheme we have to define a “catch all” route in app/config/routes.php:

Router::connect('*', array('controller' => 'pages', 'action' => 'display'));

This route has to be the latest route in the routes file. And that’s also the disadvantage of this approach: because of the “catch all” route you have to define routes for all controllers…

Anyway, I hope this approach is useful for some of you :)