Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

fcno's avatar
Level 6

Show link to parent records on filament form

Hello Masters!

Objective: to include in the edit/registration form of a model, link to parent models (belongsTo).

Why: because the relationship with parents is very deep, reaching 6 levels of belongsTo. With this, the user could easily visit the parent models if he wanted.

The road so far: I'm not sure if it's the best way, but I created a 'custon-field' called Link and set the view to render as a Filament LInk, but to me it looks like the code doesn't smell right.

<?php

namespace App\Forms\Components;

use Filament\Forms\Components\Field;

class Link extends Field
{
    protected string $view = 'forms.components.link';

    protected string|\Closure|null $url = null;

    protected string|\Closure|null $text = null;

    public function setUrl(string|\Closure|null $url): static
    {
        $this->url = $url;

        return $this;
    }

    public function getUrl(): ?string
    {
        return $this->evaluate($this->url);
    }

    public function setText(string|\Closure|null $text): static
    {
        $this->text = $text;

        return $this;
    }

    public function getText(): ?string
    {
        return $this->evaluate($this->text);
    }
}
// link.blade.php

<x-dynamic-component
    :component="$getFieldWrapperView()"
    :field="$field"
>
    <div x-data="{ state: $wire.$entangle('{{ $getStatePath() }}') }">
        <x-filament::link
            :href="$getUrl()"
            iconPosition="after"
            icon="heroicon-o-link"
            size="sm"
        >
            {{ $getText() }}
        </x-filament::link>
    </div>
</x-dynamic-component>

Link::make('localidade')
    ->setText(fn (?Model $record): string => $record->nome)
    ->setUrl(fn (?Model $record): string => LocalidadeResource::getUrl('view', ['record' => $record]))
    ->inlineLabel()

Could you tell me a better way to do this or is this the way to go?

0 likes
3 replies
LaryAI's avatar
Level 58

Your approach to creating a custom field component for Filament to display a link to the parent model is a reasonable solution. However, there are a few improvements and suggestions that can be made to ensure that your code is clean and follows best practices.

Firstly, it's important to ensure that your custom field component is reusable and flexible. Your current implementation seems to be on the right track, but let's refine it a bit.

Here's an improved version of your Link class:

namespace App\Forms\Components;

use Filament\Forms\Components\Field;

class Link extends Field
{
    protected string $view = 'forms.components.link';

    protected string|\Closure|null $url = null;
    protected string|\Closure|null $text = null;

    public function url(string|\Closure|null $url): static
    {
        $this->url = $url;
        return $this;
    }

    public function text(string|\Closure|null $text): static
    {
        $this->text = $text;
        return $this;
    }

    public function getUrl(): ?string
    {
        return $this->evaluate($this->url);
    }

    public function getText(): ?string
    {
        return $this->evaluate($this->text);
    }
}

And the link.blade.php view:

@props([
    'field',
])

<div x-data="{ state: $wire.entangle('{{ $field->getStatePath() }}') }">
    <a href="{{ $field->getUrl() }}" class="text-indigo-600 hover:text-indigo-900">
        {{ $field->getText() }}
    </a>
</div>

When using the Link component in your form, you can do something like this:

use App\Forms\Components\Link;
use App\Filament\Resources\LocalidadeResource;

Link::make('parentLink')
    ->text(fn (?Model $record): string => $record ? $record->nome : '')
    ->url(fn (?Model $record): string => $record ? LocalidadeResource::getUrl('view', ['record' => $record]) : '#')
    ->dehydrated(false) // Prevents the field from being included in the form submission
    ->disabled(true) // Makes the field non-interactive
    ->visible(fn (?Model $record): bool => $record !== null); // Only show the link if there is a record

This code snippet creates a Link field that will display a link to the parent model if it exists. The dehydrated(false) method call ensures that the field is not included in the form submission, and disabled(true) makes it non-interactive. The visible method is used to conditionally display the link only if there is a parent record.

Remember to replace Model with the actual model class you are using and adjust the LocalidadeResource and nome to match your actual resource and field names.

This solution should provide a clean and reusable way to include links to parent models in your Filament forms.

Dave Wize's avatar
Level 18

Do you mean breadcrumbs?

You can customize these...

But if I understand correctly, you should use the plugin Nested Resources to get your resources nested one in the other, and it will give you the desired breadcrumbs for free:)

1 like
clem's avatar

This is for tables, not forms, but it might help: https://www.answeroverflow.com/m/1085145914571772004

I created this macro to link resources to my parent user:

TextColumn::macro('linkToUser', function () {
    return $this->url(fn ($record): ?string => $record->user ? UserResource::getUrl('view', ['record' => $record->user]) : null);
});
Tables\Columns\TextColumn::make('user.name')
    ->linkToUser()

This macro is compatible with other models: https://v2.filamentphp.com/tricks/link-to-related-model-from-table

Please or to participate in this conversation.