Question

I have a requirement that I want to implement with freemaker, I already know how the freemarker works, like this

template.process(dataMap,out);

dataMap contains the data we would use to fill the template, of course all the data implemented the TamplateModel interface, there is no difference if we use user-defined directives, because user-defined directive implement TemplateDirectiveModel, this interface implemented TemplateModel, what I need to do is is access data stored in session, and then use theses data in my directives.like this <@authCheck> </@authCheck>, my auth data is stored in session, so I need to get these data from session in my directive.

ps: I use springMVC with freemarker

Was it helpful?

Solution

The runtime environment of templates is represented by the Environment object, which you also get as the parameter of TemplateDirectiveModel-s, or can get from TLS with the static method Environment.getCurrentEnvironment(). You can attach additional objects, like the session, to the Environment with setCustomAttribute(String name, Object value) and so your directives can get it with env.getCustomAttribute(name).

Each Template.process call makes its own Environment object internally. To access it before the main template is called, you have to do this instead of simply calling Tempalte.process:

Environment env = myTemplate.createProcessingEnvironment(root, out);
env.setCustoomAttribute("session", sesssion);
// You can addjust other environment settings here too.
env.process();  // template is called here to render the output

Another possibility is putting the session into the data-model. TemplateDirective-s can access the data-model via env.getDataModel().

OTHER TIPS

Note: my answer doesn't answer the question directly.

As you mentioned you use Freemarker with Spring-MVC, I guess you use Spring-Security also, if not it is recommended to do so.

Here is my way of using Spring-Security taglib in my Freemarker templates.

<#macro auth expr>
 <#assign security=JspTaglibs["http://www.springframework.org/security/tags"] />
 <@security.authorize access=expr>
  <#nested>
 </@security.authorize>
</#macro>

and above macro could be used like:

<#import "/mywebsitename/foomacro.ftl" as foo>
<@foo.auth "isAnonymous()">
 <a href="/signup">Signup</a>
</@foo.auth>

<@foo.auth "hasRole('ROLE_USER')">
 <a href="/profile">Profile</a>
</@foo.auth>

I also will be happy to know about weakness of my method, for example could we gain better performance with using some other method?

For example, maybe this imaginary code perform better?

<@foo.authCheck AUTH_OBJ_IN_SESSION "ROLE_USER">
 <a href = '/profile'>Profile</a>
</@foo.authCheck>

<#macro authCheck authObj role>
 <#if authObj.hasRole(role)>
  <#nested>
 </#if>
</#macro>

My own guess is, they are not much different, since they both use authentication object from user's session anyway. so why not using tested(ready to use) taglib from Spring-Security?

p.s. I usually access SESSION variables in my templates just like model or request variables, e.g. ${VAR_IN_SESSION}. maybe that is because I set <property name="exposeSpringMacroHelpers" value="true"/> in my spring configs. I also have <property name="exposeSessionAttributes" value="false"/> which it seems has no effect in not providing session variables!

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top