Copied to clipboard

Flag this post as spam?

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


  • Daliz 4 posts 24 karma points
    Aug 25, 2011 @ 12:30
    Daliz
    0

    Root and menus

    Hi! I'm new to Umbraco and Razor engine. I'm just experimenting around and I'm positively impressed by what can be achieved using Razor scripts and macros.

    However, I'm having some difficulties. For example:

    When I create a new Razor Script directly from the Umbraco admin interface with the Select Children by Document Type - Dynamic Node template, the script doesn't work.

    It generates:

    @foreach (var item in @Model.ChildItem.Where("umbracoNaviHide != true"))
        {
        <li><href="@item.Url">@item.Name</a></li>
        }

    But I have to change @Model.ChildItem.Where... to @Model.Children.Where...

    Anyway, this is not a great problem.

    Now, I'm searching for a way to get the root element of my content because I want to create a dynamic menu for my web pages.

    With the previous script I can get all the children of a node. But I want to create a classic menu starting from "node 0", in order to get a classic Home, About, Products, Contacts menu.

    I hope I've been straightforward in my request. Thanks!


  • Barry Fogarty 493 posts 1129 karma points
    Aug 25, 2011 @ 14:12
    Barry Fogarty
    0

    Hi Daliz, try this:

    @{
      var startLevel = 1;
      var finishLevel = 2;  
      var parent = @Model.AncestorOrSelf(startLevel);
      if (parent != null) { @ulMenu(parent, startLevel, finishLevel) ; }
    }

    @helper ulMenu(dynamic parent, int startLevel, int finishLevel)
    {
     var count = 0;
     <ul>
        @foreach (var node in parent.Children.Where("Visible")) {
            if (node.template > 0 && node.HasAccess)
            { 
              <li>
                <a href="@node.Url">@node.Name</a>                                      
                @if (@node.Level <= finishLevel) { @ulMenu(node, startLevel, finishLevel); } 
              </li>
              count++;
            }
         }
     </ul>                                                           
    }

    This will create a 2-level dropdown menu from your root node.  The key is the AncestorOrSelf method - this can be used to tell Umbraco when to stop climbing the tree or can be used without a parameter to go from the root node:  AncestorOrSelf()

    If you do not want a nested dropdown but just a menu bar, remove the nested call to @ulMenu in between the <li>..</li>

  • Daliz 4 posts 24 karma points
    Aug 25, 2011 @ 14:53
    Daliz
    0

    Thank you, Barry (I named the Razor script "RazorBarry" in your honor ;-)).

    Anyway, with your script, I'm still getting only the children of the active page.

    I'd like to get, wherever I am, a menu with links to: Homepage, About Me.

    Instead, if I'm viewing Homepage, I'm getting the subpages of Homepage.

     

  • Barry Fogarty 493 posts 1129 karma points
    Aug 25, 2011 @ 15:04
    Barry Fogarty
    1

    Try to restructure you site and have a root node "Website" then put home, about us, and any other pages you want at the level.  Use the umbracoInternalRedirectId document type property on the website node to redirect into home.

    Or, perhaps easier - put all your top level pages within homepage and hard code a homepage link in the scriptas follows

    (just inside the <ul> tag before the for each loop)

    <li><a href=/">Home</a></li>

    if you are creating a dropdown menu you will need to ensure this only runs when the (@parent.Level == startLevel)

    e.g.

    if ((@parent.Level == startLevel)) {<li><a href=/">Home</a></li>}

     

  • Daliz 4 posts 24 karma points
    Aug 25, 2011 @ 15:16
    Daliz
    0

    Ok, that's good.

    What do you think of using the hard-coded page id?

    @{
        var node @Model.NodeById(1051);
    }

    @foreach (var item in @node.Children{
        <p><href="@item.Url">@item.Name</a></p>
    }

    I was thinking of this because I can't find this umbracoInternalRedirectId property.

  • Barry Fogarty 493 posts 1129 karma points
    Aug 25, 2011 @ 16:00
    Barry Fogarty
    0

    The thing is this.  You are looking to get a reference to the root node of your site (which in your case is Homepage') - and then your script terates over the children of that node.  So, in your structure, 'About Us' will never appear as it is not a child of your root node.

    Model.AncestorOrSelf();

    THe above code definitely will return the value of the Homepage node on your system.  But the rest of the code will only return the children of it.

    THis is why a lot of people use a "Site Settings" document type as their root node, then you can have Home and About Us etc at the same level.  If you create the document type with no template, the actual homepage of you site will be move to the next node down anyway so you dont have to worry about the umbracoInternalRedirectIdproperty.

    For your reference though, you create this property yourself (content picker datatype) and then Umbraco automatically routes through to the chosen page internally

  • Rich Green 2246 posts 4008 karma points
    Aug 25, 2011 @ 16:04
    Rich Green
    0

    As Barry advises, I would restructure your content tree like this:

     

    Content

    ----------- Homepage

    ---------------  About Us

    ---------------  Contact Us

    ---------------  etc.

    Rich

  • Daliz 4 posts 24 karma points
    Aug 27, 2011 @ 13:42
    Daliz
    0

    Ok. Thank you.

  • Barry Fogarty 493 posts 1129 karma points
    Aug 30, 2011 @ 13:39
    Barry Fogarty
    0

    Hi Daliz, dont forget to mark an answer as the solution!  (that way the solution providers get karma points)

Please Sign in or register to post replies

Write your reply to:

Draft