Skip to content

Commit 2b5e848

Browse files
authored
Nested sections rendering (#4622)
* Fix: Nested sections rendering * Changed UG and applied PR suggestions
1 parent 1472864 commit 2b5e848

File tree

5 files changed

+68
-8
lines changed

5 files changed

+68
-8
lines changed

system/View/View.php

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ class View implements RendererInterface
109109
*/
110110
protected $layout;
111111

112+
112113
/**
113114
* Holds the sections and their data.
114115
*
@@ -121,9 +122,18 @@ class View implements RendererInterface
121122
* if any.
122123
*
123124
* @var string|null
125+
* @deprecated
124126
*/
125127
protected $currentSection;
126128

129+
/**
130+
* The name of the current section being rendered,
131+
* if any.
132+
*
133+
* @var array<string>
134+
*/
135+
protected $sectionStack = [];
136+
127137
/**
128138
* Constructor
129139
*
@@ -227,7 +237,7 @@ public function render(string $view, array $options = null, bool $saveData = nul
227237
// When using layouts, the data has already been stored
228238
// in $this->sections, and no other valid output
229239
// is allowed in $output so we'll overwrite it.
230-
if (! is_null($this->layout) && empty($this->currentSection))
240+
if (! is_null($this->layout) && $this->sectionStack === [])
231241
{
232242
$layoutView = $this->layout;
233243
$this->layout = null;
@@ -402,35 +412,44 @@ public function extend(string $layout)
402412
/**
403413
* Starts holds content for a section within the layout.
404414
*
405-
* @param string $name
415+
* @param string $name Section name
416+
*
417+
* @return void
418+
*
406419
*/
407420
public function section(string $name)
408421
{
422+
//Saved to prevent BC.
409423
$this->currentSection = $name;
424+
$this->sectionStack[] = $name;
410425

411426
ob_start();
412427
}
413428

414429
/**
430+
* Captures the last section
431+
*
432+
* @return void
415433
* @throws RuntimeException
416434
*/
417435
public function endSection()
418436
{
419437
$contents = ob_get_clean();
420438

421-
if (empty($this->currentSection))
439+
if ($this->sectionStack === [])
422440
{
423441
throw new RuntimeException('View themes, no current section.');
424442
}
425443

444+
$section = array_pop($this->sectionStack);
445+
426446
// Ensure an array exists so we can store multiple entries for this.
427-
if (! array_key_exists($this->currentSection, $this->sections))
447+
if (! array_key_exists($section, $this->sections))
428448
{
429-
$this->sections[$this->currentSection] = [];
449+
$this->sections[$section] = [];
430450
}
431-
$this->sections[$this->currentSection][] = $contents;
432451

433-
$this->currentSection = null;
452+
$this->sections[$section][] = $contents;
434453
}
435454

436455
/**

tests/system/View/ViewTest.php

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ public function testRenderSaveDataCover()
367367
$this->assertEquals(true, $this->getPrivateProperty($view, 'saveData'));
368368
}
369369

370-
public function testRenderSaveDataUseAflterSaveDataFalse()
370+
public function testRenderSaveDataUseAfterSaveDataFalse()
371371
{
372372
$view = new View($this->config, $this->viewsDir, $this->loader);
373373
$view->setVar('testString', 'test');
@@ -387,4 +387,17 @@ public function testCachedAutoDiscoverAndRender()
387387
// this second renderings should go thru the cache
388388
$this->assertStringContainsString($expected, $view->render('Nested/simple', ['cache' => 10]));
389389
}
390+
391+
public function testRenderNestedSections()
392+
{
393+
$view = new View($this->config, $this->viewsDir, $this->loader);
394+
395+
$view->setVar('testString', 'Hello World');
396+
397+
$content = $view->render('nested_section');
398+
399+
$this->assertStringContainsString('<p>First</p>', $content);
400+
$this->assertStringContainsString('<p>Second</p>', $content);
401+
$this->assertStringContainsString('<p>Third</p>', $content);
402+
}
390403
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php $this->extend('layout'); ?>
2+
3+
<?php $this->section('content'); ?>
4+
<p>Second</p>
5+
6+
<?php $this->section('content'); ?>
7+
<p>First</p>
8+
<?php $this->endSection(); ?>
9+
10+
<?php $this->endSection(); ?>
11+
12+
<?php $this->section('content'); ?>
13+
<p>Third</p>
14+
<?php $this->endSection(); ?>

user_guide_src/source/changelogs/v4.1.2.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ Enhancements:
1616

1717
Changes:
1818

19+
- Layouts in views now support nested sections.
1920
- ``Response::getCookie`` now returns a ``Cookie`` instance instead of an array of cookie attributes.
2021
- ``Response::getCookies`` now returns an array of ``Cookie`` instances instead of array of array of attributes.
2122
- To eliminate warnings from modern browsers' consoles, empty samesite values will be defaulted to ``Lax`` on cookie dispatch.
@@ -30,6 +31,7 @@ Changes:
3031

3132
Deprecations:
3233

34+
- Deprecated ``Codeigniter\View\View::$currentSection`` property.
3335
- Language strings and exceptions on invalid cookie samesite are deprecated for the ``CookieException``'s own exception message.
3436
- Deprecated `CodeIgniter\Entity` in favor of `CodeIgniter\Entity\Entity`
3537
- Deprecated cookie-related properties of ``Response`` in order to use the ``Cookie`` class.

user_guide_src/source/outgoing/view_layouts.rst

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,18 @@ matches the section name exists.::
6060

6161
The ``endSection()`` does not need the section name. It automatically knows which one to close.
6262

63+
Sections can contain nested sections::
64+
65+
<?= $this->extend('default') ?>
66+
67+
<?= $this->section('content') ?>
68+
<h1>Hello World!</h1>
69+
<?= $this->section('javascript') ?>
70+
let a = 'a';
71+
<?= $this->endSection() ?>
72+
<?= $this->endSection() ?>
73+
74+
6375
******************
6476
Rendering the View
6577
******************

0 commit comments

Comments
 (0)