Url Column
Render DataTable cells as links from raw URLs, Symfony routes, or per-row callables
UrlColumn renders a cell as an <a> tag. The link target can be read from the cell value directly, generated from a Symfony route, or computed with a per-row callable.
Basic Usage
When the cell value already contains the URL, no extra configuration is needed:
use Pentiminax\UX\DataTables\Column\UrlColumn;
UrlColumn::new('website', 'Website');
Renders as: <a href="https://example.com">https://example.com</a>
Empty Values
When a row has no resolvable URL (a null/empty field, or linkToRoute()/linkToUrl()
resolving to nothing for that row), the column renders its plain, escaped text instead of an
<a> tag:
UrlColumn::new('website', 'Website');
A row with an empty website value renders as plain text — no href-less anchor. This avoids
producing <a href=""></a>, which has no accessible name or purpose and fails
WCAG 2.4.4.
This also applies to linkToRoute()/linkToUrl(): when the resolver returns nothing for a
particular row, that row falls back to plain text too — the cell’s own value (e.g. a name) is
never substituted in as a fake href, since it isn’t a URL at all.
If a use case genuinely needs the old always-render-an-anchor behavior, opt back in with
renderEmptyAsAnchor():
UrlColumn::new('website', 'Website')
->renderEmptyAsAnchor();
Symfony Route
Use linkToRoute() when the URL should be generated from a Symfony route. The callable receives the original source object (or the row array for inline data).
use App\Entity\User;
use Pentiminax\UX\DataTables\Column\UrlColumn;
UrlColumn::new('email', 'Email')
->linkToRoute('admin_user_show', static fn (User $user): array => [
'id' => $user->getId(),
]);
The displayed text stays the column value (email here). Only the href is generated from the route.
Pass a static array when the parameters do not depend on the row:
UrlColumn::new('help', 'Help')
->linkToRoute('app_help', ['section' => 'users']);
Custom URL per Row
Use linkToUrl() for external URLs or computed URLs:
use App\Entity\User;
use Pentiminax\UX\DataTables\Column\UrlColumn;
UrlColumn::new('profileLabel', 'Profile')
->linkToUrl(static fn (User $user): string => 'https://example.com/u/' . $user->getSlug())
->openInNewTab();
linkToUrl() also accepts a static string:
UrlColumn::new('support', 'Support')
->setDisplayValue('Contact support')
->linkToUrl('/support');
linkToRoute() and linkToUrl() are mutually exclusive — calling one clears the other.
Open in New Tab
UrlColumn::new('website', 'Website')
->openInNewTab();
Adds target="_blank" and rel="noopener noreferrer".
Custom Display Text
Use a fixed label instead of the cell value:
UrlColumn::new('profile_url', 'Profile')
->setDisplayValue('View profile');
External Link Icon
Append a visual indicator that the link opens externally:
UrlColumn::new('website', 'Website')
->showExternalIcon();
Protocol Options
Use setDefaultProtocol() to prepend a protocol to values that do not already include one:
UrlColumn::new('website', 'Website')
->setDefaultProtocol('https');
With this configuration, a value like example.com is rendered with href="https://example.com" while keeping example.com as the displayed text.
Use allowedProtocols() to render only specific URL protocols as links:
UrlColumn::new('website', 'Website')
->allowedProtocols(['http', 'https']);
Values with other protocols are escaped and rendered as plain text. You can combine both options:
UrlColumn::new('website', 'Website')
->setDefaultProtocol('https')
->allowedProtocols(['https']);
API Reference
| Method | Description |
|---|---|
UrlColumn::new(string $name, string $title = '') | Creates a new UrlColumn (type: html) |
linkToRoute(string $routeName, array|callable|null $params = null) | Generate href from a Symfony route. Params can be a static array or a per-row callable. |
linkToUrl(string|callable $url) | Set href from a static string or a per-row callable. Clears any configured route. |
openInNewTab() | Add target="_blank" and rel="noopener noreferrer" |
setDisplayValue(string $value) | Use a fixed label instead of the cell value |
showExternalIcon(bool $show = true) | Append the external-link icon after the anchor text |
setDefaultProtocol(string $protocol) | Prepend a protocol to href values that do not already include one |
allowedProtocols(array $protocols) | Render only URLs with the listed protocols as links |
renderEmptyAsAnchor(bool $render = true) | Render <a href=""> for rows with no resolvable URL instead of falling back to plain text |
Complete Example
use App\Entity\User;
use Pentiminax\UX\DataTables\Attribute\AsDataTable;
use Pentiminax\UX\DataTables\Column\NumberColumn;
use Pentiminax\UX\DataTables\Column\TextColumn;
use Pentiminax\UX\DataTables\Column\UrlColumn;
use Pentiminax\UX\DataTables\Model\AbstractDataTable;
#[AsDataTable(User::class)]
final class UsersDataTable extends AbstractDataTable
{
public function configureColumns(): iterable
{
yield NumberColumn::new('id', 'ID');
yield TextColumn::new('name', 'Name');
yield UrlColumn::new('name', 'Profile')
->linkToRoute('admin_user_show', static fn (User $user): array => [
'id' => $user->getId(),
]);
yield UrlColumn::new('website', 'Website')
->openInNewTab()
->showExternalIcon();
}
protected function mapRow(mixed $row): array
{
return [
'id' => $row->getId(),
'name' => $row->getName(),
'website' => $row->getWebsite(),
];
}
}