Click here to Skip to main content
15,881,281 members
Articles / Web Development / ASP.NET

Introduction to Bellevue View Engine - Part 1

Rate me:
Please Sign up or sign in to vote.
3.43/5 (4 votes)
18 Mar 2010CPOL8 min read 26K   126   10  
Prototype of a new template engine for ASP.NET MVC Framework that respects HTML and uses CSS-like syntax for model binding.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Ope.Bellevue.Rendering;

namespace Ope.Bellevue.Renderers.General
{
    public class Text : INodeRenderer, IAttributeRenderer
    {
        public void RenderNode(RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            string text = data.GetValue(parameters["value"]);
            if (parameters["noEncoding"] == null || parameters["noEncoding"].Value != "true")
            {
                text = System.Web.HttpUtility.HtmlEncode(text);
            }
            renderContext.Write(text);
        }

        public void RenderAttribute(string attributeName, RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            // TODO: Think which one to use: the one from RenderAttribute method or from parameters.
            string attrName = data.GetValue(parameters["attr-name"]);
            string newText = data.GetValue(parameters["value"]);
            string text = data.GetValue(parameters["original-value"]);

            switch (parameters.Position)
            {
                case RelativePosition.ReplaceOuter:
                    renderContext.Output.Write(newText);
                    return;
                case RelativePosition.Append:
                    text += newText;
                    break;
                case RelativePosition.Insert:
                    text = newText + text;
                    break;
                case RelativePosition.InsertBefore:
                    renderContext.Output.Write(newText);
                    break;
                case RelativePosition.Default:
                case RelativePosition.ReplaceInner:
                    text = newText;
                    break;
            }
            
            renderContext.RenderAttr(attributeName, text);

            if (parameters.Position == RelativePosition.InsertAfter)
            {
                renderContext.Output.Write(newText);
            }
        }
    }

    public class TextFormat : INodeRenderer
    {
        public void RenderNode(RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            object valueToFormat = data.GetObject(parameters["value"]);
            string formatString = parameters["format-text"].Value;
            string text = System.Web.HttpUtility.HtmlEncode(string.Format(formatString, valueToFormat));
            renderContext.Write(text);
        }
    }

    public class TextReplace : INodeRenderer
    {
        public void RenderNode(RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            string newText = data.GetValue(parameters["value"]);
            string replaceText = data.GetValue(parameters["replace-text"]);
            string originalText = parameters["original-text"].Value;
            string text = System.Web.HttpUtility.HtmlEncode(originalText.Replace(replaceText, newText));
            renderContext.Write(text);
        }
    }

    public class Checked : IAttributeRenderer 
    {
        public void RenderAttribute(string attributeName, RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            if (data.GetBool(parameters["value"]))
            {
                renderContext.RenderAttr(attributeName, "checked");
            }
        }
    }

    public class ApplyTemplate : INodeRenderer
    {
        public void RenderNode(RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            var templateContainer = renderContext.Templates.GetTemplate(data.GetValue(parameters["template-id"]));
            if (templateContainer == null)
            {
                return;
            }
            var collection = data.GetEnumerable(parameters["value"]);
            if (collection == null)
            {
                // TODO: Is this an error or not? Warning?
                return;
            }

            var itemEnumerator = collection.GetEnumerator();
            int counter = -1;
            bool quit = false;
            while (!quit)
            {
                foreach (var templateElem in templateContainer)
                {
                    if (!itemEnumerator.MoveNext())
                    {
                        quit = true;
                        break;
                    }
                    counter++;
                    HtmlRenderer.RenderNode(templateElem, data.GetItemContext(itemEnumerator.Current, counter), renderContext);
                }
            }
        }
    }

    public class RenderControl : INodeRenderer
    {
        public void RenderNode(RenderingInstruction parameters, DataContext data, ViewRenderingContext renderContext)
        {
            string partialViewName = data.GetValue(parameters["value"]);

            System.Web.Mvc.ViewEngineResult result = System.Web.Mvc.ViewEngines.Engines.FindPartialView(renderContext.MvcViewContext, partialViewName);
            if (result.View == null)
            {
                StringBuilder locationsText = new StringBuilder();
                foreach (string location in result.SearchedLocations)
                {
                    locationsText.AppendLine();
                    locationsText.Append(location);
                }

                throw new InvalidOperationException(String.Format(
                    "The partial view '{0}' could not be found. The following locations were searched:{1}",
                    partialViewName, locationsText));
            }
            else
            {
                result.View.Render(renderContext.MvcViewContext, renderContext.Output);
            }
        }
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Founder OPE AG
Switzerland Switzerland
Olli is a .Net developer and architect.

He specializes in Asp.net MVC and other web technologies, XML and lately Domain Specific Languages.

Olli is originally from Finland, but currently works for his own one-man-initiative OPE AG (www.ope.ag) from Switzerland. He has over 10 years of experience as one of the founding partners and Chief Technology Officer of Quartal group of companies (www.quartal.com).

Comments and Discussions