有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

将Velocity宏转换为Java指令

我正在尝试将下面的velocity宏转换为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;
    }
}

因此,我被困在需要Java等价物的#parse("<template_name>.vm")调用的地方。这是正确的方法吗?相反,扩展Parse指令会有帮助吗


共 (1) 个答案

  1. # 1 楼答案

    我相信

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

    将完成你想要做的事情

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