Usually when building a custom relationship fieldtype you want to work with data from somewhere else than Statamic.
In this example we extended the relationship fieldtype in order to provide a list of imported tags. Thanks to the Statamic docs, this is pretty easy.
class Tags extends Relationship
{
protected array | string $tags;
// Fetch tags from api.
// Using a facade makes it nice to read and easier to test.
public function __construct()
{
$this->tags = Api::tags();
}
// Define columns.
protected function getColumns()
{
return [
Column::make('title'),
];
}
// Take search requests into account.
// Just comparing strings. Nothing fancy.
public function getIndexItems($request)
{
return collect($this->tags)
->filter(function ($tag) use ($request) {
if (! $request->search) {
return true;
}
return Str::contains($tag['title'], $request->search);
});
}
}
In many cases this would already be it. But what if you have a huge amount of tags or items that need to be loaded into Statamics selector stack
?
I found that loading about 16000 tags at once into the selector stack would either cause unbearable loading times or even make the browser freeze.
This issue could be solved by enabling pagination. But unfortunately the relationship fieldtype does not automatically enable pagination when loading a specific number of items.
In order to do so and show pagination at the bottom of the selector stack you need to return an instance of the \Statamic\Extensions\Pagination\LengthAwarePaginator
instead of a collection in the getIndexItems
method.
This could be done like this:
public function getIndexItems($request)
{
$tags = collect($this->tags)->filter(function ($tag) use ($request) {
if (! $request->search) {
return true;
}
return Str::contains($tag['title'], $request->search);
});
return $this->paginate($tags);
}
protected function paginate($tags): LengthAwarePaginator
{
$currentPage = Paginator::resolveCurrentPage();
$perPage = 50;
$total = $tags->count();
$result = $total ? $tags->forPage($currentPage, $perPage) : collect();
return new LengthAwarePaginator($result, $total, $perPage, $currentPage, []);
}
Curios about the LengthAwarePaginator? Read more in the Laravel Docs
Et voilà - a custom relationship fieldtype with added pagination:
Top comments (0)