mirror of
https://github.com/codeigniter4/CodeIgniter4.git
synced 2025-02-20 11:44:28 +08:00
Allow Cells to be auto-located within */Cells directories (#6601)
* Allow Cells to be located in */Cell directories. * Refactor to use factories. * Apply suggestions from code review Co-authored-by: kenjis <kenji.uui@gmail.com> Co-authored-by: kenjis <kenji.uui@gmail.com>
This commit is contained in:
parent
00ff8f3ee3
commit
adcfde7ca1
@ -640,6 +640,11 @@ parameters:
|
||||
count: 2
|
||||
path: system/View/Cell.php
|
||||
|
||||
-
|
||||
message: "#^Call to an undefined static method CodeIgniter\\\\Config\\\\Factories\\:\\:cells\\(\\)\\.$#"
|
||||
count: 1
|
||||
path: system/View/Cell.php
|
||||
|
||||
-
|
||||
message: "#^Property Config\\\\View\\:\\:\\$plugins \\(array\\) on left side of \\?\\? is not nullable\\.$#"
|
||||
count: 1
|
||||
|
@ -12,6 +12,7 @@
|
||||
namespace CodeIgniter\View;
|
||||
|
||||
use CodeIgniter\Cache\CacheInterface;
|
||||
use CodeIgniter\Config\Factories;
|
||||
use CodeIgniter\View\Exceptions\ViewException;
|
||||
use Config\Services;
|
||||
use ReflectionException;
|
||||
@ -68,9 +69,13 @@ class Cell
|
||||
*/
|
||||
public function render(string $library, $params = null, int $ttl = 0, ?string $cacheName = null): string
|
||||
{
|
||||
[$class, $method] = $this->determineClass($library);
|
||||
[$instance, $method] = $this->determineClass($library);
|
||||
|
||||
// Is it cached?
|
||||
$class = is_object($instance)
|
||||
? get_class($instance)
|
||||
: null;
|
||||
|
||||
// Is the output cached?
|
||||
$cacheName = ! empty($cacheName)
|
||||
? $cacheName
|
||||
: str_replace(['\\', '/'], '', $class) . $method . md5(serialize($params));
|
||||
@ -79,9 +84,6 @@ class Cell
|
||||
return $output;
|
||||
}
|
||||
|
||||
// Not cached - so grab it...
|
||||
$instance = new $class();
|
||||
|
||||
if (method_exists($instance, 'initController')) {
|
||||
$instance->initController(Services::request(), Services::response(), Services::logger());
|
||||
}
|
||||
@ -197,7 +199,10 @@ class Cell
|
||||
throw ViewException::forNoCellClass();
|
||||
}
|
||||
|
||||
if (! class_exists($class, true)) {
|
||||
// locate and return an instance of the cell
|
||||
$class = Factories::cells($class);
|
||||
|
||||
if (! is_object($class)) {
|
||||
throw ViewException::forInvalidCellClass($class);
|
||||
}
|
||||
|
||||
|
28
tests/_support/Cells/StarterCell.php
Normal file
28
tests/_support/Cells/StarterCell.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* This file is part of CodeIgniter 4 framework.
|
||||
*
|
||||
* (c) CodeIgniter Foundation <admin@codeigniter.com>
|
||||
*
|
||||
* For the full copyright and license information, please view
|
||||
* the LICENSE file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Tests\Support\Cells;
|
||||
|
||||
/**
|
||||
* Class StarterCell
|
||||
*
|
||||
* This class is only used to provide a reference point
|
||||
* during tests to make sure that things work as expected.
|
||||
*/
|
||||
class StarterCell
|
||||
{
|
||||
public function hello($params)
|
||||
{
|
||||
$name = $params['name'] ?? 'World';
|
||||
|
||||
return "Hello {$name}!";
|
||||
}
|
||||
}
|
@ -251,4 +251,10 @@ final class CellTest extends CIUnitTestCase
|
||||
{
|
||||
$this->assertSame(Response::class, $this->cell->render('\Tests\Support\View\SampleClassWithInitController::index'));
|
||||
}
|
||||
|
||||
public function testLocateCellSuccess()
|
||||
{
|
||||
$this->assertSame('Hello World!', $this->cell->render('StarterCell::hello'));
|
||||
$this->assertSame('Hello CodeIgniter!', $this->cell->render('StarterCell::hello', ['name' => 'CodeIgniter']));
|
||||
}
|
||||
}
|
||||
|
@ -155,6 +155,7 @@ Others
|
||||
- Added ``$routes->useSupportedLocalesOnly(true)`` so that the Router returns 404 Not Found if the locale in the URL is not supported in ``Config\App::$supportedLocales``. See :ref:`Localization <localization-in-routes>`
|
||||
- Now you can specify Composer packages to auto-discover manually. See :ref:`Code Modules <modules-specify-composer-packages>`.
|
||||
- Added new ``$routes->view()`` method to return a the view directly. See :ref:`View Routes <view-routes>`.
|
||||
- View Cells are now first-class citizens and can located in the **app/Cells** directory. See :ref:`View Cells <view-cells-app-cells>`.
|
||||
|
||||
Changes
|
||||
*******
|
||||
|
@ -2,16 +2,22 @@
|
||||
View Cells
|
||||
##########
|
||||
|
||||
View Cells allow you to insert HTML that is generated outside of your controller. It simply calls the specified
|
||||
class and method, which must return a string of valid HTML. This method could be in any callable method, found in any class
|
||||
that the autoloader can locate. The only restriction is that the class can not have any constructor parameters.
|
||||
This is intended to be used within views, and is a great aid to modularizing your code.
|
||||
View Cells allow you to insert HTML that is generated outside of your controller. It simply calls the specified class and method, which must return a string of valid HTML. This method could be in any callable method, found in any class that the autoloader can locate. The only restriction is that the class can not have any constructor parameters. This is intended to be used within views, and is a great aid to modularizing your code.
|
||||
::
|
||||
|
||||
<?= view_cell('\App\Libraries\Blog::recentPosts') ?>
|
||||
|
||||
In this example, the class ``App\Libraries\Blog`` is loaded, and the method ``recentPosts()`` is run. The method
|
||||
must return the generated HTML as a string. The method can be either a static method or not. Either way works.
|
||||
In this example, the class ``App\Libraries\Blog`` is loaded, and the method ``recentPosts()`` is run. The method must return the generated HTML as a string. The method can be either a static method or not. Either way works.
|
||||
|
||||
.. _view-cells-app-cells:
|
||||
|
||||
app/Cells
|
||||
---------
|
||||
|
||||
Since v4.3.0, if the Cell is a class, you can locate it in the **app/Cells** directory and it can be discovered automatically, allowing the use of just the class name and method::
|
||||
<?= view_cell('Blog::recentPosts') ?>
|
||||
|
||||
This respects the :ref:`Factories preferApp option <factories-options>`, so if you have a class in both **app/Cells** and **MyNamespace/Cells**, the one in **app/Cells** will be used when ``preferApp`` is ``true``.
|
||||
|
||||
Cell Parameters
|
||||
---------------
|
||||
|
Loading…
x
Reference in New Issue
Block a user