Roadmap and Points of Interest
The current released version is called CTP 01. It is a preview version demonstrating the idea: The point is to get some feedback about the principal idea - not really about the implementation. If you are looking for something you can actually use in production, please check back in one or two months: I am about to start a major rewrite to fix the hack-level code.
- April: Release Candidate
- Feature-complete version ready for real testing and restricted production use.
- May-June: Version 1.0
- Visual Studio 2010 Designer tools
- Perhaps a separate Enterprise version.
All around in the documentation I have put ideas that I clearly have for further development. I thought it would be helpful to also put all of them here in one place. There are also some that I have not mentioned elsewhere.
I am not making any commitments, but these are the things I am thinking:
- Currently, only one declaration is applied to each element or attribute (except with @if and even there are some issues): possibility to apply more.
- Extensibility: custom declaration handlers and renderers, possibly directives and formatters.
- Implement Asp.Net MVC HtmlHelper methods: Not all, but ones that make sense.
- Additional declarations like: display/hide, attr-hide, change-element
- @debugger directive for more control.
More features to Templates
- Inline templates: possibility to add a template HTML directly in the Bellevue script.
- Conditional templates: use this template, if "item(x)" is true, otherwise use that template.
- Making the inner html of the match(es) to be the template instead of the outer HTML:
- Templates from include files
- Creating new data structures - at least for template calls.
- Resolving to ViewData and Model property paths work in most cases, but there is some room for improvement in edge cases / consistency.
- Rewrite @if: The else and else-if cases are missing explicitly and implicit else does not work.
- I am considering the whole function syntax. I would rather like chained dot-syntax "data(foo).strip().first()" instead of the nesting "first(strip(data(foo)))", but it would probably mean a major rewrite to the CSS parser.
StringTemplate as inspiration
The main inspiration for me in the design is Terence Parr's StringTemplate. The main point there that I am trying to follow is the principle of strict model-view separation. From StringTemplate web site:
Its distinguishing characteristic is that it strictly enforces model-view separation unlike other engines. Strict separation makes websites and code generators more flexible and maintainable; it also provides an excellent defense against malicious template authors.
I do believe in this concept: I think one of the main problems with Asp.Net (MVC) Web Forms is that when developers have pressure in projects, they start hacking model and controller logic into the aspx-views instead of making proper changes into the controller and model code. I have seen this happen many times and I must admit I am guilty of it myself.
Check the link to the PDF above to understand the whole model-view separation idea. Here is an unfinished comparison to StringTemplate features, it is also in the downloads project.
I am using the following excellent projects as bases for the implementation
- To parse HTML, I use the HTML Agility Pack. This project seems to be quite mature: I have found one bug and that was minor.
- I use the Simple CSS Parser to parse the Bellevue script. There, I have had more problems and I might be forced to either change the code in the parser or implement a custom parser. This is not to say that the CSS Parser project is bad quality: it is just that Bellevue script is not really CSS and I am using a lot of edge cases which produces problems.
- For positioning custom logic in HTML based on the CSS selectors, I use of course Fizzler. I am using it as it is designed to be used - have not tried many edge cases, but it seems to be working well. Note though that it does not yet implement all more exotic CSS level 3 selectors.
Principal design: Parsing vs. Rendering and extensibility
If you have looked at the code, you might be asking why is the parsing and rendering code so complex. You could do this in a much simpler way. The first reason is performance consideration:
HtmlAgilityPack is quite fast - for normal sites and pages, render times are really OK, usually like dozens of milliseconds after the first JIT loads. But for big-load sites, and ones with large pages with a lot of replaces, this might be too much. So the idea is to separate the Bellevue rendering to two parts
Parsing would be the part where HtmlAgilityPack, CSS Parser and Fizzler do the heavy parsing with HTML and CSS DOMs and selectors. It positions the rule sets and directives all around the HTML, separates the templates etc. This logic should be independent from the ViewData which may be different on each call so that this work could be cached to be common for several page calls as parse result.
Rendering would then be done for each call and without having access to full HTML DOM. It takes the parse result and directly outputs HTML as is, and where there is active content, puts in the data. Currently the parse result is based on HTML DOM, and it is done every time, so there is no performance gain. But later versions, could implement a caching mechanism and e.g. put static HTML parts together as long strings the same way as Aspx compilation does. In extreme case it should even be possible to create ASPX from Bellevue views at parse time, but I am not sure whether it makes sense or not.
The second thing that adds a lot of complexity is the extensibility story. There is no extensibility API yet, but I am preparing for it. The idea is that you could add your own declaration handlers, renderers - even directives and formatters. This way, it should be possible to add your own view functionality like you can add Html helpers for Web Forms.
- March 18th: Added introduction articles here and in Codeproject.com
- March 17th: Updated intro documentation (links in the left navi), small updates to the downloads project
- March 16th: Added Downloadable project
- March 12th: Added Declarations, Relative Positioning and StringTemplate comparison.