Assign <#nested> to variable in FreeMarker

FreeMarker is awesome template engine. I'm still wonder how much powerful it is and how flexible it can be when you need. Last week, when I was writing a simple macro to render tweets using user defined template, my though was that it may be good to define this template as macro nested content. For instance:

<@tweets 'rkhmelyuk', 10>
[picture] [username]: <br/>
<a href="[url]">[date]</a>

Pretty simple, but the only way for me was to load tweets using Twitter API through JSONP protocol. So my macro was need to generate a javascript code, that should correctly define callback and fetch tweets. Callback function simply applies received JSON data to the user defined template.

And here is the problem. How to get macro's nested content into javascript variable? Well, who ever used FreeMarker knows that nested content can be rendered with command <#nested/>. This could be a solution, but isn't. Why? Because I need to do extra preparing of template to put it as a javascript string. I need to remove newlines and replace quotes. So the best decision is to put nested content as Freemarker variable and do preparation over it first and than insert into javascript. And here is the power of Freemarker. This was possible and easy to do with <#assign/> or <#local/> command:

<#local layout><#nested/></#local>
<#-- Now layout variable contains a template defined as nested -->
<script type="text/javascript">
function callback_${id}(data) {
var layout = "${layout?SomePreparationsGoHere}";
renderTweets(layout, data);

In this code, the nested content is assigned to variable layout. Then we generates a javascript code and insert layout variable as string, but first do some preparations.

I also like flexibility of Freemarker. I hope that could find a time and describe some other tips about it soon.

Facebook was failing to parse OG meta tags

Last week was having awful time fighting with strange work of Facebook. We had a page with OG meta tags and a Facebook Like button on the page. And Facebook was discarding to parse the page and extract data from OG meta tags. Using URL linter didn't help to find the problem but show the same information - page isn't parsed, OG meta tags are not used.

So I tried to check next things to find the issue:

  • whether property attribute in used <meta/> tags

  • whether correct fb:app_id meta tag value is set

  • whether nginx returns correct page when facebook requests the page

  • whether correct namespaces added to the <html/> tag

  • whether we are using UTF-8 encoding

  • and something other, don't remember all my tests

And was checking web page through URL Linter each time. With no success. Facebook discarded parsing the page and fetching page title with other data from meta tags.

So I reviewed response/request data through firebug to find suspicious things. I found one scanty detail: Content-Type header had value "text/html;charset=utf-8;charset=UTF-8".
I must say, this one web page is generated by application using user-defined template. Grails controller is responsible for handling request and renders output like:

render text: context.out, contentType: "text/html;charset=$AppConstant.RENDER_CHARSET"

where AppConstant.RENDER_CHARSET equals to "UTF-8". But the rendered page had Content-Type equal to "text/html;charset=utf-8;charset=UTF-8". And my thought was to fix header value to have something like "text/thml;charset=UTF-8" and hoped this may help. So I changed code to be like:

render text: context.out, contentType: "text/html"

Content-Type header value now is "text/html;charset=utf-8". So I tried URL Lint again. I wasn't expecting much from Facebook this time either, but miracle happened! Everything works fine now. I know, that is my fault, but, nevertheless, thank you Facebook for "nice" time spending :).