ZombieSheep
ZombieSheep

Reputation: 29953

CakePHP - How do i set the page title to an item name?

OK, so I'm trying to teach myself the CakePHP framework, and I'm trying to knock up a simple demo app for myself.

I have the controllers, views and models all set up and working, but I want to do something slightly more than the basic online help shows.

I have a guitars_controller.php file as follows...

<?php
class GuitarsController extends AppController {
    var $name = 'Guitars';
    function index() {
        $this->set('Guitars', $this->Guitar->findAll());
        $this->pageTitle = "All Guitars";
    }
    function view($id = null) {
        $this->Guitar->id = $id;
        $this->set('guitar', $this->Guitar->read());
        // Want to set the title here.
    }
}
?>

The 'Guitar' object contains an attribute called 'Name', and I'd like to be able to set that as the pageTitle for the individual page views.

Can anyone point out how I'd do that, please?

NB: I know that there is general disagreement about where in the application to set this kind of data, but to me, it is data related.

Upvotes: 5

Views: 13129

Answers (10)

windmaomao
windmaomao

Reputation: 7680

OK, I really want to set the page title in the controller instead in the view. So here's what I did:

class CustomersController extends AppController {

    var $name = 'Customers';

    function beforeFilter() {
        parent::beforeFilter();
        $this->set('menu',$this->name);
        switch ($this->action) {
          case 'index':
            $this->title = 'List Customer';
            break;
          case 'view':
            $this->title = 'View Customer';
            break;
          case 'edit':
            $this->title = 'Edit Customer';
            break;
          case 'add':
            $this->title = 'Add New Customer';
            break;
          default:
            $title = 'Welcome to '.$name;
            break;
        }
        $this->set('title',$this->title);
      }

The trick is that you can't set $this->title inside any action, it won't work. It seems to me that the web page reaches action after rendering, however you can do it in beforeFilter.

Upvotes: 0

Tarik
Tarik

Reputation: 81771

As of CakePHP 1.3, setting page title has been changed.

$this->pageTitle = "Title"; //deprecated

$this->set("title_for_layout",Inflector::humanize($this->name)); // new way of setting title

Note: More about Inflector: http://api13.cakephp.org/class/inflector#method-Inflector

Upvotes: 1

bob
bob

Reputation:

echo "<pre>"; print_r($this);echo "</pre>";

how about

pr( $this );

Upvotes: 0

Paolo Bergantino
Paolo Bergantino

Reputation: 488544

You can set this in the controller:

function view($id = null) {
    $guitar = $this->Guitar->read(null, $id);
    $this->set('guitar', $guitar);
    $this->pageTitle = $guitar['Guitar']['name'];
}

Or in the view:

<? $this->pageTitle = $guitar['Guitar']['name']; ?>

The value set in the view will override any value that may have already been set in the controller.

For security, you must ensure that your layout / view that displays the pageTitle html-encodes this arbitrary data to avoid injection attacks and broken html

<?php echo h( $title_for_layout ); ?>

Upvotes: 4

Alexander Morland
Alexander Morland

Reputation: 6454

In response to your own answer about oo paradigm. Its like this :

function view($id) {
    $this->Guitar->id = $id;
    $this->Guitar->read();
    $this->pageTitle = $this->Guitar->data['Guitar']['name'];
    $this->set('data', $this->Guitar->data);
}

By the way, you should check if id is set and valid etc, since this is url user input.

Upvotes: 1

neilcrookes
neilcrookes

Reputation: 4203

These actions are model agnostic so can be put in your app/app_controller.php file

<?php
class AppController extends Controller {
    function index() {
        $this->set(Inflector::variable($this->name), $this->{$this->modelClass}->findAll());
        $this->pageTitle = 'All '.Inflector::humanize($this->name);
    }
    function view($id = null) {
        $data = $this->{$this->modelClass}->findById($id);
        $this->set(Inflector::variable($this->modelClass), $data);
        $this->pageTitle = $data[$this->modelClass][$this->{$this->modelClass}->displayField];
    }
}
?>

Pointing your browser to /guitars will invoke your guitars controller index action, which doesn't exist so the one in AppController (which GuitarsController inherits from) will be run. Same for the view action. This will also work for your DrumsController, KeyboardsController etc etc.

Upvotes: 5

ZombieSheep
ZombieSheep

Reputation: 29953

Ah, the none-obvious answer is as follows...

$this->pageTitle = $this->viewVars['guitar']['Guitar']['Name'];

I found this by placing the following code in the controller (was a long shot that paid off, to be honest)

echo "<pre>"; print_r($this);echo "</pre>";

Thanks to all those that tried to help.

Upvotes: 0

rg88
rg88

Reputation: 20977

"but I want to do something slightly more than the basic online help shows."

Isn't that always the rub? So much documentation is geared towards a bare minimum that it really does not help much. You can complete many of the tutorials available but as soon as you take 1 step off the reservation the confusion sets in. Well, it's either bare minimum or pro developer maximum but rarely hits that sweet spot of ease, clarity and depth.

I'm currently rewriting some Zend Framework documentation for my own use simply so I can smooth out the inconsistencies, clarify glossed over assumptions and get at the core, "best practice" way of understanding it. My mantra: Ease, clarity, depth. Ease, clarity, depth.

Upvotes: 0

Gaurav
Gaurav

Reputation: 486

It should go in the controller. See this

Upvotes: 0

FlySwat
FlySwat

Reputation: 175653

$this->pageTitle = $this->Guitar->Name;

It should go in the View though, I don't PHP, or cakePHP, but thats something a view should do, not the controller.

Upvotes: 0

Related Questions