将Velocity宏转换为Java指令

时间:2013-09-05 00:02:24

标签: java velocity

我正在尝试将下面的速度宏转换为速度Java指令,因为我需要在渲染逻辑周围添加一些铃声和口哨声:

#macro(renderModules $modules)
    #if($modules)
        #foreach($module in $modules)
            #if(${module.template})
                #set($moduleData = $module.data)
                #parse("${module.template}.vm")
            #end
        #end
    #end
#end

我的等效Java指令:

import org.apache.velocity.context.InternalContextAdapter;
import org.apache.velocity.exception.MethodInvocationException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.runtime.directive.Directive;
import org.apache.velocity.runtime.parser.node.ASTBlock;
import org.apache.velocity.runtime.parser.node.Node;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.io.Writer;
import java.util.List;

public class RenderModulesDirective extends Directive {
    private static final Logger LOGGER = LoggerFactory.getLogger(RenderModulesDirective.class);

    @Override
    public String getName() {
        return "renderModules";
    }

    @Override
    public int getType() {
        return LINE;
    }

    @Override
    public boolean render(InternalContextAdapter context, Writer writer, Node node) throws IOException, ResourceNotFoundException, ParseErrorException, MethodInvocationException {

        for(int i=0; i<node.jjtGetNumChildren(); i++) {
            Node modulesNode = node.jjtGetChild(i);
            if (modulesNode != null) {
                if(!(modulesNode instanceof ASTBlock)) {
                    if(i == 0) {
                        // This should be the list of modules
                        List<Module> modules = (List<Module>) modulesNode.value(context);
                        if(modules != null) {
                            for (Module module : modules) {
                                context.put("moduleData", module.getData());
                                String templateName = module.getTemplate() + ".vm";
                                try {
                                    // ??? How to parse the template here ???
                                } catch(Exception e) {
                                    LOGGER.error("Encountered an error while rendering the Module {}", module, e);
                                }
                            }
                            break;
                        }
                    }
                }
            }
        }

        return true;
    }
}

所以,我陷入了需要与#parse("<template_name>.vm")调用相当的Java的地步。这是正确的方法吗?相反,从Parse指令扩展是否有帮助?

1 个答案:

答案 0 :(得分:1)

我相信

Template template = Velocity.getTemplate("path/to/template.vm");
template.merge(context, writer);

将完成你想要做的事。

如果您有权访问RuntimeServices,可以调用createNewParser(),然后在解析器内部调用parse(Reader reader, String templateName),出现的SimpleNode有一个render()方法,我认为这就是你的'重看佛法