0

我正在尝试将以下速度宏转换为速度 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指令扩展会有所帮助吗?

4

1 回答 1

1

我相信

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

将完成您想做的事情。

如果您可以访问 RuntimeServices,您可以调用createNewParser()然后parse(Reader reader, String templateName)在解析器内部调用,出来的 SimpleNode 有一个render()我认为您正在寻找的方法

于 2013-09-05T00:39:38.763 回答