With all the recent attention given to the Razor view engine, I thought it would be interesting to see if I could prototype an even less intrusive syntax for a view engine. In other words…
From WebForms:
1 2 3 4 | <% for (var i = 0; i < 10; i++) {%> <%= Html.RadioButton("Rating", i, new { id = "vote" + i })%> <label for="<%= "vote" + i %>"><%= i%></label> <%} %> |
To Razor:
1 2 3 4 | @for (var i = 0; i < 10; i++) { @Html.RadioButton("Rating", i, new { id = "vote" + i }) <label for="vote" + @i">@i</label> } |
To Unobtrusive:
1 | #{ratings} |
The basic idea I came up with was to pair a view file up with a “code beside” file that has rules for processing view tokens. It’s sort of like XSLT, but with IronPython instead of XML. The view is clean and designer friendly. And the code beside file would have a template processing rule such as the following:
1 2 3 4 5 6 7 8 | def ratings(context): sb = StringBuilder() for i in range(10): sb.AppendFormat("<input type='radio' id='vote{0}' value='{0}' />", i); sb.AppendFormat("<label for='vote{0}'>{0}</label>", i) return sb.ToString() |
I also imagine this approach would lend itself well to IDE support. Control+Left Click on a token and you’re in the code beside file, editing the template.
The prototype is hardly as efficient as it could be. There’s no file caching. String building should probably be replaced by direct writing to the response’s output stream (or something better than using a StringBuilder and returning strings). And I feel like I should be using expression trees somewhere instead of a dictionary of function references. I also haven’t yet implemented partials, masters or HTML helpers. But of course, this is a prototype. A proof of concept…
The full Code Voyeur article is available at http://www.codevoyeur.com/Articles/23/An-Unobtrusive-IronPython-ViewEngine-for-ASP.NET-MVC.aspx.
Enjoy.
Pingback: ASP.NET MVC Archived Blog Posts, Page 1
No offence but that’s a terrible idea, the whole reason rasor is good is because people who only know html can still see what it’s doing, and html needs it’s own environment not just code, with your method it’s just spaghetti again.
Hi Daniel,
I’m guessing you haven’t been working with Web frameworks for very long or maybe you just didn’t read or understand my actual article?
Razor is simply attempting to reduce code noise (i.e., curly braces) in the template. People “who only know html” don’t benefit from seeing Razor’s templating language embedded in their HTML. What good is a for loop to a designer? Or more importantly, why should your designer even know what a model or view model is? Razor unnecessarily exposes these ideas.
The holy grail for all web frameworks has been the right mix of code and HTML. Classic ASP and PHP are the extreme spaghetti examples. By contrast, my prototype introduces nearly 100% separation of code and HTML. This approach has far less spaghetti than even Razor.
Either way, I appreciate the feedback!
– jz
Your sode doesn’t run:
Parser Error Message: An error occurred creating the configuration section handler for microsoft.scripting: Could not load file or assembly ‘Microsoft.Scripting’ or one of its dependencies. The system cannot find the file specified.
Source Error:
Line 9:
Line 10:
Line 11:
Line 12:
Line 13:
This code does not run. Apparently, some of the libraries have been moved:
An error occurred creating the configuration section handler for microsoft.scripting: Could not load file or assembly ‘Microsoft.Scripting’ or one of its dependencies. The system cannot find the file specified.
Are you still working on this framework? It looks like the foundation of a great system.
Hi Gabriel.
If you grab the code from https://bitbucket.org/johnzablocki/codevoyeur-samples/src/tip/src/ArticleSamples/IronPythonViewEngine/ it should run. I don’t include the binaries in the sample projects, though I probably should…
– John