I am using freemarker template engine with Spring and I want to add or replace lang=xxx
parameter in the href attribute of link element when rendering page.
The closest solution I have found is following:
<a href="${springMacroRequestContext.getRequestUri()}?lang=en'/>English</a>
But this is not sufficient when I have URL with parameters and fragments because I will miss them. For example http://localhost/sports/search?query=Volleyball&lang=cs#some-fragment
results in http://localhost/sports/search?lang=en
How to compose the URL with added or changed lang
parameter in freemarker and do not miss any part of requested URL?
I preferred to do it in Java, this simple implementation does not take into account hashes (#
) or the presence of the given parameter in the url..
public static String addParamToUrl(String url, String paramName, String paramValue){
StringBuffer buffer = new StringBuffer(url);
//adding separator
if(url.indexOf('?') == -1){
buffer.append('?');
}else if(!url.endsWith("?") && !url.endsWith("&")){
buffer.append('&');
}
buffer.append(paramName);
if(paramValue != null){
buffer.append("=");
buffer.append(URLEncoder.encode(paramValue, "UTF-8"));
}
return buffer.toString();
}
Put this method in a Class (i.e:Utils.java
) that can be staticly accessed by Freemarker engine and than:
<#assign url = Utils.addParamToUrl(springMacroRequestContext.getRequestUri(), "lang", "en") />
<a href="${url}">English</a>
To expose your Utils
class you have to customize FreemarkerManager
public class MyFreemarkerManager extends FreemarkerManager {
public MyFreemarkerManager(){
super();
}
@Override
protected void populateContext(ScopesHashModel model, ValueStack stack, Object action, HttpServletRequest request, HttpServletResponse response) {
super.populateContext(model, stack, action, request, response);
try {
BeansWrapper beansWrapper = new BeansWrapperBuilder(Configuration.VERSION_2_3_24).build();
TemplateHashModel staticModels = beansWrapper.getStaticModels();
TemplateHashModel utils = (TemplateHashModel)staticModels.get("com.package.Utils");
model.put("Utils", utils);
} catch (TemplateModelException e) {
//...
}
}
}
Finally you have to tell Spring you are using MyFreemarkerManager
as manager for Freemarker.