Skip to content

Commit e8dc87b

Browse files
committed
feature #1511 Refactor how we define the available locales (javiereguiluz)
This PR was squashed before being merged into the main branch. Discussion ---------- Refactor how we define the available locales I never liked the `app_locales` parameter: https://github.com/symfony/demo/blob/main/config/services.yaml#L9 But we need it for the route locale requirements. I was digging into how to improve this ... and realized that if we use the standard [enabled_locales](https://symfony.com/doc/current/reference/configuration/framework.html#enabled-locales) config option from Symfony, the `{_locale}` parameter included in the URLs is automatically restricted to those values. So, we can simplify code by moving to `enabled_locales` without losing any functionality. Commits ------- 2955454 Refactor how we define the available locales
2 parents 719a423 + 2955454 commit e8dc87b

File tree

6 files changed

+21
-36
lines changed

6 files changed

+21
-36
lines changed

config/packages/framework.yaml

+4
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,10 @@ framework:
66
http_method_override: false
77
handle_all_throwables: true
88

9+
# this defines the codes of the locales (languages) available in the application
10+
# https://symfony.com/doc/current/reference/configuration/framework.html#enabled-locales
11+
enabled_locales: ['ar', 'bg', 'bn', 'bs', 'ca', 'cs', 'de', 'en', 'es', 'eu', 'fr', 'hr', 'id', 'it', 'ja', 'lt', 'ne', 'nl', 'pl', 'pt_BR', 'ro', 'ru', 'sl', 'sq', 'sr_Cyrl', 'sr_Latn', 'tr', 'uk', 'vi', 'zh_CN']
12+
913
# Enables session support. Note that the session will ONLY be started if you read or write from it.
1014
# Remove or comment this section to explicitly disable session support.
1115
session:

config/packages/security.yaml

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ security:
6565
access_control:
6666
# this is a catch-all for the admin area
6767
# additional security lives in the controllers
68-
- { path: '^/(%app_locales%)/admin', roles: ROLE_ADMIN }
68+
- { path: '^/{_locale}/admin', roles: ROLE_ADMIN }
6969

7070
# The ROLE_ADMIN role inherits from the ROLE_USER role
7171
role_hierarchy:

config/routes.yaml

-4
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
homepage:
66
path: /{_locale}
77
controller: Symfony\Bundle\FrameworkBundle\Controller\TemplateController::templateAction
8-
requirements:
9-
_locale: '%app_locales%'
108
defaults:
119
template: default/homepage.html.twig
1210
_locale: '%locale%'
@@ -17,7 +15,5 @@ controllers:
1715
namespace: App\Controller
1816
type: attribute
1917
prefix: /{_locale}
20-
requirements:
21-
_locale: '%app_locales%'
2218
defaults:
2319
_locale: '%locale%'

config/services.yaml

+1-3
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,6 @@
55
# https://symfony.com/doc/current/best_practices.html#use-parameters-for-application-configuration
66
parameters:
77
locale: 'en'
8-
# This parameter defines the codes of the locales (languages) enabled in the application
9-
app_locales: ar|en|fr|de|es|cs|nl|ru|uk|ro|pt_BR|pl|it|ja|id|ca|sl|sq|hr|zh_CN|bg|tr|lt|bs|sr_Cyrl|sr_Latn|eu|ne|bn|vi
108
app.notifications.email_sender: [email protected]
119

1210
services:
@@ -18,7 +16,7 @@ services:
1816
# this allows to define the scalar arguments once and apply them to any services
1917
# defined/created in this file; if some argument is used rarely, instead of defining
2018
# it here you can use the #[Autowire] attribute to inject it manually in the service constructor
21-
string $locales: '%app_locales%'
19+
array $enabledLocales: '%kernel.enabled_locales%'
2220
string $defaultLocale: '%locale%'
2321

2422
# makes classes in src/ available to be used as services

src/EventSubscriber/RedirectToPreferredLocaleSubscriber.php

+10-17
Original file line numberDiff line numberDiff line change
@@ -28,34 +28,27 @@
2828
*/
2929
final class RedirectToPreferredLocaleSubscriber implements EventSubscriberInterface
3030
{
31-
/**
32-
* @var string[]
33-
*/
34-
private array $locales;
35-
private readonly string $defaultLocale;
36-
3731
public function __construct(
3832
private readonly UrlGeneratorInterface $urlGenerator,
39-
string $locales,
40-
?string $defaultLocale = null
33+
/** @var string[] */
34+
private array $enabledLocales,
35+
private ?string $defaultLocale = null
4136
) {
42-
$this->locales = explode('|', trim($locales));
43-
44-
if (empty($this->locales)) {
37+
if (empty($this->enabledLocales)) {
4538
throw new \UnexpectedValueException('The list of supported locales must not be empty.');
4639
}
4740

48-
$this->defaultLocale = $defaultLocale ?: $this->locales[0];
41+
$this->defaultLocale = $defaultLocale ?: $this->enabledLocales[0];
4942

50-
if (!\in_array($this->defaultLocale, $this->locales, true)) {
51-
throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".', $this->defaultLocale, $locales));
43+
if (!\in_array($this->defaultLocale, $this->enabledLocales, true)) {
44+
throw new \UnexpectedValueException(sprintf('The default locale ("%s") must be one of "%s".', $this->defaultLocale, implode(', ', $this->enabledLocales)));
5245
}
5346

5447
// Add the default locale at the first position of the array,
5548
// because Symfony\HttpFoundation\Request::getPreferredLanguage
5649
// returns the first element when no an appropriate language is found
57-
array_unshift($this->locales, $this->defaultLocale);
58-
$this->locales = array_unique($this->locales);
50+
array_unshift($this->enabledLocales, $this->defaultLocale);
51+
$this->enabledLocales = array_unique($this->enabledLocales);
5952
}
6053

6154
public static function getSubscribedEvents(): array
@@ -81,7 +74,7 @@ public function onKernelRequest(RequestEvent $event): void
8174
return;
8275
}
8376

84-
$preferredLanguage = $request->getPreferredLanguage($this->locales);
77+
$preferredLanguage = $request->getPreferredLanguage($this->enabledLocales);
8578

8679
if ($preferredLanguage !== $this->defaultLocale) {
8780
$response = new RedirectResponse($this->urlGenerator->generate('homepage', ['_locale' => $preferredLanguage]));

src/Twig/AppExtension.php

+5-11
Original file line numberDiff line numberDiff line change
@@ -24,23 +24,17 @@
2424
*/
2525
final class AppExtension extends AbstractExtension
2626
{
27-
/**
28-
* @var string[]
29-
*/
30-
private readonly array $localeCodes;
31-
3227
/**
3328
* @var list<array{code: string, name: string}>|null
3429
*/
3530
private ?array $locales = null;
3631

3732
// The $locales argument is injected thanks to the service container.
3833
// See https://symfony.com/doc/current/service_container.html#binding-arguments-by-name-or-type
39-
public function __construct(string $locales)
40-
{
41-
$localeCodes = explode('|', $locales);
42-
sort($localeCodes);
43-
$this->localeCodes = $localeCodes;
34+
public function __construct(
35+
/** @var string[] */
36+
private array $enabledLocales,
37+
) {
4438
}
4539

4640
public function getFunctions(): array
@@ -65,7 +59,7 @@ public function getLocales(): array
6559

6660
$this->locales = [];
6761

68-
foreach ($this->localeCodes as $localeCode) {
62+
foreach ($this->enabledLocales as $localeCode) {
6963
$this->locales[] = ['code' => $localeCode, 'name' => Locales::getName($localeCode, $localeCode)];
7064
}
7165

0 commit comments

Comments
 (0)