Skip to content

Instantly share code, notes, and snippets.

@narenranjit
Created January 24, 2012 20:23
Show Gist options
  • Star 15 You must be signed in to star a gist
  • Fork 6 You must be signed in to fork a gist
  • Save narenranjit/1672345 to your computer and use it in GitHub Desktop.
Save narenranjit/1672345 to your computer and use it in GitHub Desktop.
Convert objects in Velocity templates to JSON
#macro(VelListToJSON $list )
#set($myList = $list )## dereference
{
#foreach($key in $myList.keySet())
"$key":
#set($x = $myList.get($key))
#VelToJSON($x)
#if($foreachCount != $myList.keySet().size()) , #end
#end
}
#end
#macro(VelArrayToJSON $arr)
#set($myArr = $arr)
[
#foreach($x in $myArr)
#VelToJSON($x)
#if($foreachCount != $myArr.size()) , #end
#end
]
#end
##TODO: Make it not treat numbers as strings
#macro(VelToJSON $item)
#if($item.keySet())
#VelListToJSON($item)
#elseif($item.size())
#VelArrayToJSON($item)
#elseif($item == true || $item ==false)
$item
#else
"$item"
#end
#end
@mexitek
Copy link

mexitek commented May 16, 2017

Modified a bit. Now checks for Numbers:

#set ( $obj = '' ) ## dummy object
#set ( $int_class = $obj.class.forName('java.lang.Number') )
#set ( $bool_class = $obj.class.forName('java.lang.Boolean') )
#set ( $string_class = $obj.class.forName('java.lang.String') )
#set ( $map_class = $obj.class.forName('java.util.Map') )
#set ( $list_class = $obj.class.forName('java.util.List') )
#set ( $foreachCount = 10 )

#macro(VelListToJSON $list )
    #set($myList = $list )## dereference
    {
    #foreach($key in $myList.keySet())
        "$key":
        #set($x = $myList.get($key))
        #VelToJSON($x)
        #if($foreachCount != $myList.keySet().size()) , #end
    #end
    }
#end

#macro(VelArrayToJSON $arr)
    #set($myArr = $arr)
    [
    #foreach($x in $myArr)
        #VelToJSON($x)
        #if($foreachCount != $myArr.size()) , #end
    #end
    ]
#end

#macro(VelToJSON $item)
    #if($map_class.isAssignableFrom($item.class))
        #VelListToJSON($item)
    #elseif($list_class.isAssignableFrom($item.class))
        #VelArrayToJSON($item)
    #elseif($bool_class.isAssignableFrom($item.class)|| $int_class.isAssignableFrom($item.class))
        $item
    #else ## $string_class.isAssignableFrom($item.class)
        "$item"
    #end
#end

@TheClassic
Copy link

@mexitek @narenranjit
I'd like to use this, can you license it with the MIT or Apache license, please?

@wmertens
Copy link

@TheClassic gists don't support notifications :(

you won't get this mention but maybe you'll revisit this topic someday :)

@li-a
Copy link

li-a commented Apr 12, 2019

Please note that JSON (like JavaScript) has encoding and escaping rules that will not be followed by this code. So for example, if your strings are allowed to contain characters like " and \, then you have an injection vulnerability. You could make use of the EscapeTool builtin, but you would need to put that on the template context, e.g., $esc.

@sacredwx
Copy link

Sorry for the question, I'm new to VTL, but it would be nice to have a usage example of the code above..

@narenranjit
Copy link
Author

@sacredwx I haven't done velocity for a while but you should be able to do something like

#set($data = ["a", "b"])
#VelListToJSON($data)

@sacredwx
Copy link

thank you for suggestion!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment