3

ASP.NET MVC アプリケーションで NVelocity をビュー エンジンとしてではなく、電子メール テンプレートをレンダリングするためだけに使用したいと考えています。

しかし、私は一生それを機能させることはできません。私は城プロジェクトからダウンロードし、http://www.castleproject.org/others/nvelocity/usingit.html#step1の例に従いました。

何を試しても、自分のサイトにあるテンプレートを読み込めないようです。この例では、絶対パスを使用することを提案していますが、これは役に立ちませんでした。

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

誰かが私に2つの例を教えてください。1 つは Web サイトのディレクトリにあるテンプレートをロードすること、もう 1 つは文字列変数を解析することです (私のテンプレートはデータベースに保存される可能性が高いため)。

どうもありがとうベン

4

3 に答える 3

6

過去のプロジェクトの 1 つでこのクラスを使用しました。

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ファイルを参照します。

于 2010-03-17T11:14:56.950 に答える
2

また、テンプレート ファイルの代わりに文字列を処理する次のメソッドを追加しました (データベースからテンプレート コンテンツを取得する場合など)。

        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/")));
于 2010-03-17T13:30:20.750 に答える
1

TemplateEngine コンポーネントが役立つ場合があります。

Darin's answerと同様に、NVelocity 実装を使用したテンプレート エンジンの抽象化ですが、(レンダーごとに 1 つのインスタンスを初期化するのではなく) VelocityEngine の単一のインスタンスを使用し、オプションのキャッシュがあるため、わずかにパフォーマンスが向上するはずです。また、ロギング、NVelocity プロパティのオーバーライド、アセンブリ リソースからのテンプレートの読み込みなど、他にもいくつかの機能があります。

于 2010-03-20T23:29:51.213 に答える