outerweb / filament-link-picker
This package adds a field to pick a link from your defined routes or external links.
Requires
- php: ^8.0
- filament/filament: ^3.2
- laravel/framework: ^10.0|^11.0
- spatie/laravel-package-tools: ^1.16
README
This package adds a field to pick a link from your defined routes or external links. It also adds a blade component to render the links.
Features
The link picker field will show the following options:
- A list of all your application routes that are marked for the link picker to discover.
- An external link option to add a link to an external website. (Can be disabled)
- An email link option to add a mailto link. (Can be disabled)
- A telephone link option to add a tel link. (Can be disabled)
The link picker will automatically show and bind the parameters of the selected route. This includes:
- A select field powered by route model binding to automatically show the available models.
- A text input field for all other parameters.
- An url input field for the external link option.
- An email input field for the email link option.
- A tel input field for the telephone link option.
The link picker can also show route options:
is_download
to specify if the link is a download link.opens_in_new_tab
to specify if the link should open in a new tab.
The link can be rendered using the <x-filament-link-picker-link />
blade component.
Installation
You can install the package via composer:
composer require outerweb/filament-link-picker
Add the plugin to your desired Filament panel:
use OuterWeb\FilamentLinkPicker\Filament\FilamentLinkPicker; class FilamentPanelProvider extends PanelProvider { public function panel(Panel $panel): Panel { return $panel // ... ->plugins([ FilamentLinkPickerPlugin::make(), ]); } }
Configuration
Disabling the external link option
You can disable the external link option by adding the disableExternalLinks
method to the plugin.
FilamentLinkPickerPlugin::make() ->disableExternalLinks();
Disabling the email link option
You can disable the email link option by adding the disableMailto
method to the plugin.
FilamentLinkPickerPlugin::make() ->disableMailto();
Disabling the telephone link option
You can disable the telephone link option by adding the disableTel
method to the plugin.
FilamentLinkPickerPlugin::make() ->disableTel();
Disabling the 'download' option
You can disable the 'download' option by adding the disableDownload
method to the plugin.
FilamentLinkPickerPlugin::make() ->disableDownload();
Disabling the 'opens in new tab' option
You can disable the 'opens in new tab' option by adding the disableOpenInNewTab
method to the plugin.
FilamentLinkPickerPlugin::make() ->disableOpenInNewTab();
Multi language support
You can enable multi language support by adding the translateLabels
method to the plugin.
FilamentLinkPickerPlugin::make() ->translateLabels();
The following items can be translated:
- label: The label of the route defined in the
filamentLinkPicker()
method. - group: The group of the route defined in the
filamentLinkPicker()
method. - parameter labels: The labels of the parameters defined in the
filamentLinkPicker()
method.
To do so, just set the values to the translation key.
Route::get('/your-route/{parameter}', YourController::class) ->name('your-route') ->filamentLinkPicker( label: 'your-route.label', group: 'your-route.group', parameterLabels: [ 'parameter' => 'your-route.parameter', ] );
Usage
Setting up routes
You can mark a route for the link picker to discover by adding the filamentLinkPicker()
method to the route.
use Illuminate\Support\Facades\Route; Route::get('/your-route', YourController::class) ->name('your-route') ->filamentLinkPicker();
Customizing the route's label
The label of the route will be used in the dropdown of the link picker. You can customize the label by passing it as an argument to the filamentLinkPicker()
method.
Route::get('/your-route', YourController::class) ->name('your-route') ->filamentLinkPicker( label: 'Your custom label' );
By default, the label will be the route's name. If the route name contains dots, they will be replaced by '>'.
Customizing the route's group
The group will be used to group the routes in the dropdown of the link picker. You can customize the group by passing it as an argument to the filamentLinkPicker()
method.
Route::get('/your-route', YourController::class) ->name('your-route') ->filamentLinkPicker( group: 'Your custom group' );
Marking the route as 'localized'
Marking a route as 'localized' will make the link picker combine all localized versions of that route. This is useful when you have a multi-language where you have the same route for different languages so that the link picker does not show the same route multiple times. See the Localization section for more information.
Route::get('/your-route', YourController::class) ->name('your-route') ->filamentLinkPicker( isLocalized: true );
Defining specific parameter labels
You can define specific parameter labels for the route by passing an array to the filamentLinkPicker()
method.
These labels will be used in the link picker as labels for the parameter input fields.
Route::get('/your-route/{parameter}', YourController::class) ->name('your-route') ->filamentLinkPicker( parameterLabels: [ 'your-parameter' => 'Your parameter label' ] );
Defining specific parameter options
You can define specific parameter options for the route by passing an array to the filamentLinkPicker()
method.
These options will be used in the link picker as options for the parameter select field.
Route::get('/your-route/{parameter}', YourController::class) ->name('your-route') ->filamentLinkPicker( parameterOptions: [ 'your-parameter' => [ 'option1' => 'Option 1', 'option2' => 'Option 2', ] ] );
Explicitly defining the column name to store the value in the database
By default, the package will use the $model->getKey()
method to store the selected value of a parameter in the database. If you want to store the value in a different column, you can pass the column name as an argument to the filamentLinkPicker()
method.
Route::get('/event/{event:slug}', 'show')->name('show')->filamentLinkPicker( label: 'Single Event', group: 'Details Page', parameterModelKeys: [ 'event' => 'slug', ] );
Setting up route model binding
Route model binding is supported by default. The link picker will automatically show the available models in the parameter select field. It will save the primary key of the model to the database.
By default, we go through the following attributes to automatically find the model's label:
- label
- name
- title
If none of these attributes are found, the application will throw an exception.
Explicitly defining the model's label
You can explicitly define the model's label by adding a getLinkPickerLabel
method to the model.
class YourModel extends Model { public function getLinkPickerLabel(): string { return $this->your_attribute; } }
Or you can define the label as a property on the model.
class YourModel extends Model { public string $linkPickerLabel = 'your_attribute'; }
Filtering the available models
You can filter the available models by adding a scopeLinkPickerOptions
method to the model.
This scope will then be applied to the model's query when fetching the available options for the select field.
class YourModel extends Model { public function scopeLinkPickerOptions(Builder $query): void { // Your query here } }
Localization
The link picker can handle localized routes well. To do so, follow these steps:
- Mark the route as 'localized' by adding the
localized
argument to thefilamentLinkPicker()
method on your route.
Route::get('/your-route', YourController::class) ->name('your-route') ->filamentLinkPicker( isLocalized: true );
- Configure how the link picker should combine the localized routes by adding the
combineLocalizedRoutesUsing
method to the plugin.
use Outerweb\FilamentLinkPicker\Entities\LinkPickerRoute; FilamentLinkPickerPlugin::make() ->combineLocalizedRoutesUsing(function (LinkPickerRoute $route): LinkPickerRoute { // Imagine your routes are named like `en.your-route` and `nl.your-route` // We want to combine these routes so that the link picker only shows one option for `your-route` return $route->name(Str::after($route->name(), '.')); });
By default, the package will combine the localized routes by removing the part of the name before the first dot. If you want to use this behavior, you do not need to specify the combineLocalizedRoutesUsing
method.
- Configure how the link picker should build the localized routes by adding the
buildLocalizedRouteUsing
method to the plugin.
use Outerweb\FilamentLinkPicker\Entities\LinkPickerRoute; FilamentLinkPickerPlugin::make() ->buildLocalizedRouteUsing(function (string $name, array $parameters = [], bool $absolute = true, ?string $locale = null): ?string { // If you use our `outerweb/localization` package, // You can use the `localizedRoute` helper. return localizedRoute($name, $parameters, $absolute, $locale); });
As a fallback, when you do not specify a callback function, the link picker will use the outerweb/localization
package to build the localized routes if it is installed. This package provides a localizedRoute
helper that you can use in your application. Read more about this package here.
Using the actual value
To use the actual value of the link, you can cast the attribute in your model or use the facade.
Casting
You can cast your model's attribute to the Outerweb\FilamentLinkPicker\Entities\Link
class to take advantage of the entity's properties and methods.
use Outerweb\FilamentLinkPicker\Casts\LinkCast; class YourModel extends Model { protected $casts = [ 'link' => LinkCast::class, ]; }
Using the facade
You can use the Outerweb\FilamentLinkPicker\Facades\LinkPicker
facade to cast the value to a Link
entity.
use Outerweb\FilamentLinkPicker\Facades\LinkPicker; $link = LinkPicker::dataToLinkEntity(array $data);
Rendering the link
You can use the <x-filament-link-picker-link />
blade component to render the link.
<x-filament-link-picker-link :link="$link"> Your label here </x-filament-link-picker-link>
The link picker options like is_download
and opens_in_new_tab
will only take effect when you do not specify them on the component itself. If you do specify them, the component will use the specified values.
<x-filament-link-picker-link :link="$link" download target="_self" />
Here, we specified the download
and target
attributes. The component will use these values instead of the ones from the link picker.
Changelog
Please see CHANGELOG for more information on what has changed recently.
Credits
License
The MIT License (MIT). Please see License File for more information.