{{-- The Role cell of the Users listing — docs/wireframes-v12/user-management.html: Super Admin Used two ways, and the model is what both hand over — the profile page includes it directly, the listing reaches it through addColumn(): @include('users.partials.role', ['model' => $user]) ->addColumn('role', 'users.partials.role') The tone comes from App\Support\RoleBadge, whose docblock explains why it is the one `match` in this application with a `default` arm: roles are rows somebody creates at runtime, not a closed enum, so there is no set to be exhaustive over. **A user with no role gets an em-dash, not an empty badge** (CR-13 §3.5). That is a real state — spatie's pivot is empty until a role is assigned, and only a seeder or a hand-edited database can produce it, since both form twins require a role — and a badge with no text in it would read as a rendering fault rather than as "none". Reached through UsersDataTable's rawColumns(['role']), **so this output is injected into the page unescaped**. The role NAME is a user-creatable string and is therefore the one untrusted value here: it goes through `{{ }}`, which escapes it for HTML, and it reaches no Javascript context on this page. The class beside it is not interpolated from the name at all — RoleBadge returns one of three constant strings — so a role called `" onmouseover="alert(1)` cannot break out of the attribute either. The relation is eager-loaded by UsersDataTable::query(), so this costs no query per row. yajra hands the row's model in as $model. --}} @php /** @var \App\Models\User $model */ $roleName = $model->roles->pluck('name')->first(); @endphp @if (is_string($roleName) && $roleName !== '') {{ $roleName }} @else — @endif