Quick Tip: Velocity Template Debugging
By Andrius Miasnikovas
In this post I’ll try to share my recent experience with Velocity template debugging. There are a few ways to debug the templates depending on where you think the problem lies. But at times you have modify templates written by others and that’s when you need to do some exploring like finding out what variables are actually passed to the template. This is not always easily found in code, sometimes it’s simpler to print this stuff out when you’re already in the template. Below is a macro that I used to print out request and session attributes and parameters.
#macro (installDebugWindow)
<script language="javascript">
function debugWindow() {
vc = window.open("", true, "width=800,height=600,resizable,scrollbars=yes");
vc.document.write("<html><head><title>Velocity Debug Console</title>");
vc.document.write('<style type="text/css">textarea{width:100%;} tr:nth-child(odd){background:#ddd;} tr:nth-child(even){background:#fafafa;} td:nth-child(odd){font-family:monospace;} tr:first-child{background:#ccc;} tr:first-child td{font-family:Arial;vertical-align:middle;} td h3{margin:10px;} table{margin-bottom:30px;border:2px solid #000;}</style>');
vc.document.write("</head><body>");
vc.document.write("<h2>Velocity Debug Console</h2>");
vc.document.write("<table width='100%'>");
vc.document.write("<tr bgcolor=#cccccc><td colspan='2'><h3>Request Attributes:</h3></td></tr>");
#foreach ($name in $request.getAttributeNames())
#printRow($name $request.getAttribute($name).toString().
replaceAll("\n", "\\n").replaceAll("\r", " "))
#end
vc.document.write("</table>");
vc.document.write("<table width='100%'>");
vc.document.write("<tr bgcolor=#cccccc><td colspan='2'>" +
"<h3>Request Parameters:</h3></td></tr>");
#foreach ($name in ${request.getParameterNames()})
#printRow($name $request.getParameter($name).toString().
replaceAll("\n", "\\n").replaceAll("\r", " "))
#end
vc.document.write("</table>");
vc.document.write("<table width='100%'>");
vc.document.write("<tr bgcolor=#cccccc><td colspan='2'>" +
"<h3>Session Attributes:</h3></td></tr>");
#foreach ($name in ${session.getAttributeNames()})
#printRow($name $session.getAttribute($name).toString().
replaceAll("\n", "\\n").replaceAll("\r", " "))
#end
vc.document.write("</table>");
vc.document.write("</body></html>");
vc.document.close();
}
function parseKeys(e) {
e = e || window.event;
if (e.ctrlKey && e.keyCode === 48) debugWindow();
}
if (window.addEventListener) {
window.addEventListener('keydown', parseKeys, false);
} else if (window.attachEvent) {
window.attachEvent('onkeydown', parseKeys);
} else {
window['onkeydown'] = parseKeys;
}
#end
It creates a new window and prints this data separate from your actual page layout, just make sure that your browser doesn’t kill this pop-up window. I placed the macro in my VM_global_library.vm file to be able to access it from any Velocity template. Then you can put the call to this macro #installDebugWindow() at the end of the page. This macro is based on the one I found on the Apache Wiki. I adjusted some things to better suit my taste. In the original version whenever you open a template that contains a call to #installDebugWindow a new window will instantly pop up. This is not always the desired behaviour. In my suggested version to get this window with all the template variable information you have to hit the key combination Ctrl+0. This doesn’t clutter your view with debug information when you don’t need and you have access to it whenever you do. Hope someone finds this useful.