# Multilanguage

### Introduction

Thanks to the [spatie/laravel-translatable](https://github.com/spatie/laravel-translatable) package you can translate your models into multiple languages. HotCoffee's own `Article` and `InfoPage` models take advantage of this. Additionally there is a helper method `language_fields()` that will generate the HTML input fields in your forms in separate tabs on the page for each language that you declare in `hotcoffee.php` config file.

### Usage

Define all the locales for the translatable models in the `languages` array in `config/hotcoffee.php`. Each language should be an associative array with this structure`'acronym' => 'full name'`. The first language is going to be the default one.

```php
'languages' => [
        'en' => 'English',
        'bg' => 'Български',
        'de' => 'Deutsche',
],
```

If you have defined more than one language in the array you will be able to see the flag icons above the **title** and **content** fields when creating or editing info pages and articles. Clicking an icon will switch to the tab that contains the fields for that particular locale.

<div align="left"><img src="https://582218703-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0JvlXkNR9xWhK_ij0j%2F-M23uHAyTFlBSt7I3fUk%2F-M23vAZEjsfaNfhLaG_n%2Fadmin_articles_1.gif?alt=media&#x26;token=684dd65b-d42c-4e76-a5a4-e5866ad3e6eb" alt=""></div>

These fields and flag icons are generated, because we called the `language_fields()` helper method in the template. Flag images are loaded from the `public/vendor/hotcoffee/img/flags` directory. If the acronym of a locale is 'de', then the loaded image will be `de.svg` from that same directory. Simply put any missing flag svg files that you need there.&#x20;

To make your own models translatable they should use the `Spatie\Translatable\HasTranslations` trait. You need to also define all translatable fields:

```php
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;
use Spatie\Translatable\HasTranslations;

class Product extends Model
{

	use HasTranslation;
	
	/**
   * Translatable attributes.
   */
	public $translatable = ['name', 'description'];
	
	/**
   * The attributes that are mass assignable.
   */
  protected $fillable = [
    'name', 'description', 'price'
  ];
}
```

Now in your template:

```markup
<form action="{{ route('products.store') }}" method="post">
  <h6 class="heading-small text-muted mb-4">New Product</h6>
  
  {{ csrf_field() }}
  
  <!-- TRANSLATABLE FIELDS -->
  {!! language_fields([
    'name' => ['type' => 'text', 'title' => 'Product Name'],
    'description' => ['type' => 'textarea', 'title' => 'Content', 'class' => 'tinymce'],
  ], $product ?? null) !!}
  <!-- END TRANSLATABLE FIELDS -->
  
  <!-- NON TRANSLATABLE FIELDS -->
  <input type="text" name="price" />
  <!-- END NON TRANSLATABLE FIELDS -->
  
  <input type="submit" />
</form>
```

The HTML output of `language_fields()` method in this case would look something like this (given, that we have set 3 locales - **en**, **bg** and **de**):

```markup
<!-- Flag Icons -->
<ul class="nav nav-pills nav-pills-circle" role="tablist" id="tabs_2">

    <li class="nav-item">
        <a class="nav-link rounded-circle  active " id="en" data-toggle="tab" href="#tab-en" role="tab" aria-controls="en" aria-selected="true">
            <img src="https://yourapp.com/vendor/hotcoffee/img/flags/en.svg" alt="English" class="flag-img">
        </a>
    </li>

    <li class="nav-item">
        <a class="nav-link rounded-circle " id="bg" data-toggle="tab" href="#tab-bg" role="tab" aria-controls="bg" aria-selected="true">
            <img src="https://yourapp.com/vendor/hotcoffee/img/flags/bg.svg" alt="Български" class="flag-img">
        </a>
    </li>
    
    <li class="nav-item">
        <a class="nav-link rounded-circle " id="de" data-toggle="tab" href="#tab-de" role="tab" aria-controls="bg" aria-selected="true">
            <img src="https://yourapp.com/vendor/hotcoffee/img/flags/de.svg" alt="Deutsche" class="flag-img">
        </a>
    </li>

</ul>

<!-- Tabs with language fields -->
<div class="tab-content" id="lang-tabs">

    <!-- English Fields -->
    <div class="tab-pane fade" id="tab-en" role="tabpanel" aria-labelledby="tab-en">
        <label class="form-control-label" for="input-name">Name</label>
        <input type="text" name="name[en]" class="form-control" />
        
        <label class="form-control-label" for="input-name">Content</label>
        <textarea name="description[en]" class="tinymce form-control"><textarea>
    </div>
    
    <!-- Bulgarian Fields -->
    <div class="tab-pane fade" id="tab-bg" role="tabpanel" aria-labelledby="tab-bg">
        <label class="form-control-label" for="input-name">Name</label>
        <input type="text" name="name[bg]" class="form-control" />
        
        <label class="form-control-label" for="input-name">Content</label>
        <textarea name="description[bg]" class="tinymce form-control"><textarea>
    </div>

    <!-- German Fields -->
    <div class="tab-pane fade" id="tab-de" role="tabpanel" aria-labelledby="tab-de">
        <label class="form-control-label" for="input-name">Name</label>
        <input type="text" name="name[de]" class="form-control" />
        
        <label class="form-control-label" for="input-name">Content</label>
        <textarea name="description[de]" class="tinymce form-control"><textarea>
    </div>
</div>
```

The function will also add "has-danger" class if a validation of a field has failed.

<div align="left"><img src="https://582218703-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0JvlXkNR9xWhK_ij0j%2F-M29rfWM4pgqKztFyXZA%2F-M29sio7f4vZTlxHQILC%2Fvalidate_fail.png?alt=media&#x26;token=b9c89d72-a48e-4d9f-9339-4b63cfca74d9" alt=""></div>

It will also populate the `value=""` attribute (or content of a `<textarea>` field) automatically when editing a model. Hence why you need to specify the variable name of the model as a second parameter:

```markup
{!! language_fields($fields = array(), $product ?? null !!}
```

{% hint style="info" %}
Say you have a method called `edit()` in your `ProductController.php`. In this method we get the product from the database, pass the `$product` variable to the template and return the product.blade.php view. However you may also have a `create()` method, that will return the same view. But this time we don't have to get a product from the database. We will create a new one. Hence the `$product` variable is not defined. To not get an error "_**unidentified variable name $product**_" when using calling `language_fields()` you can ad&#x64;**`$product ?? null`** as the second parameter.
{% endhint %}

When the form is submitted, the content of the request will be this:

<div align="left"><img src="https://582218703-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-M0JvlXkNR9xWhK_ij0j%2F-M2DOND_8FyIdlv9B5ZR%2F-M2DV-BwAIS0ZbK2wkN_%2Frequest_trans.png?alt=media&#x26;token=68fd5820-102d-4465-b314-e68f7a359d9a" alt=""></div>

Now in your `store()` method you can do this:

```php
Product::create($request->all());
```

Of course  when using Eloquent's `create()` or `update()` methods you will need to specify the `fillable` or `guarded` attribute on the model.

```php
public $translatable = ['name', 'description'];
protected $fillable = ['name', 'description', 'price'];
```

Whenever you need to display the content of the product for example you can just do this:

```php
$product->content; // Returns value of content field in the current app locale.
```

If you want to get the content field in a specific locale:

```php
$product->getTranslation('content', 'bg'); // Returns value of content field in Bulgarian.
```

{% hint style="success" %}
To learn more about translating models visit [https://github.com/spatie/laravel-translatable](https://github.com/spatie/laravel-translatable)
{% endhint %}
