Velocity 1.7嵌套块宏

前端开发 2026-07-08

有没有用#@macro_name语法来调用宏的示例?据Velocity引擎1.7的用户指南所述,似乎只有与 $bodyContent搭配时才起作用,但对这种方法的目的尚不清楚。我尝试过类似的做法作为实验,但还不知道它的局限性是什么。

#macro( div )
    <div>$!bodyContent</div>
#end

#@div()
    #@div()
        First Level-Inner Div
        #@div()
            Second Level-Inner Div 1
        #end
        #@div()
            Second Level-Inner Div 2
        #end
    #end
#end

嗯,我尝试在一个宏内部嵌套调用,但似乎不被允许。

#macro( divTag $content )
    <div>$content</div>
#end

#divTag( #divTag("Testing Inline Div Syntax") )

我最初想到这个点的问题,是在随机的位置出现的未闭合的HTML标签或其他标签,因此如果有一种机制能强制为每个开启标签都闭合标签,应该就能促使编写Velocity模板的人(很可能是我)在很长的宏末尾也不会忘记写诸如 #if(fullWidth)</div></div>#end 之类的内容来闭合标签。

-- 使用 #@d 语法被称为块宏。

再举一个例子,使用哈希映射传入键值对,如class、id等。

#macro( div $attributes )
    <div
        ## Loop through whatever key/value combinations were passed in
        #foreach( $key in $attributes.keySet() )
            $key="$_EscapeTool.xml($attributes.get($key))"
        #end
    >
        $!bodyContent
    </div>
#end

#@div({ 
    "id": "main_area", 
    "class": "tw-container tw-mx-auto tw-pt-12",
    "data-role": "page-wrapper"
})
    <h1>Attribute Injection Test</h1>
#end

#* Expected Output:
<div id="main_area" class="tw-container tw-mx-auto tw-pt-12" data-role="page-wrapper">
    <h1>Attribute Injection Test</h1>
</div>
*#

目前正在测试在该块内使用if和 foreach;如果该块允许任何形式的流程控制,那么它就有可能有效地替代我模板的大部分内容。

参考

velocimacro.body.reference = false

定义可以用于获取主体内容的引用名(一个提供给块宏调用的AST块)。例如#@myMacro() 的主体是#end。默认的引用名是 "bodyContent"(例如 $bodyContent)。该块宏特性是在Velocity 1.7版本中引入的。

解决方案

好吧,我尝试在一个宏里嵌套调用,似乎不被允许。

我几乎逐字照着你给的三个例子来做,它们立刻就能工作。

我唯一做的改变是针对inline示例:

#divTag( "#divTag('Testing Inline Div Syntax')" )

一个宏调用不能直接作为宏或方法的参数。这正是你在用例中,块宏结构之所以有趣的原因。

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章