Scott Watermasysk

Still Learning to Code

NVelocity Server Control

I have been chatting with some folks about the possibility of introducing NVelocity into ASPX pages without the need to use MVC or have the entire page generated by it.

Using the SimpleTemplate component I pushed previously, I wrote a light weight server control which wraps the NVelocity implementation. This control should be usable with both ASP.Net MVC and regular ASPX pages.

Before we look at the code, here it is in action:


<T:SimpleTemplateControl runat="Server" ID="test1" >
 
    #foreach($name in $content)
        <h1>Name: $name</h1>
    #end
 
</T:SimpleTemplateControl>
 
<T:SimpleTemplateControl runat="Server" 
    ID="test2" DataSourceName = "names" >
    
    #foreach($name in $names)
        <h1>Name: $name.First, $name.Last</h1>
    #end
 
</T:SimpleTemplateControl>

Then, some simple code to bind the data:


protected void Page_Load(object sender, EventArgs e)
{
    string[] names = {"Scott", "Beata", "Emily"};
    test1.DataSource = names; 
 
    object[] items = 
                    {
                        new {First = "Scott", Last = "Watermasysk"},
                        new {First = "Emily", Last = "Watermasysk"}
                    };
 
    test2.DataSource = items;
}

There is quite a bit which could be done to improve the code (caching, shared contexts, access to the context, remove #foreach, etc), but for now, here it is:


[ParseChildren(false)]
public class SimpleTemplateControl : DataBoundControl
{
    public string DataSourceName
    {
        get; set;
    }
 
    [PersistenceMode(PersistenceMode.InnerDefaultProperty)]
    public string Template
    {
        get; set;
    }
 
    protected override void AddParsedSubObject(object obj)
    {
        var litControl = obj as LiteralControl;
        if(litControl != null)
            Template = litControl.Text;
    }
 
    protected override void Render(HtmlTextWriter writer)
    {
        if (string.IsNullOrEmpty(Template)) return;
 
        var icntx = TemplateEngine.CreateContext();
            
        if(DataSource != null)
            icntx.Put(DataSourceName ?? "content", DataSource);
 
        writer.Write(TemplateEngine.Parse(Template, icntx));
    }
}

Also note, as previously mentioned, NVelocity’s support for fancy loops means there is no need for separate templates like ASP.Net’s Repeater control.