Copied to clipboard

Flag this post as spam?

This post will be reported to the moderators as potential spam to be looked at


  • webmonger 130 posts 285 karma points
    Nov 08, 2011 @ 15:20
    webmonger
    2

    uSiteBuilder and strongly-typed views with razor

    I was chatting with Lee on Friday about uSiteBuilder and I explained that I thought it was great.

    The one issue I had not overcome until now is strong typed razor views which adds intelesense to VS :))

    Anyway this is questions about how to do this as I have a solution but wanted to check if this was the best way to do it.

    First I tried to cast the @Model object to the type I wanted to use:

    var basicPageData = (BasicPage)@Model;

    This returned an error so I figured I would create a Cast method in the BasicPage DocumentType class to convert the @Model to a type

            public static BasicPage Cast(DynamicNode node)
    {
    BasicPage basicPage = new BasicPage();
    basicPage.PageTitle = ((dynamic)node).PageTitle;
    basicPage.SeoDescription = ((dynamic)node).SeoDescription;
    return basicPage;
    }

    This works great in Razor and I get intelesense and should alos be able to do lambda queries on the object with no magic strings :)

    var basicPageData = BasicPage.Cast(@Model);

    Anyone got any comments on this? Could I do it better convert is easier? Have I coded something thats already built in to uSiteBuilder or .net that I dont know about?

    I look forward to your comments

    Jon

  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Nov 10, 2011 @ 11:26
    Dave Woestenborghs
    0

    Hi Jon,

    You can also create a constructor on your documenttype class that has a dynamic node parameter.

    Dave

  • Rich Green 2246 posts 4008 karma points
    Nov 10, 2011 @ 11:29
    Rich Green
    0

    Hey Jon,

    Good to see you Friday :)

    I don't have the answer for you but very interesting that it would be possible to have intellisense on doc type properties.... 

    Rich

  • webmonger 130 posts 285 karma points
    Nov 10, 2011 @ 11:50
    webmonger
    1

    Hi Dave

    Yeah converting it to a constructor makse sense I've just changes it and it works great.

            public BasicPage(DynamicNode node)
            {
                PageTitle = ((dynamic)node).PageTitle;
                SeoDescription = ((dynamic)node).SeoDescription;
            }

    So thats simplified it I did however have to add an empty public constructor too though as I got build errors without it.

    It also simplifies the code in the razor to

    var basicPageData = new BasicPage(@Model);

    Which is nice.

    Rich, was great to see you again on Friday. Really hope this is helping and look forward to you input ;)

    Cheers

    Jon

     

  • webmonger 130 posts 285 karma points
    Nov 10, 2011 @ 12:00
    webmonger
    1

    I've made another change. The parameter node can be set to dynamic to save all the casting:

            public BasicPage(dynamic node)
    {
    PageTitle = node.PageTitle;
    SeoDescription = node.SeoDescription;
    }

    This looks nice a tidy now and if you have all the properties above or below in the code you know exactly what properties you're looking for.

    I was wondering about writing a T4 template to create this everytime the page was saved so as new properties are added they are automatically added to the Constructor. Anyone done anything like this before?


  • Dave Woestenborghs 3504 posts 12135 karma points MVP 9x admin c-trib
    Nov 10, 2011 @ 12:42
    Dave Woestenborghs
    0

    Maybe through reflection would be a solution. Have to try that later on.

  • webmonger 130 posts 285 karma points
    Nov 10, 2011 @ 12:46
    webmonger
    0

    Interesting, I was just thinking of using regular expressions or something like that on the text file. I'm not sure which would be quicker.

  • Vladan Ostojic 94 posts 210 karma points
    Nov 10, 2011 @ 17:33
    Vladan Ostojic
    0

    Hey guys, we found a nice way to support Razor in uSiteBuilder and offer stongly typed views with uSiteBuilder & Razor! Soon we'll post more details. I'm sure you'll like it and I hope that some of you guys will be able to do test before we officially release it!

  • webmonger 130 posts 285 karma points
    Nov 11, 2011 @ 15:17
    webmonger
    0

    OK so yesterday after my last post I wondered how difficult it would be to write a T4 template to do the coding for me to create the constructors. Here is the output, let me know what you think.

    <#@ template debug="false" hostspecific="True" language="C#" #>
    <#@ output extension=".template.cs" #>
    <#@ import namespace="System.IO" #>
    <#@ import namespace="System.Text.RegularExpressions" #>
    using System;
    using System.Collections.Generic;
    using umbraco.MacroEngines;
    using umbraco.interfaces;
    namespace Project.DocumentTypes
    {
    string classNamePattern = @"public partial class (\w+)";
    string propertyNamePattern = @"public string (\w+)";
    string inheritedNamePattern = @" : (\w+)";
    Regex classRgx = new Regex(classNamePattern);
    string absolutePath = Path.GetDirectoryName(Host.TemplateFile);
    string[] files = Directory.GetFiles(absolutePath, "*.cs");
    foreach (string file in files)
    {
    if (!file.Contains(".template."))
    {
    string contents = File.ReadAllText(file);
    MatchCollection classMatches = classRgx.Matches(contents);
    if (classMatches.Count > 0)
    {
    foreach (Match classMatch in classMatches)
    {
    //this.WriteLine(classMatch.Groups[1].Value);
    this.WriteLine("\t" + classMatch.Value);
    this.WriteLine("\t{");
    this.WriteLine("\t\tpublic " + classMatch.Groups[1].Value + "(dynamic node)");
    this.WriteLine("\t\t{");
    this.WriteLine("\t\t\t// Object Properties");
    Regex propertyRgx = new Regex(propertyNamePattern);
    MatchCollection propertyMatches = propertyRgx.Matches(contents);
    foreach (Match propertyMatch in propertyMatches)
    {
    this.WriteLine("\t\t\t" + propertyMatch.Groups[1].Value + " = node." + propertyMatch.Groups[1].Value + ".ToString();");
    }
    Regex inheritedRgx = new Regex(inheritedNamePattern);
    MatchCollection inheritedNameMatches = inheritedRgx.Matches(contents);
    if (inheritedNameMatches.Count == 1)
    {
    if (inheritedNameMatches[0].Groups[1].Value != "DocumentTypeBase")
    {
    this.WriteLine("\t\t\t// Inherited Properties");
    string inheritedContents = File.ReadAllText(absolutePath + "\\" + inheritedNameMatches[0].Groups[1].Value + ".cs");
    // regex for properties
    Regex inheritedPopertiesRgx = new Regex(propertyNamePattern);
    MatchCollection inheritedPropertyMatches = inheritedPopertiesRgx.Matches(inheritedContents);
    if (inheritedPropertyMatches.Count > 0)
    {
    foreach (Match propertyMatch in inheritedPropertyMatches)
    {
    this.WriteLine("\t\t\t" + propertyMatch.Groups[1].Value + " = node." + propertyMatch.Groups[1].Value + ".ToString();");
    }
    }
    }
    }
    this.WriteLine("\t\t\t// Umbraco Properties");
    this.WriteLine("\t\t\tGetChildrenAsList = node.GetChildrenAsList;");
    this.WriteLine("\t\t\tParent = node.Parent;");
    this.WriteLine("\t\t\tId = node.Id;");
    //this.WriteLine("\t\t\tTemplate = node.Template;");
    this.WriteLine("\t\t\tSortOrder = node.SortOrder;");
    this.WriteLine("\t\t\tName = node.Name;");
    this.WriteLine("\t\t\tVisible = node.Visible;");
    this.WriteLine("\t\t\tUrl = node.Url;");
    this.WriteLine("\t\t\tUrlName = node.UrlName;");
    this.WriteLine("\t\t\tNodeTypeAlias = node.NodeTypeAlias;");
    this.WriteLine("\t\t\tWriterName = node.WriterName;");
    this.WriteLine("\t\t\tCreatorName = node.CreatorName;");
    this.WriteLine("\t\t\tWriterID = node.WriterID;");
    this.WriteLine("\t\t\tCreatorID = node.CreatorID;");
    this.WriteLine("\t\t\tPath = node.Path;");
    this.WriteLine("\t\t\tCreateDate = node.CreateDate;");
    this.WriteLine("\t\t\tUpdateDate = node.UpdateDate;");
    this.WriteLine("\t\t\tVersion = node.Version;");
    this.WriteLine("\t\t\tNiceUrl = node.NiceUrl;");
    this.WriteLine("\t\t\tLevel = node.Level;");
    this.WriteLine("\t\t\tPropertiesAsList = node.PropertiesAsList;");
    //this.WriteLine("\t\t\tChildrenAsList = node.ChildrenAsList;");

    this.WriteLine("\t\t}");
    this.WriteLine("\t\tpublic " + classMatch.Groups[1].Value + "(){}");

    this.WriteLine("\t\tpublic DynamicNodeList GetChildrenAsList { get; private set; }");
    this.WriteLine("\t\tpublic DynamicNode Parent { get; private set; }");
    this.WriteLine("\t\tpublic int Id { get; private set; }");
    this.WriteLine("\t\tpublic int Template { get; private set; }");
    this.WriteLine("\t\tpublic int SortOrder { get; private set; }");
    this.WriteLine("\t\tpublic string Name { get; private set; }");
    this.WriteLine("\t\tpublic bool Visible { get; private set; }");
    this.WriteLine("\t\tpublic string Url { get; private set; }");
    this.WriteLine("\t\tpublic string UrlName { get; private set; }");
    this.WriteLine("\t\tpublic string NodeTypeAlias { get; private set; }");
    this.WriteLine("\t\tpublic string WriterName { get; private set; }");
    this.WriteLine("\t\tpublic string CreatorName { get; private set; }");
    this.WriteLine("\t\tpublic int WriterID { get; private set; }");
    this.WriteLine("\t\tpublic int CreatorID { get; private set; }");
    this.WriteLine("\t\tpublic string Path { get; private set; }");
    this.WriteLine("\t\tpublic DateTime CreateDate { get; private set; }");
    this.WriteLine("\t\tpublic DateTime UpdateDate { get; private set; }");
    this.WriteLine("\t\tpublic Guid Version { get; private set; }");
    this.WriteLine("\t\tpublic string NiceUrl { get; private set; }");
    this.WriteLine("\t\tpublic int Level { get; private set; }");
    this.WriteLine("\t\tpublic List< IProperty > PropertiesAsList { get; private set; }");
    this.WriteLine("\t\tpublic List< INode > ChildrenAsList { get; private set; }");
    this.WriteLine("\t}");
    this.WriteLine("");
    }
    }
    }
    }
    #>
    }
  • Vladan Ostojic 94 posts 210 karma points
    Nov 11, 2011 @ 15:24
    Vladan Ostojic
    0

    I didn't see your original question before but you can consider the following (I assume that your BasePage is an uSiteBuilder document type):

    BasePage basePage = (BasePage)ContentHelper.GetByNodeId(@Node.Id);  

     

    (you can write this directly in your razor script).

     

    You can check out also other methods in ContentHelper.

  • Vladan Ostojic 94 posts 210 karma points
    Nov 11, 2011 @ 15:26
    Vladan Ostojic
    0

    So you can always get instance of an uSiteBuilder document type class if you know node id (of course, with all properties set with actual content).

  • webmonger 130 posts 285 karma points
    Nov 11, 2011 @ 15:32
    webmonger
    0

    Hi Vladan

    I'm just using the @Model object in Razor at the moment but I guess I could do as you say and do

    BasePage basePage = (BasePage)ContentHelper.GetByNodeId(@Model.Id);

    At the moment i have

    var basicPageData = new BasicPage(@Model);

    It works well and is much clearer for a developer to know what they are working with as there is no need for casting.

  • Vladan Ostojic 94 posts 210 karma points
    Nov 11, 2011 @ 15:39
    Vladan Ostojic
    0

    Yes you can use @Model.Id as well but I mentioned @Node because that's not dynamic property - you can access it as well and @Node has intellisense. Your solution with custom constructor works but you have to write constructor for each of your document types (and maintain it in the future). You will also lose possibility for using custom data types in properties (e.g. you can define a property in your document type as List<RelatedLink> MyLinks etc...).

     BTW, you can also use the following:

     

    BasePage basePage =ContentHelper.GetByNodeId<BasePage>(@Model.Id);

     

  • webmonger 130 posts 285 karma points
    Nov 11, 2011 @ 17:40
    webmonger
    0

    I may look in to implementing the generic lists in to the T4 template as I'm aware it's quite harsh limiting everything to a string.

  • mayur rathi 2 posts 22 karma points
    Feb 27, 2012 @ 14:33
    mayur rathi
    0

    can we create the strongly typed views as those in mvc

    If no then can anyone tell the steps to create the strongly typed views in umbraco 5

Please Sign in or register to post replies

Write your reply to:

Draft