Skip to content

Commit

Permalink
Issue #60 Cleanup creation logic and allow empty default language
Browse files Browse the repository at this point in the history
  • Loading branch information
mikehaertl committed Jan 9, 2017
1 parent e8d16bc commit f080c39
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 19 deletions.
12 changes: 12 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,18 @@ for the default language in the URL. For example if default language is `fr`:

In this case, `fr` will first be stored as last used language before the user is redirected.

If you explicitely need to create a URL to the default language without any language code,
you can also pass an empty string as language:

```php
<?= Url::to(['demo/action', 'language' => '']) ?>
```

This will give you:

/demo/action


### Language Detection

If a user visits your site for the first time and there's no language stored in session
Expand Down
38 changes: 19 additions & 19 deletions UrlManager.php
Original file line number Diff line number Diff line change
Expand Up @@ -194,31 +194,29 @@ public function createUrl($params)
if ($this->enableLocaleUrls && $this->languages) {
$params = (array) $params;

if (isset($params[$this->languageParam])) {
$language = $params[$this->languageParam];
$addLanguage = false;
$isLanguageGiven = isset($params[$this->languageParam]);
$language = $isLanguageGiven ? $params[$this->languageParam] : Yii::$app->language;
$isDefaultLanguage = $language===$this->getDefaultLanguage();

if ($isLanguageGiven) {
unset($params[$this->languageParam]);
$languageRequired = true;
} else {
$language = Yii::$app->language;
$languageRequired = false;
}

// Do not use prefix for default language to prevent unnecessary redirect if there's no persistence and no detection
$url = parent::createUrl($params);

if (
$languageRequired && $language===$this->getDefaultLanguage() &&
!$this->enableDefaultLanguageUrlCode && !$this->enableLanguagePersistence && !$this->enableLanguageDetection
) {
$languageRequired = false;
}
// Only add language if it's not empty and ...
$language!=='' && (

$url = parent::createUrl($params);
// ... it's not the default language or default language uses URL code ...
!$isDefaultLanguage || $this->enableDefaultLanguageUrlCode ||

// Unless a language was explicitely specified in the parameters we can return a URL without any prefix
// for the default language, if suffixes are disabled for the default language. In any other case we
// always add the suffix, e.g. to create "reset" URLs that explicitely contain the default language.
if (!$languageRequired && !$this->enableDefaultLanguageUrlCode && $language===$this->getDefaultLanguage()) {
return $url;
} else {
// ... or if a language is explicitely given, but only if either persistence or detection is enabled.
// This way a "reset URL" can be created for the default language.
$isLanguageGiven && ($this->enableLanguagePersistence || $this->enableLanguageDetection)
)
) {
$key = array_search($language, $this->languages);
if (is_string($key)) {
$language = $key;
Expand Down Expand Up @@ -250,6 +248,8 @@ public function createUrl($params)
}
$needleLength = strlen($needle);
return $needleLength ? substr_replace($url, "$needle/$language", 0, $needleLength) : "/$language$url";
} else {
return $url;
}
} else {
return parent::createUrl($params);
Expand Down
8 changes: 8 additions & 0 deletions tests/UrlCreationTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ public function testCreateHomeUrlWithLanguageFromUrl()
],
]);
$this->mockRequest('/de/site/page');
$this->assertEquals($this->prepareUrl('/'), Url::to(['/site/index', 'language' => '']));
$this->assertEquals($this->prepareUrl('/de'), Url::to(['/site/index']));
$this->assertEquals($this->prepareUrl('/de?x=y'), Url::to(['/site/index', 'x' => 'y']));
}
Expand All @@ -129,6 +130,7 @@ public function testCreateAbsoluteHomeUrlWithLanguageFromUrl()
],
]);
$this->mockRequest('/de/site/page');
$this->assertEquals('http://localhost'.$this->prepareUrl('/'), Url::to(['/site/index', 'language' => ''], 'http'));
$this->assertEquals('http://localhost'.$this->prepareUrl('/de'), Url::to(['/site/index'], 'http'));
$this->assertEquals('http://localhost'.$this->prepareUrl('/de?x=y'), Url::to(['/site/index', 'x' => 'y'], 'http'));
}
Expand All @@ -154,6 +156,10 @@ public function testCreateUrlWithSpecificLanguage()
],
]);
$this->mockRequest('/de/site/page');
$this->assertEquals($this->prepareUrl('/'), Url::to(['/', 'language' => '']));
$this->assertEquals($this->prepareUrl('/demo/action'), Url::to(['/demo/action', 'language' => '']));
$this->assertEquals($this->prepareUrl('/en'), Url::to(['/', 'language' => 'en']));
$this->assertEquals($this->prepareUrl('/en/demo/action'), Url::to(['/demo/action', 'language' => 'en']));
$this->assertEquals($this->prepareUrl('/en-us'), Url::to(['/', 'language' => 'en-US']));
$this->assertEquals($this->prepareUrl('/en-us/demo/action'), Url::to(['/demo/action', 'language' => 'en-US']));
$this->assertEquals($this->prepareUrl('/en-us/demo/action?x=y'), Url::to(['/demo/action', 'language' => 'en-US', 'x'=>'y']));
Expand Down Expand Up @@ -388,10 +394,12 @@ public function testCreateUrlWithoutDefaultLanguageIfPersistenceAndDetectionDisa
'enableLanguagePersistence' => false,
'enableLanguageDetection' => false,
'rules' => [
'' => 'site/index',
'/foo/<term:.+>/bar' => 'slug/action',
],
]);
$this->mockRequest('/de/site/page');
$this->assertEquals($this->prepareUrl('/'), Url::to(['/site/index', 'language' => 'en']));
$this->assertEquals($this->prepareUrl('/demo/action'), Url::to(['/demo/action', 'language' => 'en']));
$this->assertEquals($this->prepareUrl('/demo/action?x=y'), Url::to(['/demo/action', 'x' => 'y', 'language' => 'en']));
$this->assertEquals($this->prepareUrl('/foo/baz/bar'), Url::to(['/slug/action', 'term' => 'baz', 'language' => 'en']));
Expand Down

0 comments on commit f080c39

Please sign in to comment.