当前位置: 首页 > 知识库问答 >
问题:

速度模板元数据

司徒宏远
2023-03-14

我尝试使用文字#[[...]]#块(并解析它们)和#set指令,但这两个指令都存在问题。它们很笨拙(需要对模板进行一些解析),而且远非优雅。

共有1个答案

糜征
2023-03-14

嗯,我不知道有什么内置的东西可以做到这一点。不过,为了避免在第一次传递时处理整个模板,一个技巧是在传递过程中有条件地抛出异常(metadatafinished),但不是正常执行。

显然,这仍然需要预先编译整个模板,尽管这在执行时会很有用。

例如。

import org.apache.commons.io.output.NullWriter;

public class Metadata {

    private Map<String, Template> byKey = new LinkedHashMap<>();
    private Template currentTemplate;

    /** Callback from .vm */
    public void set(String key) throws MetadataFinished {
        // Only do this in addTemplate()
        if (currentTemplate != null) {
            byKey.put(key, currentTemplate);
            throw new MetadataFinished();
        }
    }

    public void addTemplate(Template template) {
        currentTemplate = template;
        try {
            Context context = new VelocityContext();
            context.put("metadata", this);
            template.merge(context, new NullWriter());
        } catch (MetadataFinished ex) {
            // Ignored
        } finally {
            currentTemplate = null;
        }
    }

    public void execute(String key) {
        Template template = byKey.get(key);

        Context context = new VelocityContext();
        PrintWriter pw = new PrintWriter(System.out);
        template.merge(context, pw);
        pw.flush();
    }

    // Extends Error to avoid Velocity adding a wrapping MethodInvocationException
    private static class MetadataFinished extends Error {
    }

    public static void main(String[] args) {
        Metadata metadata = new Metadata();

        VelocityEngine engine = new VelocityEngine();
        engine.setProperty("file.resource.loader.path", "/temp");
        engine.init();

        String[] fileNames = { "one.vm", "two.vm" };
        for (String fileName : fileNames) {
            Template template = engine.getTemplate(fileName);
            metadata.addTemplate(template);
        }

        metadata.execute("vm1");
        metadata.execute("vm2");
    }
}
$!metadata.set("vm1")##
-----------
This is VM1
-----------

这里的##有点难看--它只是停止输出一个空行。如果可读性很重要,可以使用宏使其更加整洁:

#metadata("vm2")
-----------
This is VM2
-----------

该宏可以在全局vm_global_library.vm中定义:

#macro( metadata $key )
$!metadata.set($key)#end

仅供参考,输出与预期相同:

-----------
This is VM1
-----------
-----------
This is VM2
-----------
 类似资料:
  • 我在编辑速度模板。它们用于生成PDF。问题是我不能预览它们。我看不出模板呈现时会是什么样子。有什么工具可以用来吗?我试过谷歌搜索,但什么也找不到。 另外,我知道如果我在本地加载它,它不会显示变量。我感兴趣的是知道它会是什么样子。布局等。,

  • 我正在将一个应用程序从WebSphere迁移到Tomcat,从Ant迁移到Maven。在此过程中,我们决定对Spring进行更新,并对较新的版本进行少量其他更新。该应用程序可以追溯到2005年。所以不是所有的,都是最新和最伟大的。 其中一个障碍是,迁移到Spring5.0,下降了对速度的支持。我们的应用程序广泛使用的工具。我们用的是Spring2.8之类的!:) 现在,我看到这些声明:

  • 我试图将velocity模板中数组的最后一个元素删除,然后将其连接成字符串,并在下面的“classname”:键中显示结果: 我尝试了几种不同的方法来让数组删除元素并将其连接到一个字符串中,但到目前为止还没有任何运气。 从上面的示例中,我希望实现以下输出。 变量将保存不同长度的字符串,其中有不同数量的要拆分,这样数组的长度就会不同。

  • 我需要用价格值追加$symbol。从db中,我得到的值是:“125.00”、“--”、“废话废话”。 我只需要为有效的整数追加$symbol。如何才能做到这一点,我已经尝试了以下代码:

  • 有人能让我知道,如果有可能以某种方式打开速度Excel模板,并流到它的部分更大的数据量在飞行中? 假设我想在一个循环中读取外部资源ArrayLists中的数据。一个列表,每个迭代有10,000个项目。在简单的迭代中,我想把列表推到Velocity Excel模板中,跳到下一个迭代时忘掉它。在数据处理结束时,我将对Velocity上下文和模板与所有数据进行最后的合并。 null