views:

667

answers:

2

In Freemarker templates we can use the escape directive to automatically apply an escaping to all interpolations inside the included block:

<#escape x as x?html>
  <#-- name is escaped as html -->
  Hallo, ${name}
</#escape>

Is there a way to programmatically achieve a similar effect, defining a default escape applied to all interpolations in the template, including those outside escape directives?

Thanks.

+1  A: 

There is a solution, although it's not entirely trivial. You can create a special TemplateLoader that wraps other template loaders, and injects <#escape x as x?html> in the prolog of the template source text, and adds as the epilogue of it.

Obvious drawbacks: - column numbers in first line will be thrown off - if your template starts with <#ftl> declaration, you need to insert <#escape> after it.

Attila Szegedi
+1  A: 

To elaborate on Attila's answer: you can use a class like this one and then wrap your template loader like this:

final TemplateLoader templateLoader = new ClassTemplateLoader(this.getClass(), templatePath) {
  /**
   * Replaces the normal template reader with something that changes the default
   * escaping to HTML as to avoid XSS attacks.
   */
  @Override
  public Reader getReader(Object templateSource, String encoding) throws IOException {
     return new WrappingReader(super.getReader(templateSource, encoding), "<#escape x as x?html>", "</#escape>");
  }
};

If you don't include linebreaks in the added parts you don't get the line numbering problem. You can't use the <#ftl>/[#ftl] with this approach, though.

Peter Becker