Copied to clipboard

Flag this post as spam?

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


  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 23, 2012 @ 18:08
    Matt Bliss
    0

    Best way of including data from a settings node?

    I have a simple site with a "settings" node under the root (home page) node. The settings doc type will have properties that will be needed on every other page of the site (and therefore every other doc type's masterpage).

    What would be the best way of accessing this data within my masterpages for all other doctypes using the uSiteBuilder approach?

    I thought first of all of creating usercontrols that can be included in any masterpage where the usercontrol uses the umbraco Node class to find the settings node and then fill in values accordingly. But if multiple usercontrols are included in a single masterpage then the process of finding the settings node is repeated multiple times and this would be inefficient.

    Maybe I'm missing the obvious or have not adjusted my mindset correctly to the uSiteBuilder approach, so I am interested to hear how others go about this.

    Thanks,
    Matt

  • Richard Terris 273 posts 715 karma points
    Apr 23, 2012 @ 20:35
    Richard Terris
    0

    Hi mate

    I think you're on the right track with your thinking. I'm no expert but the way I tend to do it is have a SiteSettings.cs document type which contains the properties that are to be on the home page, and then have a GeneralPage.cs document type which caters for the main internal pages.

    The GeneralPage.cs does NOT inherit from the SiteSettings.cs file (SiteSettings could be called HomePage.cs)

    Within my General.master I have a SiteHeader.ascx user control which contains all of the references to css files and js files. There is a PageHeader.ascx file which generally contains top menu.

    I then build user controls for elements such as footer, calls to action etc.

    After this, if I have a requirement for another template, I have a nested masterpage, inheriting from General.master which means that everything in the General.master will be included on my new template, including all server controls, but only need to be called once.

    Another useful tip is to say use the same codebehind in user control to do different things, depending which page.

    So for example you have a menu on "About.aspx" and on "Qualifications.aspx" you have the the same menu, but with a further dropdown menu, I'd use the same pages and controls, and in the code say if(currentPage.name == "Qualifications") { and build the additional menu in here}

    This saves from having to build a new user control just for the sake of that one additional menu.

    Hope this helps, but feel free to come back to me if you don't think it will and I'll be glad to help where I can - You can catch me anytime on Twitter.

  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 25, 2012 @ 13:46
    Matt Bliss
    0

    Thanks Richard,

    You have raised some interesting points there that are in many ways similar to the approach I have been taking. With regard to getting Settings node content in any page / User control I have come up with the following approach:

    I have a standard settings class based on uSiteBuilder:

    namespace MyProject.DocumentTypes
    {
        [DocumentType(Name = "Settings",
            IconUrl = "cog.png"]
        public class Settings : Vega.USiteBuilder.DocumentTypeBase
        {

    ...

        }
    }

    I then have a Settings helper class:

    using Vega.USiteBuilder;
    using uComponents.Core;

    namespace MyProject.Helpers
    {
        public static class Settings
        {
            private static int _settingsNodeID;

            static Settings()
            {
                _settingsNodeID = 0;
                foreach (DocumentTypeBase child in ContentHelper.GetChildren(uQuery.GetRootNode().Id,true))
                {
                    if (child.NodeTypeAlias == "Settings")
                    {
                        _settingsNodeID = child.Id;
                        break;
                    }
                }
            }

            public static bool Located
            {
                get { return _settingsNodeID != 0; }
            }

            public static DocumentTypes.Settings Content
            {
                get 
                {
                    if (_settingsNodeID != 0)
                        return (DocumentTypes.Settings)ContentHelper.GetByNodeId(_settingsNodeID);
                    else
                        return new DocumentTypes.Settings();
                }
            }
        }
    }

     

    I can then get any value from the Settings node using the following syntax:

    value = Helpers.Settings.Content.propertyName;

    I've yet to check perfomance with this approach but it is working well in a simple test.

    Once again any comments welcome.

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 13:59
    Richard Terris
    0

    Hi Matthew

    Sounds like we're talking about pretty much the same thing.

    I'd be interested to see what the difference in page loads would be compared to my way.

    The only thing I'd say is that this way is always going to return an object of DocumentTypeBase, so how would you deal with pages that have a different document type? Would you require another helper file, or another method within that helper file? With the above you would likely get an error if the nodes you're trying to access are of a different document type.

    This is why I tend to separate these out into codebehind in the user controls, but your way may well turn out to be better - like I said, I'd be interested to see.

    Let me know how you get on please.

  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 25, 2012 @ 14:24
    Matt Bliss
    0

    Hi Richard,

    I would only take this approach for document types that should only have a single instance like the settings node. (If the user creates more than one then the first match will be used)

    The 'Content' function within the helper returns my specific settings document type by casting the DocumentTypeBase object returned by ContentHelper.GetByNodeId function. The helper class knows that it is the correct type to support the casting beacuse it has already macthed the doctype Alias. You are right though that this means if I wanted to repeat this process for another doctype then another helper class would be needed, but I think for me this would be infrequent so I'm happy with that.

    The advantage to me is that I only need a single line of code in my usercontrols codebehind to grab a settings node value.

    Hopefully I've minimised the peformance hit by putting the node search logic in a static class static constuctor so it only happens once with the first request (again this would not work so well if I thought the location of the settings node might change between calls to the 'Content' method, but in this case once the node is there it will probably never be deleted or a new one be created, so this should be safe too)

    Feel free to grab the code an compare performance, it would be interesting to see a comparison.

     

     

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 14:32
    Richard Terris
    0

    I may well take a look at this in one of my freelance apps, just to see if there's a benefit.

    I still think though with regards to reusing elements, it's easier to use nested master pages and user controls; All content nodes using that template will automatically have all of these elements included without having to repeat calls (even if it is just one line of code) to have them included on the page.

    Of course if you have a new page which has elements which appear only on that page, AND had the elements from another template, then a new template created as a nested masterpage will again mean not having to repeat any code, just the new code for those elements not appearing elsewhere.

    You might be making it more complicated than it needs to be :) But I am definitely interested in seeing if the performance improves.

  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 25, 2012 @ 15:00
    Matt Bliss
    0

    Hi Richard,

    It sounds like either I am missing something obvious here (quite possible and the reason why I posted in the first place!) or perhaps we are talking at cross purposes. Perhaps I could use a simple example:

    • In the content there is a page of the "Settings" doc type immediately below the Home Page node.
    • In the settings doc type there is a property that holds the Google Analystics code ie "UA-XXXXX-X"
    • In the main masterpage (ie on every page on the site) we want to include the Google Analytics script block with the GA code if the field has been populated.
    At the moment I have a UserControl which is included in the main masterpage the usercontrol uses the classes above to grab the data needed to output the GA script block. Are we talking about he same thing? How would I remove the need to identify the settings node in my code by nesting masterpages?
    Many thanks,
    Matt

     

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 15:06
    Richard Terris
    0

    Ah I see,

    Ok well what I do there is have GoogleAC as a textString property in siteSettings.cs doctype.

    In the siteHeader.ascx control I have links to stylesheets etc, and in the codbehind I get the actual analytics code from the GoogleAC property

    this way, whenever siteHeader is used, it looks up that property and displays the code on every page it's on

    does that make sense?

  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 25, 2012 @ 15:45
    Matt Bliss
    0

    It does make sense and it sounds like we are doing exactly the same thing, but probably just using different methods to get the value from the property from the settings node in code behind for our controls.

    Out of interest how do you grab values from your settings node in code behind?

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 15:54
    Richard Terris
    0

    Int32 RootNode = Convert.ToInt32(ConfigurationManager.AppSettings["Root"]);

    Node RootPage = new Node(RootNode);

    String TitleText = String.Empty;

    TitleText = RootPage.GetProperty("siteName").Value.ToString();

    Have to register "Root" inin web.config like;

    where 1059 is the rood node ID

    Hope this makes sense also - It's always good to see how other people do things, even if it just tells you there's nothing wrong with how you do it :)

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 15:56
    Richard Terris
    0

    Sorry, I don't know how to add code snippets on this forum :(

  • Matt Bliss 176 posts 234 karma points c-trib
    Apr 25, 2012 @ 16:35
    Matt Bliss
    0

    Thanks Richard,

    We are doing something very similar just using a different route to the data at the point that we reach the code behind stage.

    In your example you use the Umbraco NodeFactory classes to get your values (and this is what I've always done before using uSiteBuilder). In my example I am using the document class I created derived from the uSiteBuilder Template Base.

    Unless I find a performance issue I think I'll stick to the approach I've found because

    1) I can have the editor prompt me with the property names for my doc type, which is good for me because my memory is poor. If I change the doc type through code then new fields will alway be in the list when I want to grab them in codebehind.

     

    2) I can specify a doctype alias in my code rather than a node IDs in the config. The node Id could be different in development to the live site, but aliases will always match. Also it makes it easier to port the code from project to project.

    Oh yes: To add a code snipet to the forum change the 'Paragraph' in the styles to 'Preformatted' and use Shift+Return to stop lines breaking up (a bit of pain actually!)

    Thanks for your comments they have been helpful as I've been feeling my way through this test code and evaluating uSiteBuilder over using the Umbraco UI for doctypes and templates and macros.

    Thanks again,
    Matt

  • Richard Terris 273 posts 715 karma points
    Apr 25, 2012 @ 16:40
    Richard Terris
    0

    No worries, so long as it works :)

    and thanks for teh tip about Preformatted - I've seen forums that actually have a button to "insert code snippet", thought maybe I'd missed something

    Of course, all of this changes when we move to Umbraco 5 :D

    Richard

Please Sign in or register to post replies

Write your reply to:

Draft