Nahbyr's avatar
Level 2

How best to translate things like statuses or types

I have a DB that contains vehicles. Every vehicle has a status (available, sold, reserved, ...), type (new, secondhand, demo, ...), bodytype (coupe, van, truck, ...) etc. The frontend needs to be multilingual (nl/fr/en/de). According to the documentation for translations in Laravel, you're supposed to throw everything into the main translation json. That seems messy to me. I would much prefer it the way they handle shortcodes for translations. This however results in showing an ugly shortcode if a translation wasn't found instead of the string you're trying to translate. Is there a way to handle this in a prettier way while grouping them into their individual files?

0 likes
3 replies
LaryAI's avatar
Level 58

To handle translations for things like statuses, types, and body types in a Laravel application while keeping your translation files organized, you can use Laravel's array-based translation files instead of JSON files. This allows you to group translations into separate files, making them easier to manage.

Here's a step-by-step solution:

  1. Create Translation Files: Create separate translation files for each category (e.g., statuses, types, bodytypes) in the resources/lang/{locale} directory. For example:

    • resources/lang/en/statuses.php
    • resources/lang/en/types.php
    • resources/lang/en/bodytypes.php
  2. Define Translations: In each file, return an array of key-value pairs where the key is a unique identifier for the translation, and the value is the translated string. For example, in statuses.php:

    <?php
    
    return [
        'available' => 'Available',
        'sold' => 'Sold',
        'reserved' => 'Reserved',
    ];
    

    Similarly, create types.php and bodytypes.php with appropriate translations.

  3. Access Translations: Use the trans or __ helper functions to access these translations in your application. Specify the file and key using dot notation. For example:

    echo __('statuses.available'); // Outputs: Available
    echo __('types.new'); // Outputs: New
    
  4. Fallback Mechanism: If a translation is not found, Laravel will return the key itself. To handle this more gracefully, you can provide a default value using the trans function:

    echo trans('statuses.unknown', [], 'en', 'Unknown Status');
    

    This will output "Unknown Status" if the translation for statuses.unknown is not found.

  5. Add Other Locales: Repeat the process for other locales (e.g., nl, fr, de) by creating corresponding translation files in resources/lang/{locale} and providing translations for each key.

By organizing your translations into separate files, you maintain a clean structure and make it easier to manage translations for different parts of your application.

Snapey's avatar

Use the translation functions. Thats what they are there for ! You can split them into different files if that seems more organised to you, it does not matter. You dont need to create shortcodes either, the english of the statement will be used if a translation is not available.

But not Larry's way, we dont use echo statements in Laravel

martinbean's avatar

According to the documentation for translations in Laravel, you're supposed to throw everything into the main translation json.

@nahbyr You’re not. Where in the docs does it say that?

The Laravel localization docs give examples of defining files to translate strings. The example it uses is a file called messages.php, but you can define as many files as you want, and call them whatever you want.

So if you wanted to translate statuses, then you would define a statuses.php file for each locale you wanted to support, with translations for each status:

// lang/es/statuses.php
return [
    'available' => 'Disponable',
    'sold' => 'Vendido',
    'reserved' => 'Reservado',
];

You can then get the translated string uses Laravel’s translation functions:

echo __('messages.available'); // Return 'Disponable' if locale is 'es'

Personally, I’d define an enumeration for things like statuses, and add a method to that enumeration to get the name for displaying:

enum Status: string
{
    case Available = 'available';
    case Sold = 'sold';
    case Reserved = 'reserved';

    public function label(): string
    {
        return __(sprintf('statuses.%s', $this->value));
    }
}
// If $status is instance of Status enum...
echo $status->label(); // i.e. 'Disponable' if available and locale is 'en'

Or if you’re displaying these statuses in Blade templates, you could use a custom echo handler to get the label for the enumeration value:

Blade::stringable(function (Status $status) {
    return __(sprintf('statuses.%s', $status->value));
});

Then you don’t need to do anything; you could echo the status and Laravel will automatically translate it for you:

<!-- If $status is instance of Status enum... -->
<p>Status: {{ $status }}</p>

Please or to participate in this conversation.