Freemarker - how to get the locale instance? - freemarker

From documentation special variable .locale retrieves a String representation of the locale.
But how can the Locale be retrieved within freemarker markup?
If there is no built-in function I must pass the Locale to the template and pass it to each macro.
Simplified example:
Java Bean.class
public Locale getLocale();
public String getFoo(Locale locale);
Freemarker
Cannot use string locale!
<#setting locale="${bean.getLocale()}">
${bean.getFoo(.locale)}

I have added .locale_object in 2.3.21 for that (should be released on 2014-10-12).
Otherwise, if you have put the Locale into the data-model, why would you need to pass that to each macro? Macros see the data-model variables.

Freemarker's .locale is a String not a Locale.
Not sure what your getFoo() is doing, but maybe you need a Locale in there? This answer will help you build it if you need that: How to get Locale from its String representation in Java?

Related

why Laravel considers category as locale

I am stuck with laravel localization. I want locale optional in my routes. But issue is that if locale is not send i want en by default. If locale is not explicitly in URL. Laravel considers first parameter like category as Locale.
Route::group(["prefix"=>'{locale?}','middleware'=>'getLang'],function() {
Route::get('/',[WebsiteController::class,'get_homepage'])->name('homepage');
Route::get('{category}',[WebsiteController::class,'category_all_news'])->name('category_all_news')->middleware('getLang');
Route::get('{category}/{slug}',[WebsiteController::class,'get_a_news_blog'])->name('get_a_news_blog')->middleware('getLang');
});
How can i solve this ?
Thanks in advance.
You are able to define optional parameters in your routes, by simply adding a question mark before them
In your case, you can add a parameter for the locale before your category
Route::get('/',[WebsiteController::class,'get_homepage'])->name('homepage');
Route::get('{locale?}/{category}',[WebsiteController::class,'category_all_news'])->name('category_all_news')->middleware('getLang');
Route::get('{locale?}/{category}/{slug}',[WebsiteController::class,'get_a_news_blog'])->name('get_a_news_blog')->middleware('getLang');
When passing the locale variable in your method you can just define a default value for the parameter
https://laravel.com/docs/9.x/routing#parameters-optional-parameters

Thymeleaf - i18n get back the template by locale and custom parameter

Circumstances
I'm using Spring Boot with Thymeleaf for populating my HTML template files and get back the result as a String. For that I used SpringTemplateEngine.
The code looks like this
Context context = new Context();
context.setVariables(myProperties);
return templateEngine.process(htmlTemplateName, context);
The problem
For i18n I have a different approach. My thymeleaf HTML template namings are the following (similar to Freemaker templating):
templatename_default_FOO.html
templatename_en_EN_FOO.html
templatename_de_DE_FOO.html
templatename_default_ANOTHER.html
templatename_en_EN_ANOTHER.html
templatename_de_DE_ANOTHER.html
The convention is:
templatename - is the name of the template
default/en_EN/de_DE - is the locale which I get from an API - The locale may not exists in the templates, in this case I want to use the default template with the matching user parameter
FOO/ANOTHER - different parameter values which the users sets - they exists in atleast one template's name (the default should contain it)
Previously I used ResourceBundles to get the templates by locale if existed, otherwise the default value was automatically chosen. However with Thymeleaf implementation I don't know how to implement the same mechanics, because currently I get the template by providing the full name. If I add a locale which not exists I don't get back the default template.
Question
I know that i18n in Thymeleaf is done through language.properties, but in my case I would need a function where I provide the template name, the locale and the user parameter and I get back the specified HTML file if exists and if not the default HTML file with the matching user parameter.
Something similar:
public String getTemplate(Map<String, Object> myProperties, String templateName, Locale locale, String userParameter) {
Context context = new Context();
context.setVariables(myProperties);
return templateEngine.process(templateName, locale, userParameter context);
}
Is that possible somehow or I should use language.properties? Or I should write custom logic to check if the template not exists go with the default one?
Thanks in advance

Get Thymeleaf #{} expression to append locale

My context path is / and I'm adding locales directly as part of the path: /de/index.html.
Now I'm facing the problem that th:href="#{/login.html}" will resolve to /login.html instead of /de/login.html.
I already tried making a Filter and an Interceptor like they did it here: https://stackoverflow.com/a/23847484/1163457
But it still won't append de/ after the context path.
Writing my own dialect and attribute processors would be a solution, but isn't there any better one?
Why not expose a model attribute for the locale (e.g. curLocale) and redefine all your urls like
th:href="#{/${curLocale}/login.html}"
Thymeleaf allows other expressions inside url expressions themselves.
Locale information is easily accessible either as a method parameter or by calling RequestContext.getLocale()
I found a clean and good solution myself after hours of step debugging:
https://stackoverflow.com/a/60103777/1163457

Use Different Locale for #NumberFormat in Spring

I am working on a Spring 3 project and I need to format a Long field for Turkish currency. The default Locale of the application is en_US. I used the #NumberFormat annotation as below:
#NumberFormat(style=NumberFormat.Style.CURRENCY)
public Long getBudgetLimit() {
return budgetLimit;
}
The annotation works and formats the form field in English locale. However I need to use Turkish locale for this field. Is there a way to set the locale of a single field or a page different than the application's locale?
Edit: I just found the answer myself. Use a custom editor in the controller as below:
NumberFormat numberFormat = NumberFormat.getNumberInstance(new Locale("tr","TR"));
dataBinder.registerCustomEditor(Long.class, new CustomNumberEditor(Long.class,numberFormat, true));
and do not use the #NumberFormat annotation. For same reason it gave an error for me.
There are many ways but you could for example register a custom implementation of AnnotationFormatterFactory<NumberFormat> as a bean which would allow you to handle the formatting manually. This is documentented in the Spring documentation section 6.6. The example in the documentation even handles the use case of adjusting #NumberFormat's behavior.

JSP Global Variable using Spring

I have a date format at I wish to set globally for my jsp fmt tag to use.
May I know what is right approach to perform this?
I will wish to configure this value in future
pattern = "dd-MM-yyyy kkm"
I have read the following:
How do I create a global JSP variable that I can access across multiple pages or inside frames/iframes?
I think using applicationContext is right approach. You can set your date format at your "welcomepage.jsp",
String pattern = "dd-MM-yyyy kkm";
application.setAttribute("ApplicationPattern",pattern);
get and use the same format wherever required.
String pattern2 =(String)getServletContext().getAttribute("ApplicationPattern");
If you want to set the default data-format pattern for entire app, you could use ServletContext.setAttribute(), but you need a place to do this work, set it in a jsp page or use a initialize filter for your app.
Or you create a Utlitiy class with a static method(field) definition to get the default pattern, then from your fmt
tag use a method call to reference the default pattern

Resources