Type to search columns, filters, options, and extensions.

to navigate · Enter to open · Esc to close

Documentation

Template Column

Render table cells with a custom server-side Twig template

TemplateColumn delegates cell rendering to a Twig template. Use it when you need server-side HTML that depends on row state, complex conditionals, or components that are impractical to build as a JavaScript render callback.

Basic Usage

use Pentiminax\UX\DataTables\Column\TemplateColumn;

TemplateColumn::new('status_display', 'Status')
    ->setField('status')
    ->setTemplate('datatable/columns/user_status.html.twig');

The column name (status_display) is the key used in mapRow(). setField() tells the row mapper which property to read from the row object.

Template Context

Inside the template, the following variables are available:

VariableValue
rowThe object passed to mapRow() (the projected DTO when a page projector is active, otherwise the source object)
sourceThe original hydrated object. Same reference as row when no projector is active
payloadThe array returned by mapRow(). Use it to read a mapped key other than this cell’s
dataThe resolved field value for this cell
columnSerialized column configuration array

Read domain properties from row, this cell’s value from data, and any other mapped key from payload.

payload holds the row as the earlier pipeline stages left it, so cells rendered by other TemplateColumns and the row action metadata are absent from it. A payload entry can also be null while data is set: a null mapped value falls back to reading the object, and normalization writes null for objects that are not DateTimeInterface, BackedEnum, or Stringable.

entity is a deprecated alias of row in TemplateColumn templates. Prefer row. Collapsible detail rows and edit modals expose their own unrelated entity variable, which is not deprecated.

Example template:

{# templates/datatable/columns/user_status.html.twig #}
<span class="badge bg-{{ data == 'active' ? 'success' : 'danger' }}">
    {{ data|capitalize }}
</span>

Passing Parameters

Pass static parameters to the template via setTemplate():

TemplateColumn::new('actions', 'Actions')
    ->setTemplate('datatable/columns/row_actions.html.twig', [
        'editRoute' => 'admin_user_edit',
    ]);

Parameters are merged into the template context. The keys row, source, payload, data, column, and entity are reserved: passing one throws an InvalidArgumentException.

API Reference

MethodDescription
TemplateColumn::new(string $name, string $title = '')Creates a new TemplateColumn (type: html)
setTemplate(string $template, array $parameters = [])Set the Twig template path and optional static parameters. Throws on an empty path, and on a parameter using a reserved context key.
getTemplate(): stringReturns the configured template path. Throws if not set.
getTemplateParameters(): arrayReturns the static parameters passed to the template

Complete Example

use Pentiminax\UX\DataTables\Attribute\AsDataTable;
use Pentiminax\UX\DataTables\Column\NumberColumn;
use Pentiminax\UX\DataTables\Column\TemplateColumn;
use Pentiminax\UX\DataTables\Column\TextColumn;
use Pentiminax\UX\DataTables\Model\AbstractDataTable;

#[AsDataTable(Product::class)]
final class ProductsDataTable extends AbstractDataTable
{
    public function configureColumns(): iterable
    {
        yield NumberColumn::new('id', 'ID');
        yield TextColumn::new('name', 'Name');
        yield TemplateColumn::new('stock_badge', 'Stock')
            ->setField('stock')
            ->setTemplate('datatable/columns/stock_badge.html.twig');
    }

    protected function mapRow(mixed $row): array
    {
        return [
            'id'         => $row->getId(),
            'name'       => $row->getName(),
            'stock_badge' => $row->getStock(),
        ];
    }
}
{# templates/datatable/columns/stock_badge.html.twig #}
{% set variant = data > 10 ? 'success' : (data > 0 ? 'warning' : 'danger') %}
<span class="badge text-bg-{{ variant }}">{{ data }}</span>