题
我期待使用NVelocity在我的ASP.NET MVC应用程序,而不是一个视图引擎,只是呈现了一些电子邮件模板。
不过,我不能为我的生命得到它的工作。我从城堡项目下载了它,随后在 HTTP的例子:// WWW .castleproject.org /其他的/ nvelocity / usingit.html#步骤1
不管我怎么努力我似乎不能够加载位于我的网站模板。该例子表明使用绝对路径,这是我试图无济于事:
Template t = engine.GetTemplate("/Templates/TestEmail.vm");
所以,请能有人给我两个例子。一个加载位于Web站点目录模板,其次一个解析字符串变量(因为这很可能是我的模板将被存储在数据库中)。
非常感谢 本
解决方案
我已经使用这个类在我过去的项目之一:
public interface ITemplateRepository
{
string RenderTemplate(string templateName, IDictionary<string, object> data);
string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data);
}
public class NVelocityTemplateRepository : ITemplateRepository
{
private readonly string _templatesPath;
public NVelocityTemplateRepository(string templatesPath)
{
_templatesPath = templatesPath;
}
public string RenderTemplate(string templateName, IDictionary<string, object> data)
{
return RenderTemplate(null, templateName, data);
}
public string RenderTemplate(string masterPage, string templateName, IDictionary<string, object> data)
{
if (string.IsNullOrEmpty(templateName))
{
throw new ArgumentException("The \"templateName\" parameter must be specified", "templateName");
}
var name = !string.IsNullOrEmpty(masterPage)
? masterPage : templateName;
var engine = new VelocityEngine();
var props = new ExtendedProperties();
props.AddProperty(RuntimeConstants.FILE_RESOURCE_LOADER_PATH, _templatesPath);
engine.Init(props);
var template = engine.GetTemplate(name);
template.Encoding = Encoding.UTF8.BodyName;
var context = new VelocityContext();
var templateData = data ?? new Dictionary<string, object>();
foreach (var key in templateData.Keys)
{
context.Put(key, templateData[key]);
}
if (!string.IsNullOrEmpty(masterPage))
{
context.Put("childContent", templateName);
}
using (var writer = new StringWriter())
{
engine.MergeTemplate(name, context, writer);
return writer.GetStringBuilder().ToString();
}
}
}
为了实例,你需要您的模板根是提供一个绝对路径NVelocityTemplateRepository
类。然后,可以使用相对路径来引用vm
文件。
其他提示
我还添加以下的方法来处理字符串而不是一个模板文件(比方说如果从数据库检索所述模板的内容):
public string RenderTemplateContent(string templateContent, IDictionary<string, object> data)
{
if (string.IsNullOrEmpty(templateContent))
throw new ArgumentException("Template content cannot be null", "templateContent");
var engine = new VelocityEngine();
engine.Init();
var context = GetContext(data);
using (var writer = new StringWriter()) {
engine.Evaluate(context, writer, "", templateContent);
return writer.GetStringBuilder().ToString();
}
}
和用于StructureMap初始化服务:
ForRequestedType<ITemplateService>()
.TheDefault.Is.ConstructedBy(()=>
new NVelocityTemplateService(HttpContext.Current.Server.MapPath("~/Content/Templates/")));
您可能会发现 TemplateEngine组件有用。
这是在与NVelocity实现模板引擎的抽象,类似 Darin的答案一>,但它应该因为它使用VelocityEngine的单个实例(相对于每初始化再现一个实例),并具有可选的缓存进行略好。它也有其他几个功能,如记录,NVelocity属性压倒一切的和加载的模板从组件资源。
不隶属于 StackOverflow