A Laravel package that provides automatic localization support for PHP enums, making it easy to display translated enum values in your application.
You can install the package via Composer:
composer require domthomas-dev/laravel-localized-enum
The package will automatically register its service provider.
Optionally, you can publish the configuration file:
php artisan vendor:publish --tag=localized-enum-config
This will create a config/localized-enum.php
file where you can customize:
return [
// Default label type when none is specified
'default_label' => 'label',
// Translation file name (without .php extension)
'translation_file' => 'enums',
];
Add the LocalizedEnum
trait to your enum:
<?php
namespace App\Enums;
use DomThomas\LocalizedEnum\LocalizedEnum;
enum ContactType: string
{
use LocalizedEnum;
case EMAIL = 'email';
case PHONE = 'phone';
case SMS = 'sms';
}
Create translation files for your enums in your resources/lang
directory:
// resources/lang/en/enums.php
<?php
use App\Enums\ContactType;
return [
ContactType::class => [
'label' => [
ContactType::EMAIL->name => 'Email',
ContactType::PHONE->name => 'Phone',
ContactType::SMS->name => 'SMS',
],
'description' => [
ContactType::EMAIL->name => 'Send via email',
ContactType::PHONE->name => 'Call by phone',
ContactType::SMS->name => 'Send text message',
],
],
];
// resources/lang/fr/enums.php
<?php
use App\Enums\ContactType;
return [
ContactType::class => [
'label' => [
ContactType::EMAIL->name => 'E-mail',
ContactType::PHONE->name => 'Téléphone',
ContactType::SMS->name => 'SMS',
],
'description' => [
ContactType::EMAIL->name => 'Envoyer par e-mail',
ContactType::PHONE->name => 'Appeler par téléphone',
ContactType::SMS->name => 'Envoyer un SMS',
],
],
];
$contact = new Contact();
$contact->type = ContactType::EMAIL;
// Get default label
echo $contact->type->label(); // "Email"
// Get label in specific locale
echo $contact->type->label(locale: 'fr'); // "E-mail"
You can define multiple label types for the same enum as shown in the translation files above:
// Get description label
echo ContactType::EMAIL->label('description'); // "Send via email"
// Get default label (uses 'label' key)
echo ContactType::EMAIL->label(); // "Email"
Generate arrays suitable for HTML select inputs:
// Get all options for select
$options = ContactType::forSelect();
// Returns: ['email' => 'Email', 'phone' => 'Phone', 'sms' => 'SMS']
// With placeholder
$options = ContactType::forSelect(placeHolder: 'Choose contact type');
// Returns: ['' => 'Choose contact type', 'email' => 'Email', 'phone' => 'Phone', 'sms' => 'SMS']
// With specific label type
$options = ContactType::forSelect(label: 'description');
// Returns: ['email' => 'Send via email', 'phone' => 'Call by phone', 'sms' => 'Send text message']
// With specific locale
$options = ContactType::forSelect(locale: 'fr');
// Returns: ['email' => 'E-mail', 'phone' => 'Téléphone', 'sms' => 'SMS']
// Exclude specific cases
$options = ContactType::forSelect(excepted: [ContactType::SMS]);
// Returns only EMAIL and PHONE options
// Returns: ['email' => 'Email', 'phone' => 'Phone']
// Include only specific cases
$options = ContactType::forSelect(only: [ContactType::EMAIL, ContactType::PHONE]);
// Returns only EMAIL and PHONE options
// Returns: ['email' => 'Email', 'phone' => 'Phone']
// Get structured options array
$options = ContactType::options();
// Returns: [
// ['value' => 'email', 'label' => 'Email'],
// ['value' => 'phone', 'label' => 'Phone'],
// ['value' => 'sms', 'label' => 'SMS']
// ]
// With custom label and locale
$options = ContactType::options(label: 'description', locale: 'fr');
<!-- In a select input -->
<select name="contact_type">
@foreach(ContactType::forSelect(placeHolder: 'Select type') as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
<!-- Select with filtered options -->
<select name="preferred_contact">
@foreach(ContactType::forSelect(placeHolder: 'Choose method', excepted: [ContactType::SMS]) as $value => $label)
<option value="{{ $value }}">{{ $label }}</option>
@endforeach
</select>
<!-- Display enum label -->
<p>Contact type: {{ $contact->type->label() }}</p>
<p>Description: {{ $contact->type->label('description') }}</p>
The package automatically generates translation keys using this format:
{translation_file}.{EnumClass}.{label_type}.{case_name}
For example (with default config):
App\Enums\ContactType::EMAIL
→enums.App\Enums\ContactType.label.EMAIL
- With description:
enums.App\Enums\ContactType.description.EMAIL
You can customize the translation file name and default label type in the configuration.
// Get all enum values as array
$values = ContactType::values();
// Returns: ['email', 'phone', 'sms']
// Filter enum cases
$filtered = ContactType::filterCases(excepted: [ContactType::SMS]); // Exclude SMS
$onlyEmailPhone = ContactType::filterCases(only: [ContactType::EMAIL, ContactType::PHONE]); // Only EMAIL and PHONE
If a translation key is not found, the package will fall back to the enum case name:
// If translation doesn't exist, returns the case name
echo ContactType::EMAIL->label(); // "EMAIL" (if no translation found)
The translation structure uses the enum class as the top-level key in your translation files (default: resources/lang/{locale}/enums.php
):
use App\Enums\ContactType;
return [
ContactType::class => [
'label' => [
ContactType::EMAIL->name => 'Email',
ContactType::PHONE->name => 'Phone',
],
'description' => [
ContactType::EMAIL->name => 'Send via email',
ContactType::PHONE->name => 'Call by phone',
],
// You can add custom label types
'short' => [
ContactType::EMAIL->name => 'E',
ContactType::PHONE->name => 'P',
],
],
];
Note: If you change the translation_file
config to something other than 'enums', make sure to update your file names accordingly (e.g., translations.php
if you set it to 'translations').
## Testing
```bash
composer test
The MIT License (MIT). Please see License File for more information.