我无法使用任何已接受的解决方案来设置变量#evaluate,我已经看到过使用Vellu in Confluence将JSON字符串转换为地图。
我有一个来自另一个系统的JSON字符串,用于生成动态数据。在开发过程中,我能够直接使用地图:
#set($textMapRaw = [{"ace":"clubs"}])
$textMapRaw.get(0).ace
最后一行呈现为“俱乐部”。
我曾期望使用#evaluate将实时数据转换为对象数组。但是,当我对它做任何事情时,似乎#evaluate没有将声明的变量放回范围。这是以字符串形式出现的相同地图:
#set($textMapHtml = '[{"ace":"clubs"}]')
#set($evalHtml = '#set($myMapHtml = '+ $textMapHtml +')')
evalHtml = $evalHtml<br/>
#evaluate($evalHtml)
$myMapHtml.get(0).ace
最后一行呈现为“$ myMapHtml.get(0).ace”。
我知道$ myMapHtml正在被评估,因为当我没有将Html
附加到它的末尾时,我得到了一个评估堆栈跟踪,以避免Confluence的自动转义恶作剧。
我已经尝试使用$ {hash} set转义集合中的哈希值。我试过单引号和双引号。我已经尝试过只需通过evaluate设置一个字符串:
#evaluate('#set($dippity = "doo")')
$dippity
#set($hash = '#')
#evaluate("${hash}set($blue = 'moon')")
$blue
无论我对任何已批准的#evaluate代码做什么,它都不会被评估为Confluence中的范围。我总是得到一个与未定义变量相同的结果。
注意:在我们的环境中,我无法在Java中进行解决方法并将其推送到模板中。我需要找到一个纯粹的模板内解决方案。
Velocity 1.6.4不允许在#evaluate
指令中修改评估上下文。因此,在使用此版本时,无法使用动态名称创建上下文条目。
但是,您可以将它们存储在地图中:
#set( $stringMap = '[{"ace":"clubs"}]' )
#set( $myMap = {} )
#set( $eval = '#set($list = ' + $stringMap + ') #set ($myMap.ace =
$list.get(0).ace)' )
#evaluate( $eval )
$myMap.ace ## prints 'clubs'
由于看起来你无法将变量恢复到当前范围,我想出了一个解决方法。只需使用evaluate将数组/映射传递给宏。
如果您尝试操作已评估代码或其调用的宏之外的变量,您仍会遇到范围问题,但如果您小心,可以围绕它进行编码。
在我的例子中,我在宏中移动了另一段代码,以利用本地范围来确定处理了多少项。
#macro(processMap $theMap)
#set($count = 0)
#foreach($item in $theMap)
#set($count = $velocityCount)
<p>This thing is $item.tweedle</p>
#end
<p><b>I did that $count times</b></p>
#end
#set($workaroundHtml = '[{"tweedle":"dee"},{"tweedle":"dum"}]')
#set($eval = '#processMap(' + $workaroundHtml + ')')
#evaluate($eval)