Velocity, different template paths

2019-04-04 17:35发布

问题:

Does anyone know if it is possible to get templates from different paths with velocity? After initialization Velocity refuses to change the "file.resource.loader.path".

This is my code:

public Generator(){         
    Properties p = new Properties();
        p.setProperty("resource.loader", "file");
        p.setProperty("file.resource.loader.class", "org.apache.velocity.runtime.resource.loader.FileResourceLoader");
        p.setProperty("file.resource.loader.path", "");

    Velocity.init(p);
}

The templates can be located in different locations ( the user can select one with a file dialog ). So I have this code upon fetching the template out of velocity

private Template fetch (String templatePath) {
    out_println("Initializing Velocity core...");
    int end = templatePath.lastIndexOf(File.separator); 

    Properties p = new Properties();
        p.setProperty("file.resource.loader.path", templatePath.substring(0, end));
    Velocity.init(p);

    return Velocity.getTemplate(templatePath.substring(end+1));
}

This is not working. It seems that once Velocity is initialized it can't be reset with different properties. Any suggestions on how to solve this problem?

Possible Program flow:

  1. User selects group that needs to be filled into the template
  2. User selects a template to use (can be located anywhere on the hdd)
  3. User presses generate

回答1:

Velocity can be used in two ways: the singleton model or the separate instance model. You are currently using the singleton model in which only one instance of the Velocity engine in the JVM is allowed.

Instead, you should use the separate instance model which allows you to create multiple instances of Velocity in the same JVM in order to support different template directories.

VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, "path/to/templates");
ve.init();
Template t = ve.getTemplate("foo.vm");


回答2:

Consider instead of using singleton Velocity class creating and initializing new VelocityEngine before step 3.



回答3:

Adding to the points above:

Even if one is using non-singleton model i.e using VelocityEngine object. Multiple paths can be configured by giving comma separated values to the property.

[file.resource.loader.class=path1,path2]

In such a case velocity engine will look for template in path1 first and then in path2



回答4:

In my case I am using Velocity with Servlets in an Eclipse Dynamic Web Project.
I couldn't actually reset the path, but I could put a subdirectory under /WebContent folder and then organize my templates that way... and have nested subdirectories as well.

RequestDispatcher requestDispatcher = 
 request.getRequestDispatcher("/velocity_templates/index.vm");

This simple solution was all I needed ... didn't need to mess with velocity.properties in web.xml or setting them programmatically (in each case, neither approach worked for me unfortunately when I tried).

Note that when I do template includes with #parse(..) command, I need to use the same path prefix inside the template .vm file as I did in the example code for my servlet.



标签: java velocity