More in this section

Forums / Developing with Sitefinity / Razor Host Widget - Example Code

Razor Host Widget - Example Code

4 posts, 0 answered
  1. Jason Chester
    Jason Chester avatar
    11 posts
    Registered:
    03 Feb 2010
    04 Oct 2011
    Link to this post

    As an ASP.NET developer, I have come to appreciate the power and simplicity Razor templates give developers when creating web sites.

    Since Telerik does not currently support Razor as a templating engine, I decided to create a simple Razor Host Widget with a little help from the Razor Engine project from codeplex. http://razorengine.codeplex.com/

    Inheriting from ContentBlock i was able to leverage the builtin editor for managing the razor template and enable the control to parse and render the Razor syntax suprisingly few lines of code.By inheriting from ContentBlock, I can even share the Razor Template as a Content Block and reuse it accross multiple pages.

    Here is my quick proof of concept for a razor host widget.

    using System;
    using System.Text;
    using RazorEngine;
    using RazorEngine.Templating;
    using Telerik.Sitefinity.Modules.GenericContent.Web.UI;
    using Telerik.Sitefinity.Web.UI;
     
    namespace Rosetta.Sitefinity.Web.UI.RazorHost
    {
        public class RazorHostWidget : ContentBlock
        {
            protected override void InitializeControls(GenericContainer container)
            {
                base.InitializeControls(container);
                var template = this.ContentHtml.Text;
                string parsedText;
                try
                {
                    parsedText = Razor.Parse(template);
                }
                catch (TemplateCompilationException ex)
                {
                    var errorMessage = new StringBuilder(ex.ToString());
                    errorMessage.AppendLine();
                    errorMessage.AppendLine("<ul>");
                    foreach (var error in ex.Errors)
                    {
                        errorMessage.AppendLine("<li>");
                        errorMessage.AppendLine(error.ToString());
                        errorMessage.AppendLine("</li>");
                    }
                    errorMessage.AppendLine("</ul>");
                    parsedText = errorMessage.ToString();               
                }
                catch (Exception ex)
                {
                    parsedText = ex.ToString();
                }       
                this.ContentHtml.Text = parsedText;
            }
        }
    }

     

    As you can see, Most of the code is just plumbing and error handling.

    Once you register this control in the toolbox, you can use the Razor Host Widget to create some really powerful templates like this example which renders a random FAQ Item from a sitefinity list.

    @{
    var manager = Telerik.Sitefinity.Modules.Lists.ListsManager.GetManager();
    var items = from i in manager.GetListItems()
        where i.Parent.Title == "FAQ"
        && i.Status == Telerik.Sitefinity.GenericContent.Model.ContentLifecycleStatus.Live
        select i;
    var count = items.Count();
    var skip = new Random().Next(count);
    var item = items.Skip(skip).FirstOrDefault();
    }
    <div class="callout green">
        <h3>@item.Title</h3>
        <p>@item.Content</p>
    </div>

    There are a few issues with this implementation mainly around &'s and > being html encoded by the designer but it is a pretty simple to fix them in the HTML view before you save the Razor Template.

    I really think this is just scratching the surface and there are a lot of ways to make this even better. A few ideas i have had are:
      1. configuring namespaces in Razor Engine to make the code shorter by eliminating the fully qualified references for a lot of the code.
      2. Creating a base class for use in the template to enable Url and Html Helper extensions like MVC does.
      3. Adding Telerik helper methods in to the base class to grab the current page, or something.
      4. Fixing the editor to not encode &, > etc. in the razor code blocks. May be able to do this by adding a plain text area to the editior where you put your razor initialization code and then concatenating it with the Html view before parsing the template.
      5. Investigate the security implications of allowing content managers to write arbitrary code when content editing.

    Feel free to use this code as you will, just reply to this thread and let me know what you did with it. I would love to see more examples of razor code you used.

    Thanks,

    JASON CHESTER

    Technology Director
    629 Euclid Avenue / Cleveland, OH 44114
    E jason.chester@rosetta.com
    rosetta.com
    ROSETTA | Pilots, inventors and builders for a connected world.™

  2. Teodor
    Teodor avatar
    52 posts
    Registered:
    24 Sep 2012
    06 Oct 2011
    Link to this post
    Hi Jason Chester,

    I'm really happy to see that you've managed to achieve this. We were planing to introduce support for Razor engine at some point in Sitefinity but you've manage to do it before us. Congratulations.

    Greetings,
    Teodor
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  3. Georgi
    Georgi avatar
    3583 posts
    Registered:
    28 Oct 2016
    10 Oct 2011
    Link to this post
    Hi Jason Chester,

    We are also adding some points to your account for sharing the solution with us and the rest from the Sitefinity community.

    Keep up the good work.

    Greetings,
    Georgi
    the Telerik team
    Do you want to have your say in the Sitefinity development roadmap? Do you want to know when a feature you requested is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
  4. Lino
    Lino avatar
    45 posts
    Registered:
    06 May 2005
    10 Oct 2011
    Link to this post
    Thanks Jason,

    Great work!  Thanks for sharing!
    -Lino
4 posts, 0 answered