Middleware

A Middleware in Table Generator allows for modifying table data dynamically after the adapter has extracted it. Instead of altering the raw data source or the adapter logic, middleware provides a flexible way to process table content before rendering.

Key Responsibilities

  • Modify Data: Change cell values, add new columns, or transform data formats.
  • Apply Conditional Formatting: Highlight specific rows, add classes based on values, etc.
  • Filter and Sort: Remove unwanted rows, reorder table data, or apply business rules.

How Middleware Works

Step Description
Data Extraction The Adapter extracts data from a source (e.g., database, API, array) and converts it into a table-friendly format.
Table Creation The TableGenerator creates a Table instance using the extracted data.
Middleware Iteration The TableGenerator loops over each middleware, passing the table instance for processing.
Middleware Processing Each middleware modifies the table as needed (e.g., formatting numbers, adding buttons, modifying styles, filtering content).
Next Middleware (if available) The modified table is passed to the next middleware in the queue. This process continues until all middlewares have been applied.
Table Rendering After all middlewares have processed the data, the final table is rendered as an HTML output by the TableGenerator.

Middleware Interface

Every middleware must implement the MiddlewareInterface:

interface MiddlewareInterface {
    public function process(Table $table): Table;
}

AbstractMiddleware

To simplify the process of modifying table content, Ucscode's Table Generator provides an AbstractMiddleware class. Instead of manually iterating through rows and cells, this abstraction allows for easier traversal of table elements.

By extending AbstractMiddleware, you can efficiently modify:

  • An individual cells (Td, Th)
  • An entire rows (Tr)
  • A specific segment (Thead, Tbody, Tfoot)

Available Methods
protected AbstractMiddleware::iterateCellsIn(Table $table, callback $callback): void

The iterateCellsIn() method iterates through every cell (Td and Th) in the table. It executes the $callback and passes 3 arguments to it:

  1. CellInterface $cell — The current cell instance
  2. Tr $tr — The row instance of the current cell
  3. TableSegmentInterface $segment — The segment in which the row exists (either Thead, Tbody or Tfoot)


protected AbstractMiddleware::iterateTrsIn(Table $table, callback $callback)

The iterateTrsIn() method iterates through all table rows (Tr) across all sections. It executes the $callback and passes 2 arguments to it:

  1. Tr $tr — The current row instance
  2. TableSegmentInterface $segment — The segment in which the row exists (either Thead, Tbody or Tfoot)

Example

A middleware that adds a checkbox ☑ to the beginning of each table row:

use Ucscode\HtmlComponent\TableGenerator\Abstraction\AbstractMiddleware;
use Ucscode\HtmlComponent\TableGenerator\Component\Section\Tr;
use Ucscode\HtmlComponent\TableGenerator\Contracts\TableSegmentInterface;
use Ucscode\HtmlComponent\TableGenerator\Table;

class CheckboxMiddleware extends AbstractMiddleware
{
    public function process(Table $table): Table 
    {
        $this->iterateTrsIn($table, function (Tr $tr) {
            /**
             * This example uses UssElement but you can also use string directly
             */
            $checkbox = new UssElement('input', [
                'type' => 'checkbox'
            ]);

            $tr->getCellCollection()->prepend(new Td($checkbox));
        });

        return $table;
    }
}

If you would like to know more about UssElement, you can find reference here


Important Note:

When you instantiate a TableGenerator, the table is immediately processed. Calling the render() method multiple times will consistently produce the same output, even if you add new middleware or update the adapter afterward.

To apply changes, such as adding middleware or modifying the adapter, you must regenerate the table. This ensures that all transformations are applied to a fresh instance.

Example:

$tableGenerator = new TableGenerator($adapter, $middleware);
$tableGenerator->render(); // Output: ABC

$tableGenerator->addMiddleware($checkboxMiddleware);
$tableGenerator->render(); // Output remains: ABC (middleware not applied yet)

$tableGenerator->regenerate();
$tableGenerator->render(); // Output: ABC + Checkbox (middleware applied)

Always remember to call regenerate() whenever you make changes that should reflect in the final table output.

Source Code
If you find this project useful, consider leaving a on GitHub! Thank you!