Apache Velocity:是否有一种标准方法可以从命令行验证模板的正确性?

发布于 2024-08-14 08:43:10 字数 4953 浏览 7 评论 0原文

我们的网站使用 Apache Velocity 模板语言。我们的内容管理系统已经检查所有生成的 XML 文档的格式是否良好。我们被要求在将文件推送到实时站点之前检查文档以捕获 Velocity 语法错误。

是否有从命令行验证 Velocity 模板正确性的标准方法?

我准备读取模板路径、初始化 Velocity 引擎、解析模板并捕获任何错误 如本页所示,但如果有一个现成的工具,需要一个文件和一个配置,并吐出任何错误,那么我宁愿使用它。


更新

这就是我最终所做的:

package velocitysample;

import java.io.IOException;
import java.io.StringWriter;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.MethodInvocationException;

public class Main
{
   /** Define a static logger variable so that it references the Logger
    *  instance named "MyApp".
    */
    private static Logger logger = Logger.getLogger(Main.class);


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {

        /* Set up a simple log4j configuration that logs on the console. */
        BasicConfigurator.configure();


        /* Check to see that a template path was passed on the command line. */
        if (args.length != 1)
        {
            logger.fatal("You must pass the path to a template as a " +
                    "command line argument.");
            return;
        }

        /* Pull the template filename from the command line argument. */
        String fileName = args[0];

        try
        {
            Velocity.setProperty("resource.loader", "file");
            Velocity.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
            Velocity.setProperty("file.resource.loader.path", "/templates/");
            Velocity.setProperty("file.resource.loader.cache", "false");
            Velocity.setProperty("file.resource.loader.modificationCheckInterval", "0");

            Velocity.init();
        }
        catch (Exception ex)
        {
            logger.fatal("Error initializing the Veolcity engine.", ex);
            return;
        }

        boolean error = false;

        /* Create an empty Velocity context */
        VelocityContext context = new VelocityContext();

        Template template = null;

        try
        {
           template = Velocity.getTemplate(fileName);
        }
        catch( ResourceNotFoundException rnfe )
        {
           logger.error("Couldn't find the template to parse at this path: " +
                   fileName + ".", rnfe);
           error = true;
        }
        catch( ParseErrorException peex )
        {
            logger.error("Error parsing the template located at this path: " +
                    fileName + ".", peex);
            error = true;
        }
        catch( MethodInvocationException mie )
        {
            logger.error("Something invoked in the template (" + fileName +
                    ") threw an Exception while parsing.", mie);
            error = true;
        }
        catch( Exception e )
        {
            logger.error("An unexpected exception was thrown when attempting " +
                    "to parse the template: " + fileName + ".", e);
            error = true;
        }

        if (error)
        {
            return;
        }

        StringWriter sw = new StringWriter();
        try
        {
            template.merge(context, sw);
        } 
        catch (ResourceNotFoundException rnfe)
        {
            logger.error("Couldn't find the template to merge at this path: " +
                   fileName + ".", rnfe);
            error = true;
        } 
        catch (ParseErrorException peex)
        {
            logger.error("Error parsing the template at this path during merge: " +
                    fileName + ".", peex);
            error = true;
        } 
        catch (MethodInvocationException mie)
        {
            logger.error("Something invoked in the template (" + fileName +
                    ") threw an Exception while merging.", mie);
            error = true;
        } 
        catch (IOException ioe)
        {
            logger.error("Error reading the template located at this path from " +
                    "disk: " + fileName + ".", ioe);
            error = true;
        }
        catch( Exception e )
        {
            logger.error("An unexpected exception was thrown when attempting " +
                    "to merge the template: " + fileName + ".", e);
            error = true;
        }

        if (!error)
        {
            logger.info("No syntax errors detected.");
        }
    }
}

Our website uses the Apache Velocity template language. Our Content Management System already checks any generated XML documents for well-formedness. We've been asked to check documents to catch Velocity syntax errors before pushing the files to the live site.

Is there a standard way of verifying the correctness of a Velocity template from the command line?

I am prepared to read in the template path, initialize the Velocity Engine, parse the template, and capture any errors as shown on this page, but if there's a ready made tool that takes a file and a configuration, and spits out any errors, then I'd rather use that.


Update

Here's what I ended up doing:

package velocitysample;

import java.io.IOException;
import java.io.StringWriter;
import org.apache.log4j.Logger;
import org.apache.log4j.BasicConfigurator;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.Template;
import org.apache.velocity.app.Velocity;
import org.apache.velocity.exception.ResourceNotFoundException;
import org.apache.velocity.exception.ParseErrorException;
import org.apache.velocity.exception.MethodInvocationException;

public class Main
{
   /** Define a static logger variable so that it references the Logger
    *  instance named "MyApp".
    */
    private static Logger logger = Logger.getLogger(Main.class);


    /**
     * @param args the command line arguments
     */
    public static void main(String[] args)
    {

        /* Set up a simple log4j configuration that logs on the console. */
        BasicConfigurator.configure();


        /* Check to see that a template path was passed on the command line. */
        if (args.length != 1)
        {
            logger.fatal("You must pass the path to a template as a " +
                    "command line argument.");
            return;
        }

        /* Pull the template filename from the command line argument. */
        String fileName = args[0];

        try
        {
            Velocity.setProperty("resource.loader", "file");
            Velocity.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
            Velocity.setProperty("file.resource.loader.path", "/templates/");
            Velocity.setProperty("file.resource.loader.cache", "false");
            Velocity.setProperty("file.resource.loader.modificationCheckInterval", "0");

            Velocity.init();
        }
        catch (Exception ex)
        {
            logger.fatal("Error initializing the Veolcity engine.", ex);
            return;
        }

        boolean error = false;

        /* Create an empty Velocity context */
        VelocityContext context = new VelocityContext();

        Template template = null;

        try
        {
           template = Velocity.getTemplate(fileName);
        }
        catch( ResourceNotFoundException rnfe )
        {
           logger.error("Couldn't find the template to parse at this path: " +
                   fileName + ".", rnfe);
           error = true;
        }
        catch( ParseErrorException peex )
        {
            logger.error("Error parsing the template located at this path: " +
                    fileName + ".", peex);
            error = true;
        }
        catch( MethodInvocationException mie )
        {
            logger.error("Something invoked in the template (" + fileName +
                    ") threw an Exception while parsing.", mie);
            error = true;
        }
        catch( Exception e )
        {
            logger.error("An unexpected exception was thrown when attempting " +
                    "to parse the template: " + fileName + ".", e);
            error = true;
        }

        if (error)
        {
            return;
        }

        StringWriter sw = new StringWriter();
        try
        {
            template.merge(context, sw);
        } 
        catch (ResourceNotFoundException rnfe)
        {
            logger.error("Couldn't find the template to merge at this path: " +
                   fileName + ".", rnfe);
            error = true;
        } 
        catch (ParseErrorException peex)
        {
            logger.error("Error parsing the template at this path during merge: " +
                    fileName + ".", peex);
            error = true;
        } 
        catch (MethodInvocationException mie)
        {
            logger.error("Something invoked in the template (" + fileName +
                    ") threw an Exception while merging.", mie);
            error = true;
        } 
        catch (IOException ioe)
        {
            logger.error("Error reading the template located at this path from " +
                    "disk: " + fileName + ".", ioe);
            error = true;
        }
        catch( Exception e )
        {
            logger.error("An unexpected exception was thrown when attempting " +
                    "to merge the template: " + fileName + ".", e);
            error = true;
        }

        if (!error)
        {
            logger.info("No syntax errors detected.");
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

揽月 2024-08-21 08:43:10

Velocity 中有一个名为 TemplateTool 的工具,它会转储所有引用,并可用于验证模板的语法。

但是,您必须正确设置上下文才能验证任何模板。因此,最好的验证是根据自己的上下文编写自己的工具。

There is a tool distributed with Velocity called TemplateTool, which dumps all the references and it can be used to validate the syntax of the template.

However, you must have the context setup correctly to verify any template. So the best verification is to write your own tool with your own context.

感情洁癖 2024-08-21 08:43:10

要捕获 Velocity 语法错误,您的方法可能是最好的。

但是,它将忽略无效的宏参数和不存在的引用。在 Velocity 1.6 中,您可以设置一个严格模式,该模式会针对错误的宏参数(例如错误的数字)或错误的引用(例如 $abc.badMethod() )抛出异常。这假设您正在填充测试工具中使用的模板的上下文,就像在生产中使用模板时一样。

To catch Velocity syntax errors, your approach is probably the best.

However, it will ignore invalid macro arguments and non-existent references. In Velocity 1.6 there is a strict mode that you can set which will throw an exception for bad macro parameters (e.g. the wrong number) or for bad references (e.g. $abc.badMethod() ). This assumes you are populating the context of the templates used in your testing tool the same as when the templates are used in production.

2024-08-21 08:43:10

2010 年 12 月,有人发布了一个验证 Velocity 的工具。我尝试了一下,效果很好。它使用 Velocity 1.6.4,但如果需要,也许可以更换为其他版本。

http://code.google.com/p/velocity-validator/

In December 2010 someone published a tool for validating Velocity. I tried it out and it works fine. It uses Velocity 1.6.4, but maybe that can be swapped out for a different version if needed.

http://code.google.com/p/velocity-validator/

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文