Skip to content

Commit 88e47af

Browse files
josbeirLordSimal
andauthored
Improve Controllers guide structure and examples (#8223)
* polish controllers guide with callouts and code groups * process copilot reviews * update control expression in example Co-authored-by: Kevin Pfeifer <info@pfiff.me> * update plugin naming Co-authored-by: Kevin Pfeifer <info@pfiff.me> * Update docs/en/controllers.md Co-authored-by: Kevin Pfeifer <info@pfiff.me> --------- Co-authored-by: Kevin Pfeifer <info@pfiff.me>
1 parent c19099a commit 88e47af

File tree

1 file changed

+120
-65
lines changed

1 file changed

+120
-65
lines changed

docs/en/controllers.md

Lines changed: 120 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -7,32 +7,47 @@ description: "Learn CakePHP controllers: handle requests, render views, manage c
77

88
`class` Cake\\Controller\\**Controller**
99

10-
Controllers are the 'C' in MVC. After routing has been applied and the correct
11-
controller has been found, your controller's action is called. Your controller
12-
should handle interpreting the request data, making sure the correct models
13-
are called, and the right response or view is rendered. Controllers can be
14-
thought of as middle layer between the Model and View. You want to keep your
15-
controllers thin, and your models fat. This will help you reuse
16-
your code and makes your code easier to test.
17-
18-
Commonly, a controller is used to manage the logic around a single model. For
19-
example, if you were building a site for an online bakery, you might have a
20-
RecipesController managing your recipes and an IngredientsController managing your
21-
ingredients. However, it's also possible to have controllers work with more than
22-
one model. In CakePHP, a controller is named after the primary model it
23-
handles.
24-
25-
Your application's controllers extend the `AppController` class, which in turn
26-
extends the core `Controller` class. The `AppController`
27-
class can be defined in **src/Controller/AppController.php** and it should
28-
contain methods that are shared between all of your application's controllers.
29-
30-
Controllers provide a number of methods that handle requests. These are called
31-
*actions*. By default, each public method in
32-
a controller is an action, and is accessible from a URL. An action is responsible
33-
for interpreting the request and creating the response. Usually responses are
34-
in the form of a rendered view, but there are other ways to create responses as
35-
well.
10+
Controllers are the 'C' in MVC. After routing is applied and the correct
11+
controller is found, your controller's action is called. Your controller
12+
should interpret the request, ensure the right models are called, and return
13+
the appropriate response or view. Controllers sit between Model and View.
14+
15+
::: tip Keep Controllers Thin
16+
Move heavy business logic into models and services. Thin controllers are easier
17+
to test and reuse.
18+
:::
19+
20+
Commonly, a controller manages logic around a single model. For example, for
21+
an online bakery you might have a RecipesController managing recipes and an
22+
IngredientsController managing ingredients. However, it's also possible to have
23+
controllers work with more than one model. In CakePHP, a controller is named
24+
after the primary model it handles.
25+
26+
::: info At a Glance
27+
28+
- Controllers coordinate request handling, model calls, and responses.
29+
- Each public method is an action by default.
30+
- Shared logic goes into `AppController`.
31+
32+
:::
33+
34+
Your application's controllers extend the `AppController` class, which extends
35+
the core `Controller` class. The `AppController` class can be defined in
36+
**src/Controller/AppController.php** and should contain methods shared between
37+
all of your application's controllers.
38+
39+
Controllers provide methods that handle requests. These are called *actions*.
40+
By default, each public method in a controller is an action and is accessible
41+
from a URL. An action interprets the request and creates the response. Usually
42+
responses are rendered views, but there are other response types as well.
43+
44+
::: details Naming and Conventions
45+
46+
- Controller names are plural, e.g. `RecipesController`.
47+
- Action names map to view templates by convention.
48+
- Use `AppController` for shared behavior.
49+
50+
:::
3651

3752
<a id="app-controller"></a>
3853

@@ -88,6 +103,14 @@ CakePHP puts all the important request information into the `$this->request`
88103
property. See the section on [Cake Request](controllers/request-response#cake-request) for more information on the
89104
CakePHP request object.
90105

106+
::: info Request Flow Summary
107+
108+
- Routes map URLs to a controller/action.
109+
- The request data is available via `$this->request`.
110+
- The action returns a response (often a rendered view).
111+
112+
:::
113+
91114
## Controller Actions
92115

93116
Controller actions are responsible for converting the request parameters into a
@@ -138,6 +161,11 @@ If for some reason you'd like to skip the default behavior, you can return a
138161
`Cake\Http\Response` object from the action with the fully
139162
created response.
140163

164+
::: tip Explicit Responses
165+
Return a `Response` when you need full control (JSON, file downloads, or
166+
custom status codes).
167+
:::
168+
141169
In order for you to use a controller effectively in your own application, we'll
142170
cover some of the core attributes and methods provided by CakePHP's controllers.
143171

@@ -158,17 +186,20 @@ The `Controller::set()` method is the main way to send data from your
158186
controller to your view. Once you've used `Controller::set()`, the variable
159187
can be accessed in your view:
160188

161-
```php
162-
// First you pass data from the controller:
189+
::: code-group
163190

191+
```php [Controller]
192+
// First you pass data from the controller:
164193
$this->set('color', 'pink');
194+
```
165195

196+
```php [Template]
166197
// Then, in the view, you can utilize the data:
167-
?>
168-
169198
You have selected <?= h($color) ?> icing for the cake.
170199
```
171200

201+
:::
202+
172203
The `Controller::set()` method also takes an
173204
associative array as its first parameter. This can often be a quick way to
174205
assign a set of information to the view:
@@ -190,6 +221,11 @@ Keep in mind that view vars are shared among all parts rendered by your view.
190221
They will be available in all parts of the view: the template, the layout and
191222
all elements inside the former two.
192223

224+
::: tip View Data Scope
225+
View variables are shared with the layout and elements. Prefer specific keys
226+
to avoid accidental collisions.
227+
:::
228+
193229
### Setting View Options
194230

195231
If you want to customize the view class, layout/template paths, helpers or the
@@ -228,6 +264,13 @@ Available strategies are:
228264

229265
You can retrieve the current strategy using `getConfigMergeStrategy()`.
230266

267+
::: details When to Change Merge Strategy
268+
269+
- Use shallow merges for small, explicit overrides.
270+
- Use deep merges when you want to extend nested defaults.
271+
272+
:::
273+
231274
::: info Added in version 5.3.0
232275
`ViewBuilder::setConfigMergeStrategy()` and `ViewBuilder::getConfigMergeStrategy()` were added.
233276
:::
@@ -265,25 +308,22 @@ Although CakePHP will automatically call it after every action's logic
265308
an alternate view file by specifying a view file name as first argument of
266309
`Controller::render()` method.
267310

311+
::: tip Skipping Auto-Render
312+
Call `$this->disableAutoRender()` when the action fully handles the response.
313+
:::
314+
268315
If `$view` starts with '/', it is assumed to be a view or
269316
element file relative to the **templates** folder. This allows
270317
direct rendering of elements, very useful in AJAX calls:
271318

272-
```php
319+
::: code-group
320+
321+
```php [Element]
273322
// Render the element in templates/element/ajaxreturn.php
274-
$this->render('/element/ajaxreturn');
323+
return $this->render('/element/ajaxreturn');
275324
```
276325

277-
The second parameter `$layout` of `Controller::render()` allows you to specify the layout
278-
with which the view is rendered.
279-
280-
#### Rendering a Specific Template
281-
282-
In your controller, you may want to render a different view than the
283-
conventional one. You can do this by calling `Controller::render()` directly. Once you
284-
have called `Controller::render()`, CakePHP will not try to re-render the view:
285-
286-
```php
326+
```php [Custom Template]
287327
namespace App\Controller;
288328

289329
class PostsController extends AppController
@@ -295,14 +335,7 @@ class PostsController extends AppController
295335
}
296336
```
297337

298-
This would render **templates/Posts/custom_file.php** instead of
299-
**templates/Posts/my_action.php**.
300-
301-
You can also render views inside plugins using the following syntax:
302-
`$this->render('PluginName.PluginController/custom_file')`.
303-
For example:
304-
305-
```php
338+
```php [Plugin Template]
306339
namespace App\Controller;
307340

308341
class PostsController extends AppController
@@ -314,7 +347,22 @@ class PostsController extends AppController
314347
}
315348
```
316349

317-
This would render **plugins/Users/templates/UserDetails/custom_file.php**
350+
:::
351+
352+
The second parameter `$layout` of `Controller::render()` allows you to specify the layout
353+
with which the view is rendered.
354+
355+
#### Rendering a Specific Template
356+
357+
In your controller, you may want to render a different view than the
358+
conventional one. You can do this by calling `Controller::render()` directly.
359+
Once you have called `Controller::render()`, CakePHP will not try to re-render
360+
the view.
361+
362+
This renders **templates/Posts/custom_file.php** instead of
363+
**templates/Posts/my_action.php**. Rendering plugin templates uses the syntax
364+
`$this->render('Users.UserDetails/custom_file')` and renders
365+
**plugins/Users/templates/UserDetails/custom_file.php**.
318366

319367
<a id="controller-viewclasses"></a>
320368

@@ -330,6 +378,10 @@ render an HTML view or render a JSON or XML response. To define the list of
330378
supported view classes for a controller is done with the `addViewClasses()`
331379
method:
332380

381+
::: info Content Negotiation
382+
Use `addViewClasses()` to serve multiple formats from the same action.
383+
:::
384+
333385
```php
334386
namespace App\Controller;
335387

@@ -450,7 +502,9 @@ controller action and rendering a view.
450502

451503
You can redirect using `routing array` values:
452504

453-
```php
505+
::: code-group
506+
507+
```php [Array URL]
454508
return $this->redirect([
455509
'controller' => 'Orders',
456510
'action' => 'confirm',
@@ -463,20 +517,20 @@ return $this->redirect([
463517
]);
464518
```
465519

466-
Or using a relative or absolute URL:
467-
468-
```php
520+
```php [Relative URL]
469521
return $this->redirect('/orders/confirm');
522+
```
470523

524+
```php [Absolute URL]
471525
return $this->redirect('https://www.example.com');
472526
```
473527

474-
Or to the referer page:
475-
476-
```php
528+
```php [Referer]
477529
return $this->redirect($this->referer());
478530
```
479531

532+
:::
533+
480534
By using the second parameter you can define a status code for your redirect:
481535

482536
```php
@@ -573,20 +627,22 @@ public function initialize(): void
573627
## Request Life-cycle Callbacks
574628

575629
CakePHP controllers trigger several events/callbacks that you can use to insert
576-
logic around the request life-cycle:
630+
logic around the request life-cycle.
577631

578-
### Event List
632+
::: details Event List
579633

580634
- `Controller.initialize`
581635
- `Controller.startup`
582636
- `Controller.beforeRedirect`
583637
- `Controller.beforeRender`
584638
- `Controller.shutdown`
585639

640+
:::
641+
586642
### Controller Callback Methods
587643

588-
By default, the following callback methods are connected to related events if the
589-
methods are implemented by your controllers
644+
By default, the following callback methods are connected to related events if
645+
the methods are implemented by your controllers.
590646

591647
#### beforeFilter()
592648

@@ -623,13 +679,12 @@ To redirect from within a controller callback method you can use the following:
623679
```php
624680
public function beforeFilter(EventInterface $event): void
625681
{
626-
if (...) {
682+
if ($this->request->getParam('prefix') !== 'Admin') {
627683
$event->setResult($this->redirect('/'));
628684

629685
return;
630686
}
631-
632-
...
687+
// Normal request handling continues.
633688
}
634689
```
635690

0 commit comments

Comments
 (0)