55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content
55 changes: 31 additions & 24 deletions user_guide_src/source/outgoing/view_cells.rst
Original file line numberDiff line numberDiff line change
Expand Up@@ -19,17 +19,19 @@ Calling a View Cell
No matter which type of View Cell you are using, you can call it from any view by using the ``view_cell()`` helper method. The first parameter is the name of the class and method to call, and the second parameter is an array of parameters to pass to the method. The method must return a string, which will be inserted into the view where the ``view_cell()`` method was called.
::

<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('App\Cells\MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the above example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
If you do not include the full namespace for the class, it will assume in can be found in the ``App\Cells`` namespace. So, the following example would attempt to find the ``MyClass`` class in ``app/Cells/MyClass.php``. If it is not found there, all namespaces will be scanned until it is found, searching within a ``Cells`` subdirectory of each namespace.
::

<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']); ?>
<?= view_cell('MyClass::myMethod', ['param1' => 'value1', 'param2' => 'value2']) ?>

.. note:: Namespace omission is available since v4.3.0 and later.

You can also pass the parameters along as a key/value string:
::

<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2'); ?>
<?= view_cell('MyClass::myMethod', 'param1=value1, param2=value2') ?>

************
Simple Cells
Expand All@@ -42,7 +44,7 @@ Simple Cells are classes that return a string from the chosen method. An example

class AlertMessage
{
public function show($params): string
public function show(array $params): string
{
return "<div class="alert alert-{$params['type']}">{$params['message']}</div>";
}
Expand All@@ -51,13 +53,15 @@ Simple Cells are classes that return a string from the chosen method. An example
You would call it from within a view like:
::

<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']); ?>
<?= view_cell('AlertMessage::show', ['type' => 'success', 'message' => 'The user has been updated.']) ?>

Additionally, you can use parameter names that match the parameter variables in the method for better readability.
When you use it this way, all of the parameters must always be specified in the view cell call::

<?= view_cell('\App\Libraries\Blog::recentPosts', 'category=codeigniter, limit=5') ?>
// In a View.
<?= view_cell('Blog::recentPosts', 'category=codeigniter, limit=5') ?>

// In a Cell.
public function recentPosts(string $category, int $limit)
{
$posts = $this->blogModel->where('category', $category)
Expand All@@ -74,6 +78,8 @@ When you use it this way, all of the parameters must always be specified in the
Controlled Cells
****************

.. versionadded:: 4.3.0

Controlled Cells have two primary goals: to make it as fast as possible to build the cell, and provide additional logic and flexibility to your views, if they need it. The class must extend ``CodeIgniter\View\Cells\Cell``. They should have a view file in the same folder. By convention the class name should be PascalCase and the view should be the snake_cased version of the class name. So, for example, if you have a ``MyCell`` class, the view file should be ``my_cell.php``.

Creating a Controlled Cell
Expand All@@ -94,22 +100,23 @@ At the most basic level, all you need to implement within the class are public p
}

// app/Cells/alert_message_cell.php
<div class="alert alert-<?= $type; ?>">
<?= $message; ?>
<div class="alert alert-<?= esc($type, 'attr') ?>">
<?= esc($message) ?>
</div>

// Called in main View:
<?= view_cell('AlertMessageCell', 'type=warning, message=Failed.') ?>

.. _generating-cell-via-command:

Generating Cell via Command
===========================

.. versionadded:: 4.3.0

You can also create a controlled cell via a built in command from the CLI. The command is ``php spark make:cell``. It takes one argument, the name of the cell to create. The name should be in PascalCase, and the class will be created in the ``app/Cells`` directory. The view file will also be created in the ``app/Cells`` directory.

::

> php spark make:cell AlertMessage
> php spark make:cell AlertMessageCell
Comment thread
michalsn marked this conversation as resolved.

Using a Different View
======================
Expand All@@ -122,7 +129,7 @@ You can specify a custom view name by setting the ``view`` property in the class

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -140,7 +147,7 @@ If you need more control over the rendering of the HTML, you can implement a ``r

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
public $type;
public $message;
Expand All@@ -161,7 +168,7 @@ If you need to perform additional logic for one or more properties you can use c

use CodeIgniter\View\Cells\Cell;

class AlertMessage extends Cell
class AlertMessageCell extends Cell
{
protected $type;
protected $message;
Expand All@@ -188,7 +195,7 @@ Sometimes you need to perform additional logic for the view, but you don't want

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -198,11 +205,11 @@ Sometimes you need to perform additional logic for the view, but you don't want
}
}

// app/Cells/recent_posts.php
// app/Cells/recent_posts_cell.php
<ul>
<?php foreach ($posts as $post): ?>
<li><?= $this->linkPost($post) ?></li>
<?php endforeach; ?>
<?php endforeach ?>
</ul>

Performing Setup Logic
Expand All@@ -216,7 +223,7 @@ If you need to perform additional logic before the view is rendered, you can imp

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -229,12 +236,12 @@ If you need to perform additional logic before the view is rendered, you can imp
You can pass additional parameters to the ``mount()`` method by passing them as an array to the ``view_cell()`` helper function. Any of the parameters sent that match a parameter name of the ``mount`` method will be passed in.
::

// app/Cells/RecentPosts.php
// app/Cells/RecentPostsCell.php
namespace App\Cells;

use CodeIgniter\View\Cells\Cell;

class RecentPosts extends Cell
class RecentPostsCell extends Cell
{
protected $posts;

Expand All@@ -249,7 +256,7 @@ You can pass additional parameters to the ``mount()`` method by passing them as
}

// Called in main View:
<?= view_cell('RecentPosts::show', ['categoryId' => 5]); ?>
<?= view_cell('RecentPostsCell', ['categoryId' => 5]) ?>

************
Cell Caching
Expand All@@ -260,10 +267,10 @@ third parameter. This will use the currently configured cache engine.
::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300) ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300) ?>

You can provide a custom name to use instead of the auto-generated one if you like, by passing the new name
as the fourth parameter::

// Cache the view for 5 minutes
<?= view_cell('\App\Libraries\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>
<?= view_cell('App\Cells\Blog::recentPosts', 'limit=5', 300, 'newcacheid') ?>