spatie/laravel-options
Generate unified select option lists in Laravel from enums, Eloquent models, states, and arrays. Spatie laravel-options converts sources to a consistent label/value structure, supports customization via config, and makes building dropdowns and filters faster and cleaner.
Installation:
composer require spatie/laravel-options
No publisher or configuration required—just use the Options facade or helper.
First Use Case: Convert an enum to select options in a Blade view:
use Spatie\Options\Options;
// In a controller or service
$hobbitOptions = Options::forEnum(\App\Enums\Hobbit::class)->toArray();
// Pass to Blade
return view('hobbits.form', ['options' => $hobbitOptions]);
Blade Integration:
<select name="hobbit">
@foreach ($options as $option)
<option value="{{ $option['value'] }}">{{ $option['label'] }}</option>
@endforeach
</select>
Spatie\Options\Options (or helper options()).forEnum() → Convert enums to options.forModel() → Fetch model attributes as options.forState() → Use Laravel’s state() helper for dynamic options.forArray() → Manually define options.// Convert enum to options with custom label/value
Options::forEnum(Hobbit::class)
->label(fn ($value) => ucfirst($value->value)) // Custom label logic
->value(fn ($value) => strtoupper($value->value)) // Custom value logic
->toArray();
Fetch active users for a dropdown:
Options::forModel(User::class)
->where('active', true)
->orderBy('name')
->label('name')
->value('id')
->toArray();
Use Laravel’s state() helper for runtime options:
Options::forState('user.roles')
->label('name')
->value('id')
->toArray();
Options::forArray([
['id' => 1, 'name' => 'Admin', 'permissions' => ['create', 'delete']],
['id' => 2, 'name' => 'Editor', 'permissions' => ['edit']],
])
->label('name')
->value('id')
->withMeta('permissions') // Include extra data
->toArray();
Use with Laravel Collective or Livewire:
// Livewire component
public function mount() {
$this->hobbitOptions = Options::forEnum(Hobbit::class)->toArray();
}
public function render() {
return view('livewire.hobbit-selector', ['options' => $this->hobbitOptions]);
}
Cache options to avoid repeated queries:
// In a service or controller
$cachedOptions = Cache::remember('hobbit_options', now()->addHours(1), function () {
return Options::forEnum(Hobbit::class)->toArray();
});
Enum Case Sensitivity:
Options::forEnum(Hobbit::class)->label(fn ($value) => strtolower($value->name));
Model Query Performance:
select() to avoid loading unnecessary columns:
Options::forModel(User::class)
->select('id', 'name')
->where(...);
State Helper Dependencies:
forState() relies on Laravel’s state() helper. Ensure the state is set before calling:
state(['user.roles' => Role::all()]);
Array Key Conflicts:
forArray(), ensure value keys are unique. Duplicate values may cause issues in select fields.Inspect Raw Data:
Use ->getOptions() to debug the intermediate option objects before conversion:
$options = Options::forEnum(Hobbit::class)->getOptions();
dd($options); // Inspect before toArray()
Custom Option Classes:
Extend Spatie\Options\Option to add custom logic:
class CustomOption extends \Spatie\Options\Option {
public function getExtraData() {
return ['custom_field' => $this->value->customField];
}
}
Options::forModel(User::class)
->useOptionClass(CustomOption::class)
->toArray();
Custom Sources:
Add support for new data sources by extending the Options class or creating a new method:
// Example: Add `forApiResponse()` method
Options::macro('forApiResponse', function ($response) {
return new OptionsCollection(array_map(fn ($item) => [
'label' => $item['name'],
'value' => $item['id'],
], $response->data));
});
Global Defaults: Set defaults in a service provider:
Options::macro('forModel', function ($model) {
return $this->forModel($model)
->select('id', 'name')
->where('active', true);
});
Localization: Override labels dynamically with translations:
Options::forEnum(Hobbit::class)
->label(fn ($value) => __("hobbits.{$value->value}"));
toArray() trigger execution. Chain methods before calling toArray() for efficiency.How can I help you explore Laravel packages today?