NVelocity ASP.NET Examples

2019-04-11 04:06发布

I'm looking to use NVelocity in my ASP.NET MVC application, not as a view engine, just for rendering some email templates.

However, I cannot for the life of me get it to work. I have downloaded it from the castle project and followed the example at http://www.castleproject.org/others/nvelocity/usingit.html#step1

No matter what I try I don't seem to be able to load a template located in my site. The example suggests using the absolute path, which I have tried to no avail:

Template t = engine.GetTemplate("/Templates/TestEmail.vm");

So please can someone give me two examples. One of loading a template located in the web site directory and secondly one parsing a string variable (as it is likely that my templates will be stored in a database).

Many thanks Ben

3条回答
Juvenile、少年°
2楼-- · 2019-04-11 04:41

I also added the following method to process a string instead of a template file (say if retrieving the template content from a database):

        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();
        }
    }

And used StructureMap to initialize the service:

            ForRequestedType<ITemplateService>()
            .TheDefault.Is.ConstructedBy(()=> 
                new NVelocityTemplateService(HttpContext.Current.Server.MapPath("~/Content/Templates/")));
查看更多
Deceive 欺骗
3楼-- · 2019-04-11 04:41

You might find the TemplateEngine component useful.

It's an abstraction over template engines with a NVelocity implementation, similar to Darin's answer, but it should perform marginally better since it uses a single instance of the VelocityEngine (as opposed to initializing one instance per render) and has optional caching. It also has a couple other features, like logging, NVelocity property overriding and loading templates from assembly resources.

查看更多
Lonely孤独者°
4楼-- · 2019-04-11 04:44

I've used this class in one of my past projects:

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();
        }
    }
}

In order to instantiate the NVelocityTemplateRepository class you need to provide an absolute path where your templates root is. Then you use relative paths to reference your vm files.

查看更多
登录 后发表回答