codeigniter4 / CodeIgniter4

Open Source PHP Framework (originally from EllisLab)
https://codeigniter.com/
MIT License
5.37k stars 1.9k forks source link

Bug: VIew layout inconsistent #9223

Open neznaika0 opened 2 weeks ago

neznaika0 commented 2 weeks ago

PHP Version

8.3

CodeIgniter4 Version

4.5.5

CodeIgniter4 Installation Method

Git

Which operating systems have you tested for this bug?

Linux

Which server did you use?

cli-server (PHP built-in webserver)

Database

No response

What happened?

The template layout is not rendered correctly - the template is displayed first, then the expandable layout. I suspect this is because of the simplicity of $view->extend('main'). It adds a variable instead of working with layouts The display process starts with $view->nclude('include')since the layer is not installed at this stage

Steps to Reproduce

Apply patch for test

diff --git a/tests/system/View/ViewTest.php b/tests/system/View/ViewTest.php
index 08ba431161..4991c8d8bc 100644
--- a/tests/system/View/ViewTest.php
+++ b/tests/system/View/ViewTest.php
@@ -40,6 +40,54 @@ final class ViewTest extends CIUnitTestCase
         $this->config   = new Config\View();
     }

+    public function testHugeView(): void
+    {
+        $view = new View($this->config, $this->viewsDir, $this->loader);
+
+        $result = $view->render('huge/view');
+
+        $expected = <<<'EOD'
+            <!-- DEBUG-VIEW START 4 ROOTPATH/tests/system/View/Views/huge/view.php -->
+
+
+            View top
+
+            Fragment one (from "huge/view")
+
+            # include start in "huge/view"
+            <!-- DEBUG-VIEW START 3 ROOTPATH/tests/system/View/Views/huge/include.php -->
+            <!-- DEBUG-VIEW START 2 ROOTPATH/tests/system/View/Views/huge/layout.php -->
+            Layout top
+
+            Section (from "huge/view")
+
+            <!-- DEBUG-VIEW START 1 ROOTPATH/tests/system/View/Views/huge/include.php -->
+            Include top
+
+            Fragment one (from "huge/include")
+
+            Include bottom
+
+            <!-- DEBUG-VIEW ENDED 1 ROOTPATH/tests/system/View/Views/huge/include.php -->
+
+            Fragment one (from "huge/layout")
+
+            Layout bottom
+
+            <!-- DEBUG-VIEW ENDED 2 ROOTPATH/tests/system/View/Views/huge/layout.php -->
+
+            <!-- DEBUG-VIEW ENDED 3 ROOTPATH/tests/system/View/Views/huge/include.php -->
+            # include end in "huge/view"
+
+            View bottom
+
+            <!-- DEBUG-VIEW ENDED 4 ROOTPATH/tests/system/View/Views/huge/view.php -->
+
+            EOD;
+
+        $this->assertSame($expected, $result);
+    }
+
     public function testSetVarStoresData(): void
     {
         $view = new View($this->config, $this->viewsDir, $this->loader);
diff --git a/tests/system/View/Views/huge/include.php b/tests/system/View/Views/huge/include.php
new file mode 100644
index 0000000000..d0fccc9324
--- /dev/null
+++ b/tests/system/View/Views/huge/include.php
@@ -0,0 +1,5 @@
+Include top
+
+Fragment one (from "huge/include")
+
+Include bottom
diff --git a/tests/system/View/Views/huge/layout.php b/tests/system/View/Views/huge/layout.php
new file mode 100644
index 0000000000..1302a4e2b0
--- /dev/null
+++ b/tests/system/View/Views/huge/layout.php
@@ -0,0 +1,9 @@
+Layout top
+
+<?php echo $this->renderSection('content') ?>
+
+<?php echo $this->include('huge/include') ?>
+
+Fragment one (from "huge/layout")
+
+Layout bottom
diff --git a/tests/system/View/Views/huge/view.php b/tests/system/View/Views/huge/view.php
new file mode 100644
index 0000000000..5ecf6e2525
--- /dev/null
+++ b/tests/system/View/Views/huge/view.php
@@ -0,0 +1,15 @@
+<?php echo $this->extend('huge/layout') ?>
+
+<?php echo $this->section('content'); ?>
+Section (from "huge/view")
+<?php echo $this->endSection(); ?>
+
+View top
+
+Fragment one (from "huge/view")
+
+# include start in "huge/view"
+<?php echo $this->include('huge/include') ?>
+# include end in "huge/view"
+
+View bottom

Expected Output

The section and everything else should be displayed in the main layout

Anything else?

https://github.com/michalsn/codeigniter-htmx/pull/78

michalsn commented 2 weeks ago

All content within a view that extends a layout must be included within section($name) and endSection() method calls. Any content between these calls will be inserted into the layout wherever the renderSection($name) call that matches the section name exists.

https://codeigniter.com/user_guide/outgoing/view_layouts.html#using-layouts-in-views

neznaika0 commented 2 weeks ago

Good. If only a section is output, then the rest should be ignored, not added.