Skip to content

Commit f080c39

Browse files
committed
Issue #60 Cleanup creation logic and allow empty default language
1 parent e8d16bc commit f080c39

File tree

3 files changed

+39
-19
lines changed

3 files changed

+39
-19
lines changed

README.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -240,6 +240,18 @@ for the default language in the URL. For example if default language is `fr`:
240240

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

243+
If you explicitely need to create a URL to the default language without any language code,
244+
you can also pass an empty string as language:
245+
246+
```php
247+
<?= Url::to(['demo/action', 'language' => '']) ?>
248+
```
249+
250+
This will give you:
251+
252+
/demo/action
253+
254+
243255
### Language Detection
244256

245257
If a user visits your site for the first time and there's no language stored in session

UrlManager.php

Lines changed: 19 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -194,31 +194,29 @@ public function createUrl($params)
194194
if ($this->enableLocaleUrls && $this->languages) {
195195
$params = (array) $params;
196196

197-
if (isset($params[$this->languageParam])) {
198-
$language = $params[$this->languageParam];
197+
$addLanguage = false;
198+
$isLanguageGiven = isset($params[$this->languageParam]);
199+
$language = $isLanguageGiven ? $params[$this->languageParam] : Yii::$app->language;
200+
$isDefaultLanguage = $language===$this->getDefaultLanguage();
201+
202+
if ($isLanguageGiven) {
199203
unset($params[$this->languageParam]);
200-
$languageRequired = true;
201-
} else {
202-
$language = Yii::$app->language;
203-
$languageRequired = false;
204204
}
205205

206-
// Do not use prefix for default language to prevent unnecessary redirect if there's no persistence and no detection
206+
$url = parent::createUrl($params);
207+
207208
if (
208-
$languageRequired && $language===$this->getDefaultLanguage() &&
209-
!$this->enableDefaultLanguageUrlCode && !$this->enableLanguagePersistence && !$this->enableLanguageDetection
210-
) {
211-
$languageRequired = false;
212-
}
209+
// Only add language if it's not empty and ...
210+
$language!=='' && (
213211

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

216-
// Unless a language was explicitely specified in the parameters we can return a URL without any prefix
217-
// for the default language, if suffixes are disabled for the default language. In any other case we
218-
// always add the suffix, e.g. to create "reset" URLs that explicitely contain the default language.
219-
if (!$languageRequired && !$this->enableDefaultLanguageUrlCode && $language===$this->getDefaultLanguage()) {
220-
return $url;
221-
} else {
215+
// ... or if a language is explicitely given, but only if either persistence or detection is enabled.
216+
// This way a "reset URL" can be created for the default language.
217+
$isLanguageGiven && ($this->enableLanguagePersistence || $this->enableLanguageDetection)
218+
)
219+
) {
222220
$key = array_search($language, $this->languages);
223221
if (is_string($key)) {
224222
$language = $key;
@@ -250,6 +248,8 @@ public function createUrl($params)
250248
}
251249
$needleLength = strlen($needle);
252250
return $needleLength ? substr_replace($url, "$needle/$language", 0, $needleLength) : "/$language$url";
251+
} else {
252+
return $url;
253253
}
254254
} else {
255255
return parent::createUrl($params);

tests/UrlCreationTest.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ public function testCreateHomeUrlWithLanguageFromUrl()
115115
],
116116
]);
117117
$this->mockRequest('/de/site/page');
118+
$this->assertEquals($this->prepareUrl('/'), Url::to(['/site/index', 'language' => '']));
118119
$this->assertEquals($this->prepareUrl('/de'), Url::to(['/site/index']));
119120
$this->assertEquals($this->prepareUrl('/de?x=y'), Url::to(['/site/index', 'x' => 'y']));
120121
}
@@ -129,6 +130,7 @@ public function testCreateAbsoluteHomeUrlWithLanguageFromUrl()
129130
],
130131
]);
131132
$this->mockRequest('/de/site/page');
133+
$this->assertEquals('http://localhost'.$this->prepareUrl('/'), Url::to(['/site/index', 'language' => ''], 'http'));
132134
$this->assertEquals('http://localhost'.$this->prepareUrl('/de'), Url::to(['/site/index'], 'http'));
133135
$this->assertEquals('http://localhost'.$this->prepareUrl('/de?x=y'), Url::to(['/site/index', 'x' => 'y'], 'http'));
134136
}
@@ -154,6 +156,10 @@ public function testCreateUrlWithSpecificLanguage()
154156
],
155157
]);
156158
$this->mockRequest('/de/site/page');
159+
$this->assertEquals($this->prepareUrl('/'), Url::to(['/', 'language' => '']));
160+
$this->assertEquals($this->prepareUrl('/demo/action'), Url::to(['/demo/action', 'language' => '']));
161+
$this->assertEquals($this->prepareUrl('/en'), Url::to(['/', 'language' => 'en']));
162+
$this->assertEquals($this->prepareUrl('/en/demo/action'), Url::to(['/demo/action', 'language' => 'en']));
157163
$this->assertEquals($this->prepareUrl('/en-us'), Url::to(['/', 'language' => 'en-US']));
158164
$this->assertEquals($this->prepareUrl('/en-us/demo/action'), Url::to(['/demo/action', 'language' => 'en-US']));
159165
$this->assertEquals($this->prepareUrl('/en-us/demo/action?x=y'), Url::to(['/demo/action', 'language' => 'en-US', 'x'=>'y']));
@@ -388,10 +394,12 @@ public function testCreateUrlWithoutDefaultLanguageIfPersistenceAndDetectionDisa
388394
'enableLanguagePersistence' => false,
389395
'enableLanguageDetection' => false,
390396
'rules' => [
397+
'' => 'site/index',
391398
'/foo/<term:.+>/bar' => 'slug/action',
392399
],
393400
]);
394401
$this->mockRequest('/de/site/page');
402+
$this->assertEquals($this->prepareUrl('/'), Url::to(['/site/index', 'language' => 'en']));
395403
$this->assertEquals($this->prepareUrl('/demo/action'), Url::to(['/demo/action', 'language' => 'en']));
396404
$this->assertEquals($this->prepareUrl('/demo/action?x=y'), Url::to(['/demo/action', 'x' => 'y', 'language' => 'en']));
397405
$this->assertEquals($this->prepareUrl('/foo/baz/bar'), Url::to(['/slug/action', 'term' => 'baz', 'language' => 'en']));

0 commit comments

Comments
 (0)