Wasim's Site

Velocity to FreeMarker Converter

Convert Liferay Velocity (.vm) templates to FreeMarker (.ftl) and back — directives, variables, and comments. Built for theme and ADT migration.

Direction
Velocity (.vm)FreeMarker (.ftl)

Conversion runs automatically as you type. This is a best-effort starting point — review the output, especially macro invocations (#name(...)<@name ... />) and comparison operators, which are not always auto-converted.

Velocity to FreeMarker — Why and When

Liferay moved away from Velocity starting in 7.0: themes, Application Display Templates (ADTs), web content templates, and email templates all use FreeMarker (.ftl) now. Migrating an older Liferay 6.x theme or a pile of legacy .vm templates means rewriting every directive and variable reference by hand — exactly the kind of mechanical work this converter does in one pass.

Velocity ↔ FreeMarker Syntax Reference

The core pattern mappings the converter applies. Keep this handy as a cheat sheet even when you are editing templates by hand.

PatternVelocityFreeMarker
Variable
$user.name
${user.name}
Quiet / silent referenceSuppresses output when the value is missing.
$!user.name
${user.name!}
Assign a variable
#set($x = 10)
<#assign x = 10>
If
#if($active)
<#if active>
Else if / else
#elseif($pending)
#else
<#elseif pending>
<#else>
Close ifVelocity reuses #end for every block; the converter tracks which block to close.
#end
</#if>
Foreach loop
#foreach($item in $list)
<#list list as item>
Close foreach
#end
</#list>
Loop indexFreeMarker exposes ?index (0-based) and ?counter (1-based).
$foreach.count / $velocityCount
${item?counter}
Define a macro
#macro(greet $name)
Hi $name
#end
<#macro greet name>
Hi ${name}
</#macro>
Call a macroMacro INVOCATION differs and is not auto-converted — update calls by hand.
#greet($user)
<@greet user />
Include a template
#parse("init.vm")
<#include "init.ftl">
Line comment
## a comment
<#-- a comment -->
Block comment
#* a comment *#
<#-- a comment -->

How to Use This Converter

  1. Paste your Velocity. Drop your .vm template into the input panel, or click Load sample.
  2. Read the FreeMarker output. It regenerates live as you type — no button to press.
  3. Check the flagged items. The tool highlights any Liferay-injected variables it detects so you can confirm they exist in your FreeMarker context.
  4. Fix macro calls by hand. Convert #myMacro(args) to <@myMacro args /> — invocations are intentionally left untouched.
  5. Copy or download the result as a .ftl file.

Frequently Asked Questions

Why convert Velocity to FreeMarker?
Liferay deprecated Velocity in 7.0 and removed it in later releases. Themes, Application Display Templates (ADTs), and web content templates must use FreeMarker (.ftl). This tool gives you a fast, mechanical first pass at migrating existing .vm templates to FreeMarker syntax.
What does the converter handle automatically?
Directives (#set→<#assign>, #if/#elseif/#else→<#if>/<#elseif>/<#else>, #foreach→<#list>, #macro→<#macro>), the shared #end (resolved to the correct </#if>, </#list>, or </#macro> via a block stack), variable references ($x→${x}, $!x→${x!}), and comments (## and #* *# → <#-- -->).
What do I still need to fix by hand?
Macro invocations differ between the engines (Velocity #myMacro(args) vs FreeMarker <@myMacro args />) and are not auto-converted. Comparison operators inside conditions, built-in utilities, and any Java-side logic should also be reviewed. Treat the output as a strong starting point, not a guaranteed 1:1 port.
Does it work in both directions?
Yes. Use the swap button to convert FreeMarker back to Velocity. The Velocity-to-FreeMarker direction is the most reliable since that is the common Liferay migration path; the reverse is best-effort.
Is my template uploaded anywhere?
No. All conversion runs entirely in your browser. Your template code never leaves your device.

Official Resources