Reputation: 631
Just a simple velocity standalone app based on maven structure. Here is the code snippet written in Scala to render the template helloworld.vm
in ${basedir}/src/main/resources
folder:
com.ggd543.velocitydemo
import org.apache.velocity.app.VelocityEngine
import org.apache.velocity.VelocityContext
import java.io.StringWriter
/**
* @author ${user.name}
*/
object App {
def main(args: Array[String]) {
//First , get and initialize an engine
val ve = new VelocityEngine();
ve.init();
//Second, get the template
val resUrl = getClass.getResource("/helloworld.vm")
val t = ve.getTemplate("helloworld.vm"); // not work
// val t = ve.getTemplate("/helloworld.vm"); // not work
// val t = ve.getTemplate(resUrl.toString); // not work yet
//Third, create a context and add data
val context = new VelocityContext();
context.put("name", "Archer")
context.put("site", "http://www.baidu.com")
//Finally , render the template into a StringWriter
val sw = new StringWriter
t.merge(context, sw)
println(sw.toString);
}
}
when to compile and run the program, I got the following error:
2012-1-29 14:03:59 org.apache.velocity.runtime.log.JdkLogChute log
严重: ResourceManager : unable to find resource '/helloworld.vm' in any resource loader.
Exception in thread "main" org.apache.velocity.exception.ResourceNotFoundException: Unable to find resource '/helloworld.vm'
at org.apache.velocity.runtime.resource.ResourceManagerImpl.loadResource(ResourceManagerImpl.java:474)
at org.apache.velocity.runtime.resource.ResourceManagerImpl.getResource(ResourceManagerImpl.java:352)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1533)
at org.apache.velocity.runtime.RuntimeInstance.getTemplate(RuntimeInstance.java:1514)
at org.apache.velocity.app.VelocityEngine.getTemplate(VelocityEngine.java:373)
at com.ggd543.velocitydemo.App$.main(App.scala:20)
at com.ggd543.velocitydemo.App.main(App.scala)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
Process finished with exit code 1
Upvotes: 63
Views: 121468
Reputation: 1017
Using IntelIJ Idea community 2021.3, you just need to start your project with this config:
VelocityEngine engine = new VelocityEngine();
Properties props = new Properties();
final String path = "src/main/resources/templates/";
props.put("file.resource.loader.path", path);
engine.init(props);
You can put whatever path you want but realize that it will start from the project_root defined in the idea.
DISCLAIMER This solution may NOT work outside the IDE
Upvotes: 0
Reputation: 830
Make sure you have a properly configured resource loader. See Velocity documentation for help selecting and configuring a resource loader: https://velocity.apache.org/engine/1.7/developer-guide.html#configuring-resource-loaders
Upvotes: 3
Reputation: 11
The following code helped me resolve the issue. The path to the template needs to be provided as part of file.resource.loader path. By default it comes as "." . So setting the property explicitly will be required.
Print getClass().getClassLoader().getResource("resources")
or getClass().getClassLoader().getResource("")
to see where your template comes and based on that set it in the velocity template engine.
URL url = getClass().getClassLoader().getResource("resources");
//URL url = getClass().getClassLoader().getResource("");
File folder= new File(url.getFile());
VelocityEngine ve = new VelocityEngine();
ve.setProperty(Velocity.FILE_RESOURCE_LOADER_PATH, folder.getAbsolutePath());
ve.init();
Template template = ve.getTemplate( "MyTemplate.vm" );
Upvotes: 1
Reputation: 4801
I have put this working code snippet for future references. The code sample was written with Apache velocity version 1.7 with embedded Jetty.
Velocity template path is located at the resource folder email_templates subfolder.
Code Snippet in Java (Snippets are worked both running on eclipse and inside a Jar)
templateName = "/email_templates/byoa.tpl.vm"
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
Template t = ve.getTemplate(this.templateName);
VelocityContext velocityContext = new VelocityContext();
velocityContext.put("","") // put your template values here
StringWriter writer = new StringWriter();
t.merge(this.velocityContext, writer);
System.out.println(writer.toString()); // print the updated template as string
For OSGI plugging code snippets.
final String TEMPLATE = "resources/template.vm" // located in the resources folder
Thread current = Thread.currentThread();
ClassLoader oldLoader = current.getContextClassLoader();
try {
current.setContextClassLoader(TemplateHelper.class.getClassLoader()); // TemplateHelper is a class inside your jar file
Properties p = new Properties();
p.setProperty("resource.loader", "class");
p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init( p );
VelocityEngine ve = new VelocityEngine();
Template template = Velocity.getTemplate( TEMPLATE );
VelocityContext context = new VelocityContext();
context.put("tc", obj);
StringWriter writer = new StringWriter();
template.merge( context, writer );
return writer.toString() ;
} catch(Exception e){
e.printStackTrace();
} finally {
current.setContextClassLoader(oldLoader);
}
Upvotes: 3
Reputation: 1
Just a simple velocity standalone app based on maven structure. Here is the code snippet written in Scala to render the template helloworld.vm in
${basedir}/src/main/resources folder:
Upvotes: -1
Reputation: 1018
I faced a similar issue. I was copying the velocity engine mail templates in wrong folder. Since JavaMailSender and VelocityEngine are declared as resources under MailService, its required to add the templates under resource folder declared for the project.
I made the changes and it worked. Put the templates as
src/main/resources/templates/<package>/sampleMail.vm
Upvotes: 0
Reputation: 1492
I faced the similar problem with intellij IDEA. you can use this
VelocityEngine ve = new VelocityEngine();
Properties props = new Properties();
props.put("file.resource.loader.path", "/Users/Projects/Comparator/src/main/resources/");
ve.init(props);
Template t = ve.getTemplate("helloworld.vm");
VelocityContext context = new VelocityContext();
Upvotes: 5
Reputation: 1201
I put my .vm under the src/main/resources/templates
, then the code is :
Properties p = new Properties();
p.setProperty("resource.loader", "class");
p.setProperty("class.resource.loader.class", "org.apache.velocity.runtime.resource.loader.ClasspathResourceLoader");
Velocity.init( p );
VelocityContext context = new VelocityContext();
Template template = Velocity.getTemplate("templates/my.vm");
this works in web project.
In eclipse Velocity.getTemplate("my.vm") works since velocity will look for the .vm file in src/main/resources/ or src/main/resources/templates, but in web project, we have to use Velocity.getTemplate("templates/my.vm");
Upvotes: 35
Reputation: 107
VelocityEngine velocityEngin = new VelocityEngine();
velocityEngin.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
velocityEngin.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
velocityEngin.init();
Template template = velocityEngin.getTemplate("nameOfTheTemplateFile.vtl");
you could use the above code to set the properties for velocity template. You can then give the name of the tempalte file when initializing the Template and it will find if it exists in the classpath.
All the above classes come from package org.apache.velocity*
Upvotes: 2
Reputation: 3
You can also put your templates folder under src/main/resources instead of src/main/java. Works for me and it's a preferable location since templates are not java source.
Upvotes: 0
Reputation: 1037
While using embedded jetty the property webapp.resource.loader.path should starts with slash:
webapp.resource.loader.path=/templates
otherwise templates will not be found in ../webapp/templates
Upvotes: 0
Reputation: 23
you can try to add these code:
VelocityEngine ve = new VelocityEngine();
String vmPath = request.getSession().getServletContext().getRealPath("${your dir}");
Properties p = new Properties();
p.setProperty("file.resource.loader.path", vmPath+"//");
ve.init(p);
I do this, and pass!
Upvotes: 2
Reputation: 123
You can just use it like this:
Template t = ve.getTemplate("./src/main/resources/templates/email_html_new.vm");
It works.
Upvotes: 9
Reputation: 1409
Great question - I solved my issue today as follows using Ecilpse:
Put your template in the same folder hierarchy as your source code (not in a separate folder hierarchy even if you include it in the build path) as below:
In your code simply use the following lines of code (assuming you just want the date to be passed as data):
VelocityEngine ve = new VelocityEngine();
ve.setProperty(RuntimeConstants.RESOURCE_LOADER, "classpath");
ve.setProperty("classpath.resource.loader.class", ClasspathResourceLoader.class.getName());
ve.init();
VelocityContext context = new VelocityContext();
context.put("date", getMyTimestampFunction());
Template t = ve.getTemplate( "templates/email_html_new.vm" );
StringWriter writer = new StringWriter();
t.merge( context, writer );
See how first we tell VelocityEngine to look in the classpath. Without this it wouldn't know where to look.
Upvotes: 109