问题
Inside Layouts/default.ctp you will see something like this at line 39:
<div class="header-title">
<span><?= $this->fetch('title') ?></span>
</div>
fetch
suggests that it is a view block. I couldn't find this view block anywhere.
Currently it just displays the capitalized plural form of controller. Meaning to say if you are at /users/add
, the fetch('title');
gives you 'Users'
I want to change it. So I tried the following:
$this->set('title', 'Login');
in the /users/login
controller action.
Did not work.
I also tried
$this->assign('title', 'Login');
in the /users/login
controller action.
I get this error message:
Call to undefined method App\Controller\UsersController::assign()
I read the docs and from here
I get
Assigning a block’s content is often useful when you want to convert a view variable into a block. For example, you may want to use a block for the page title, and sometimes assign the title as a view variable in the controller:
Emphasis mine.
This suggests that you can use assign
inside controller. I think I have proven that this is false.
Perhaps there is a typo in the documents. Please advise how I can set the title
回答1:
This is how to do it thanks to dakota of the irc channel #cakephp.
Inside UsersController.php
:
$this->set('title', 'Login');
Inside src/Template/Layouts/default.ctp
above the $this->fetch('title');
write:
if (isset($title)) {
$this->assign('title', $title);
}
The question would be how does cakephp 3 set the default value?
Answer is found in https://github.com/cakephp/cakephp/blob/3.0/src/View/View.php#L468
Append image just in case link rot

Where you can see that it will be defaulted to the view path
回答2:
Assigning a block’s content is often useful when you want to convert a view variable into a block. For example, you may want to use a block for the page title, and sometimes assign the title as a view variable in the controller:
The above does not suggests that you should use assign in your controller (notice the bold). The above suggest that instead of using
$this->start('title');
echo $title;
$this->end()
You can use
$this->assign('title', $title);
and the $title
variable should be set from your controller.
If you want to do it the proper way from your controller you have to write
$this->set('title', $title);
and from your layout/view file write
echo $title;
回答3:
Cake 3 (and 2?) give you the possibility to override the 'View' class. This is a good place to call assign().
Example:
namespace App\View;
use Cake\View\View;
class AppView extends View
{
public function initialize()
{
$this->assign('the_block_name', "Hello from AppView");
}
}
In Layout/default.ctp:
<?= $this->fetch('the_block_name') ?>
If you, as in my case, want to have a 'default' block defined, the above solution works great. You can override the default block in any view file (.ctp) like this:
$this->start('the_block_name');
echo '<h4>Hello from current view!</h4>';
$this->end();
来源:https://stackoverflow.com/questions/26603377/how-to-alter-view-blocks-content-from-controller-in-cakephp-3