Skip to content
This repository has been archived by the owner on Jun 18, 2019. It is now read-only.

Commit

Permalink
Added country based fallback.
Browse files Browse the repository at this point in the history
  • Loading branch information
dimsav committed Oct 22, 2015
1 parent ef14288 commit 5bd54f2
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 6 deletions.
36 changes: 35 additions & 1 deletion readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ $germany->{'name:de'} // 'Deutschland'
If you want to fallback to a default translation when a translation has not been found, enable this in the configuration
using the `use_fallback` key. And to select the default locale, use the `fallback_locale` key.

Example:
Configuration example:

```php
return [
Expand All @@ -327,6 +327,40 @@ class Country {
}
```

#### Country based fallback

Since version v5.3 it is possible to use country based locales. For example, you can have the following locales:

- English: `en`
- Spanish: `es`
- Mexican Spanish: `es-MX`
- Colombian Spanish: `es-CO`

To configuration for these locales looks like this:

```php
'locales' => [
'en',
'es' => [
'MX',
'CO',
],
];
```

We can also configure the "glue" between the language and country. If for instance we prefer the format `es_MX` instead of `es-MX`,
the configuration should look like this:

```php
'locale_separator' => '_',
```

What applies for the fallback of the locales using the `en-MX` format?

Let's say our fallback locale is `en`. Now, when we try to fetch from the database the translation for the
locale `es-MX` but it doesn't exist, we won't get as fallback the translation for `en`. Translatable will use as a
fallback `es` (the first part of `es-MX`) and only if nothing is found, the translation for `en` is returned.

## FAQ

#### I need some example code!
Expand Down
40 changes: 35 additions & 5 deletions src/Translatable/Translatable.php
Original file line number Diff line number Diff line change
Expand Up @@ -55,16 +55,16 @@ public function translateOrNew($locale)
public function getTranslation($locale = null, $withFallback = null)
{
$locale = $locale ?: $this->locale();

$withFallback = $withFallback === null ? $this->useFallback() : $withFallback;
$fallbackLocale = $this->getFallbackLocale($locale);

if ($this->getTranslationByLocaleKey($locale)) {
$translation = $this->getTranslationByLocaleKey($locale);
} elseif ($withFallback
&& $this->getFallbackLocale()
&& $this->getTranslationByLocaleKey($this->getFallbackLocale())
&& $fallbackLocale
&& $this->getTranslationByLocaleKey($fallbackLocale)
) {
$translation = $this->getTranslationByLocaleKey($this->getFallbackLocale());
$translation = $this->getTranslationByLocaleKey($fallbackLocale);
} else {
$translation = null;
}
Expand Down Expand Up @@ -266,13 +266,43 @@ private function getTranslationByLocaleKey($key)
}

/**
* @param null $locale
*
* @return string
*/
private function getFallbackLocale()
private function getFallbackLocale($locale = null)
{
if ($locale && $this->isLocaleCountryBased($locale)) {
if ($fallback = $this->getLanguageFromCountryBasedLocale($locale)) {
return $fallback;
}
}

return App::make('config')->get('translatable.fallback_locale');
}

/**
* @param $locale
*
* @return bool
*/
private function isLocaleCountryBased($locale)
{
return strpos($locale, $this->getLocaleSeparator()) !== false;
}

/**
* @param $locale
*
* @return string
*/
private function getLanguageFromCountryBasedLocale($locale)
{
$parts = explode($this->getLocaleSeparator(), $locale);

return array_get($parts, 0);
}

/**
* @return bool|null
*/
Expand Down
16 changes: 16 additions & 0 deletions tests/TranslatableTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -395,4 +395,20 @@ public function test_locale_separator_can_be_configured()
$this->assertSame('Chips', $frenchFries->getTranslation('en_GB')->name);
}

public function test_fallback_for_country_based_locales()
{
$this->app->config->set('translatable.use_fallback', true);
$this->app->config->set('translatable.fallback_locale', 'fr');
$this->app->config->set('translatable.locales', ['en' => ['US', 'GB'], 'fr']);
$this->app->config->set('translatable.locale_separator', '-');
$data = [
'id' => 1,
'fr' => ['name' => 'frites'],
'en-GB' => ['name' => 'chips'],
'en' => ['name' => 'french fries'],
];
Food::create($data);
$fries = Food::find(1);
$this->assertSame('french fries', $fries->getTranslation('en-US')->name);
}
}

0 comments on commit 5bd54f2

Please sign in to comment.