replacing NVelocity

5 views
Skip to first unread message

Justin Chase

unread,
Jul 22, 2008, 10:53:18 PM7/22/08
to Spark View Engine Dev
Hello,

I am currently working on a project called NBusiness (http://
www.codeplex.com/NBusiness) and I have been trying to use NVelocity to
generate code and I've been having some issues with it. I have tried
contacting their forums but it seems to be moderated and the moderator
is on permanent vacation... anyway I'm trying to find a view engine
for code.

So basically I have two questions for you all:

1.) Do you think Spark is up to the challenge of generating code (such
as C# or VB)? Or is it geared too much towards HTML?

2.) Can spark handle enumerations? For example the problem I am having
in NVelocity is checking the value of an enumeration in an if/elseif
block (i.e. "#if($entity.Method == "Get")", does not work!).


I'm not really enthused about the quality of NVelocity and I'd be
happy to switch to something better.

Louis DeJardin

unread,
Jul 23, 2008, 1:35:33 AM7/23/08
to spar...@googlegroups.com
The default grammar is designed to fit the markup like a glove, so
you'd probably wouldn't get the best possible results using it as-is.
But it shouldn't be too difficult to make the grammar replacable and
craft one which fits nicely in a code template file.

Enumerations are not a problem, spark expressions are csharp. I'll
take a look at nbusiness to see what type of templating you're trying
to do. (I'm on a blackberry at the moment.)

Justin Chase

unread,
Jul 23, 2008, 9:48:39 AM7/23/08
to Spark View Engine Dev
For example here is a chunk of my NVelocity template:

[Serializable]
public partial class $entity.Name : BusinessBase<$entity.Name>
{
#region Properties
#foreach($field in $entity.Fields)
private static PropertyInfo<$field.TypeName> $
{field.Name}Property =
RegisterProperty<$field.TypeName>(
typeof($entity.Name),
new PropertyInfo<$field.TypeName>("$field.Name"));
/// <summary>
/// $field.Name property
/// </summary>
public $field.TypeName $field.Name
{
get { return
GetProperty<$field.TypeName>(${field.Name}Property); }
#if($field.IsId == false && $field.IsAuto == false &&
$field.IsReadOnly ==
false)
set { SetProperty<$field.TypeName>(${field.Name}Property,
value); }
#elseif($field.IsId == true && $field.IsAuto == false)
set
{
if(!(FieldManager.FieldExists(${field.Name}Property))
SetProperty<$field.TypeName>($
{field.Name}Property,
value);
}
#end
}
#end

So I am wanting to litterally generate C# and VB code with a template.
Spark
is starting to sound good...

On Jul 23, 12:35 am, "Louis DeJardin" <louis.dejar...@gmail.com>
wrote:
> The default grammar is designed to fit the markup like a glove, so
> you'd probably wouldn't get the best possible results using it as-is.
> But it shouldn't be too difficult to make the grammar replacable and
> craft one which fits nicely in a code template file.
>
> Enumerations are not a problem, spark expressions are csharp. I'll
> take a look at nbusiness to see what type of templating you're trying
> to do. (I'm on a blackberry at the moment.)
>

Louis DeJardin

unread,
Jul 23, 2008, 10:52:41 AM7/23/08
to spar...@googlegroups.com
That sounds perfectly reasonable. It looks like the ${expression}
syntax works very well, though you'll definitely want a different
grammar to prevent things that look like <element>s causing parse
errors.

Is there a particular syntax you for have in mind for control
notation? A leading # works, though it might be a problem if you want
to include #if statements in the output code.

Maybe a set of special comments, like

//foreach(var thing in entity.Things)
public ${thing.TypeName} ${thing.Name};
//end

Although in this case straight inlineIcode would probably fit nicely
and be more managable than it is in html. Maybe a simple escape for
that type of thing?

//! foreach (var ns in entity.namespaces) {
using ${ns};
//! }

Justin Chase

unread,
Jul 23, 2008, 3:10:24 PM7/23/08
to Spark View Engine Dev
Thanks for the response. You know actually I don't want to propose any
new type of syntax, I'm perfectly happy with the <if condition="...">
syntax! The previously posted code is actually a code snippet from an
NVelocity template I have been working on. I guess I just wanted to
run things by you all to see if you thought it would even work to try
to generate the above code with Spark (assuming I replace the
NVelocity tags with spark tags), since it's not HTML I'm trying to
output. I was just hoping that there wasn't going to be any type of
HTML validation or anything like that.

However... Clearly the appeal of spark is that it visually integrates
with the targeted output cleanly. Meaning the spark processed blocks
appear like HTML and it's primarily targeted at producing HTML so it
seems much cleaner. This sort of begs the question, is it possible to
build a view engine that can do this for any type of language? So you
were proposing a sort of "//!" syntax that could be used for
generating C# code. This is interesting but I'm just wondering if
that's a scalable solution, I mean next you'll have VB people and Boo
people and everyone else asking for special syntax. But then again we
don't necessarily want a 100 view engines that all do the same thing
only with slightly different syntax do we? I don't know the solution
but it's an interesting question.

Also, one other thing I haven't seen in your documentation yet is how
to actually consume spark. Since I won't be using Spark through MS-MVC
or monorail I'll probably need to call it directly, I'll figure it out
eventually but if you have a simple example somehwere it could save me
some time. What I'm really hoping for is to do some variation of this:

string example = "Hello World!";
string template = "${example}";

Spark s = new Spark();
s.Data["example"] = example;
string code = s.Merge(template);


Thanks!


On Jul 23, 9:52 am, "Louis DeJardin" <louis.dejar...@gmail.com> wrote:
> That sounds perfectly reasonable. It looks like the ${expression}
> syntax works very well, though you'll definitely want a different
> grammar to prevent things that look like <element>s causing parse
> errors.
>
> Is there a particular syntax you for have in mind for control
> notation? A leading # works, though it might be a problem if you want
> to include #if statements in the output code.
>
> Maybe a set of special comments, like
>
> //foreach(var thing in entity.Things)
> public ${thing.TypeName} ${thing.Name};
> //end
>
> Although in this case straight inlineIcode would probably fit nicely
> and be more managable than it is in html. Maybe a simple escape for
> that type of thing?
>
> //! foreach (var ns in entity.namespaces) {
> using ${ns};
> //! }
>

Louis DeJardin

unread,
Jul 23, 2008, 4:05:43 PM7/23/08
to spar...@googlegroups.com
Oh it's no problem. It's an interesting use-case. Plus I'm not
thinking of writing a new view engine.

Internally spark goes through a handful of steps to parse the template
markup with a loose xml grammar, postprocess for special node and
attributes, build a list of logical code chunks, and finally to use a
small number of generators on the code chunks to render the source
code. The source is then compiled and loaded.

So I was thinking of refactoring just the first few steps (parsing
with a grammar, postprocess of of nodes, and building of logical
chunks) into a little pluggable service provider class. No problem
there. Then simply make a different provider that parses with a
different grammar and builds the code chunks.

And before you know it you can instantiate the spark view factory, set
a different grammar provider, and you'll be able to parse code-centric
templates all you want.

It'll be kind of like skinning spark. Could be a nice feature to have
in general, since someone will probably ask about js/css template
targets some day. :)

On 7/23/08, Justin Chase <justn...@gmail.com> wrote:
>

Louis DeJardin

unread,
Jul 23, 2008, 5:08:04 PM7/23/08
to spar...@googlegroups.com

Also, here's an example of running spark from code without using one of the view engine plugins. The syntax provider stuff isn't done or committed quite yet, but you get the idea.

[Test]
public void UsingCSharpSyntaxInsideEngine()
{
    // engine takes base class and IViewFolder
    var engine = new SparkViewEngine(
        "Spark.Tests.Stubs.StubSparkView",
        new FileSystemViewFolder("Views"));

    // replace the default grammar
    engine.SyntaxProvider = new CSharpSyntaxProvider();

    // describe and instantiate view
    var descriptor = new SparkViewDescriptor();
    descriptor.Templates.Add("Code\\simplecode.spark");
    var view = (StubSparkView)engine.CreateInstance(descriptor);

    // provide data and render
    view.ViewData["hello"] = "world";
    var code = view.RenderView();

    Assert.IsNotNull(code);
}

You'll need to provide a base view class which inherits from Spark.AbstractSparkView and implements the ViewData property. That base class is also an excellent place to add any member properties and methods you would like to invoke from within the generated class.

You can add multiple templates to the descriptor which are expected to be in "inside-out" order, which is how you get master or layout rendering in html. You might never need that for your situation.

IViewFolder is also an interface you can implement if you want a layer of abstraction between spark and wherever the file contents come from.

Justin Chase

unread,
Jul 23, 2008, 10:19:20 PM7/23/08
to Spark View Engine Dev
Thanks! This sounds like more steps than I was hoping but being fully
extensible is probably much better honestly. I was immediately
thinking how
I might be able to call the views without having to be dependent on
the
filesystem and I noticed you mentioned the IViewFolder interface so +1
for
extensibility!

I'll give it a shot in the next couple of days and let you know how it
goes.
> On Wed, Jul 23, 2008 at 3:05 PM, Louis DeJardin <louis.dejar...@gmail.com>
> wrote:
>
> > Oh it's no problem. It's an interesting use-case. Plus I'm not
> > thinking of writing a new view engine.
>
> > Internally spark goes through a handful of steps to parse the template
> > markup with a loose xml grammar, postprocess for special node and
> > attributes, build a list of logical code chunks, and finally to use a
> > small number of generators on the code chunks to render the source
> > code. The source is then compiled and loaded.
>
> > So I was thinking of refactoring just the first few steps (parsing
> > with a grammar, postprocess of of nodes, and building of logical
> > chunks) into a little pluggable service provider class. No problem
> > there. Then simply make a different provider that parses with a
> > different grammar and builds the code chunks.
>
> > And before you know it you can instantiate the spark view factory, set
> > a different grammar provider, and you'll be able to parse code-centric
> > templates all you want.
>
> > It'll be kind of like skinning spark. Could be a nice feature to have
> > in general, since someone will probably ask about js/css template
> > targets some day. :)
>

Justin Chase

unread,
Jul 24, 2008, 7:48:55 PM7/24/08
to Spark View Engine Dev
Ok I'm getting hung up, here is what I have so far:

#region ICodeGeneratorEngine Members

public string Generate(Entity entity, string template,
EntityCompileParameters parameters)
{
NBusinessViewFolder viewFolder = new NBusinessViewFolder();
viewFolder.Add("template", template);

SparkViewEngine engine = new SparkViewEngine(
typeof(NBusinessView).FullName,
viewFolder);

string controllerName = "???";
string viewName = "template";
string masterName = "???";

NBusinessView view =
(NBusinessView)engine.CreateInstance(controllerName, viewName,
masterName);
view.Entity = entity;

StringBuilder builder = new StringBuilder();
using (TextWriter writer = new StringWriter(builder))
{
view.RenderView(writer);
}

return builder.ToString();
}

#endregion

And here is my view:
class NBusinessView : AbstractSparkView
{
public Entity Entity { get; set; }

public override void RenderView(System.IO.TextWriter writer)
{
}
}

So I was using reflector to look through the spark assemblies I
downloaded from your site (http://dev.dejardin.org/download) except I
could not actually find a concrete implementation of ISparkView... in
the castle and the mvc projects I saw a SparkView and
SparkView<TModel> but no concrete implementation. So where does the
actual compiler get ahold of the view and merge it with the viewdata?


On Jul 23, 4:08 pm, "Louis DeJardin" <louis.dejar...@gmail.com> wrote:
> On Wed, Jul 23, 2008 at 3:05 PM, Louis DeJardin <louis.dejar...@gmail.com>
> wrote:
>
> > Oh it's no problem. It's an interesting use-case. Plus I'm not
> > thinking of writing a new view engine.
>
> > Internally spark goes through a handful of steps to parse the template
> > markup with a loose xml grammar, postprocess for special node and
> > attributes, build a list of logical code chunks, and finally to use a
> > small number of generators on the code chunks to render the source
> > code. The source is then compiled and loaded.
>
> > So I was thinking of refactoring just the first few steps (parsing
> > with a grammar, postprocess of of nodes, and building of logical
> > chunks) into a little pluggable service provider class. No problem
> > there. Then simply make a different provider that parses with a
> > different grammar and builds the code chunks.
>
> > And before you know it you can instantiate the spark view factory, set
> > a different grammar provider, and you'll be able to parse code-centric
> > templates all you want.
>
> > It'll be kind of like skinning spark. Could be a nice feature to have
> > in general, since someone will probably ask about js/css template
> > targets some day. :)
>

Justin Chase

unread,
Jul 25, 2008, 10:09:47 AM7/25/08
to Spark View Engine Dev
Ah actually, I had a little bit of an epiphany last night while I was
sleeping (yes I somehow solve problems in my sleep). I'm just now
realizing that enging.CreateInstance() is actually generating the
concrete class based on the view and the base class I specified
earlier. And I don't need to implement RenderView in my base class
because it's abstract and the generated concrete instance will
generate it! So that only begs the question, how does the spark view
get ahold of the custom members? Does it just do it by reflection or
does it use the property "ViewData" as a dictionary by convention?

Louis DeJardin

unread,
Jul 25, 2008, 12:38:14 PM7/25/08
to spar...@googlegroups.com
Ah, my apologies! The examples I was providing were from the trunk, which has a refactored CreateInstance method which does not use controller/view/master names. The zip from last week won't work for you.

I'm going to close out a few of the tickets that were added recently and post a new build today.

I'd suggest making the NBusinessView abstract and removing the override RenderView method. Spark will make a class which inherits from NBusinessView and generate the RenderView method inside of that. In that class all of the ${expression} will become Output.Write(expression);

So that's pretty much all there is to merging the view data. Once you set the Entity property and call RenderView(writer) it'll be using the property you've just provided.

Justin Chase

unread,
Jul 25, 2008, 12:44:37 PM7/25/08
to Spark View Engine Dev
Gotcha! That is pretty tricky but I think I finally got it. I'll wait
a little while longer to get ahold of the new build.
Reply all
Reply to author
Forward
0 new messages