codeconsole commented on code in PR #15940:
URL: https://github.com/apache/grails-core/pull/15940#discussion_r3555947274
##########
grails-i18n/src/main/groovy/org/grails/plugins/i18n/I18nGrailsPlugin.groovy:
##########
@@ -42,6 +43,30 @@ class I18nGrailsPlugin extends Plugin {
String version = GrailsUtil.getGrailsVersion()
String watchedResources = "file:./${baseDir}/**/*.properties".toString()
+ /**
+ * Publishes the discovered available locales to the servlet context so
that views and the
+ * {@code g:localeSelect available="true"} tag can render a language
selector. Reading a servlet
+ * context attribute keeps consumers decoupled from this module.
+ */
+ static final String AVAILABLE_LOCALES_ATTRIBUTE = 'availableLocales'
+
+ @Override
+ void doWithApplicationContext() {
+ publishAvailableLocales()
+ }
+
+ private void publishAvailableLocales() {
+ def ctx = applicationContext
+ if (!(ctx instanceof WebApplicationContext)) {
+ return
+ }
+ def servletContext = ((WebApplicationContext) ctx).servletContext
+ if (servletContext != null &&
ctx.containsBean('availableLocaleResolver')) {
Review Comment:
Good catch — fixed in 9d79f67d09. Both `publishAvailableLocales()` and
`onChange` now resolve the resolver by type via
`ctx.getBeanProvider(AvailableLocaleResolver).getIfAvailable()`, so a
user-defined resolver registered under any bean name is published. Added a
regression test registering the resolver under a custom name.
##########
grails-i18n/src/main/groovy/org/grails/plugins/i18n/I18nAutoConfiguration.java:
##########
@@ -130,4 +130,30 @@ public MessageSource messageSource(GrailsApplication
grailsApplication, GrailsPl
}
return messageSource;
}
+
+ /**
+ * Discovers the locales the application is translated into (from {@code
<basename>_<locale>.properties}
+ * bundles on the classpath) so that a language selector can list only
real translations rather
+ * than every JVM locale. Published to the servlet context by {@link
I18nGrailsPlugin} and
+ * consumed by the {@code g:localeSelect available="true"} tag.
+ *
+ * <p>By default every {@code *.properties} bundle on the classpath is
considered, so locales
+ * contributed by plugins — whose bundles are namespaced (e.g.
+ * {@code spring-security-core_*.properties}) — are included
alongside the application's own.
+ * Set {@code grails.i18n.availableLocales.includePlugins=false} to
restrict discovery to the
+ * application's own {@code messages_*.properties} bundles.
+ *
+ * @param defaultLocale the base {@code messages.properties} locale,
always included
+ * ({@code grails.i18n.default.locale}, defaults to {@code en})
+ * @param includePlugins whether to also scan plugin-contributed message
bundles
+ * ({@code grails.i18n.availableLocales.includePlugins}, defaults to
{@code true})
+ */
+ @Bean
+ @ConditionalOnMissingBean(AvailableLocaleResolver.class)
+ public AvailableLocaleResolver availableLocaleResolver(GrailsApplication
grailsApplication,
+ @Value("${grails.i18n.default.locale:en}") String defaultLocale,
Review Comment:
Agreed — fixed in 9d79f67d09. The `availableLocaleResolver` bean now reuses
the existing `defaultLocale` field via `fixedLocale()`
(`StringUtils.parseLocale`, falling back to `Locale.getDefault()`), so the one
config key parses and defaults identically everywhere in the class. The
`I18nAutoConfigurationSpec` default-wiring test now asserts the JVM-default
fallback.
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]