Copied to clipboard

Flag this post as spam?

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


  • Mark Johnston 59 posts 111 karma points
    May 17, 2011 @ 16:20
    Mark Johnston
    0

    Creating a fat footer navigation structure

    I am trying to create a fat footer structure and have tried to create it below. The demo that ships with 4.7.0 doesn't really great a good structure, and I can't use && to check for the two values when I am setting the items var, hence why the multiple "Where's".

    I believe the <ul>'s are the biggest issue as it creates empty <ul>'s under objects that have no children. Any pointers would be handy.

     

    p.p1 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.5px Consolas; background-color: #000000} p.p2 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.5px Consolas; background-color: #000000; min-height: 11.0px} p.p3 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.5px Consolas; color: #2d2cfa; background-color: #000000} p.p4 {margin: 0.0px 0.0px 0.0px 0.0px; font: 9.5px Consolas; color: #007613; background-color: #000000} span.s1 {background-color: #fcfc39} span.s2 {color: #34a2bb} span.s3 {color: #2d2cfa} span.s4 {color: #b51f20} span.s5 {color: #000000} span.s6 {color: #950607} span.s7 {color: #ff1314} span.s8 {color: #000000; background-color: #fcfc39}

    @inherits umbraco.MacroEngines.DynamicNodeContext

     

    @helper traverse(dynamic node){

     

      var maxLevelForSitemap = 3;

     

      var values = new Dictionary<string,object>();

      values.Add("maxLevelForSitemap", maxLevelForSitemap) ;

      var items = node.Children.Where("showInFatFooter == true", values).Where("Level <= maxLevelForSitemap", values);

     

     

      foreach (var item in items) {

     

        <li><a href="@item.Url">@item.Name</a>

          <!-- How Do I make this following <ul> only write out and execute the helper if the current item has children? -->

          <ul>@traverse(item)</ul>

        </li>

      }

    }

     

    <nav id="FatFooter"> 

      <ul>

        <li><a href="@Model.AncestorOrSelf(-1).Url">@Model.AncestorOrSelf(-1).navigationTitle</a></li>

        <!-- I also cannot get the traverse helper to start at the site root level by using @Model.AncestorOrSelf(-1) below hence why I had to create the node outside the helper directly above -->

        @traverse(@Model.AncestorOrSelf())

      </ul>

    </nav>

  • Mark Johnston 59 posts 111 karma points
    May 17, 2011 @ 17:11
    Mark Johnston
    0

    Sorry for the poor formating, it appears I can't just drop code blocks in. Hope you all understand as it is failing when I go to edit it now too. :(

  • Robert Foster 459 posts 1820 karma points MVP 3x admin c-trib
    May 17, 2011 @ 18:09
    Robert Foster
    0

    Hi Mark:

    <!-- How Do I make this following <ul> only write out and execute the helper if the current item has children? -->

    - Put an if statement around it:

    if (item.Children.Count() > 0) { // Or something like that - just off the top of my head ;)
    <ul>@traverse(item)</ul> }

    <!-- I also cannot get the traverse helper to start at the site root level by using @Model.AncestorOrSelf(-1) below hence why I had to create the node outside the helper directly above -->

    - You're quite right - code is written assuming that your content pages start at level 2.  However, instead of

    @Model.AncestorOrSelf(-1)

    You should use

    @Model.AncestorOrSelf()

    As it returns the top level ancestor of the current node.  (Equivalent to passing 1 in as the parameter)

    "and I can't use && to check for the two values when I am setting the items var, hence why the multiple "Where's"

    - Theoretically, you should be able to write the code like this:

    var values = new Dictionary<string,object>();
    values.Add("maxLevelForSitemap", maxLevelForSitemap) ; var items = node.Children.Where("showInFatFooter == true && Level <= maxLevelForSitemap", values);

      However there's an issue with the implementation for 4.7, which has been apparently marked for resolution.  So for now you're stuck with chaining the two Where() conditions.

    Hope this helps,

    Rob.

  • Mark Johnston 59 posts 111 karma points
    May 17, 2011 @ 18:36
    Mark Johnston
    0

    Hi Rob, the if statement works well and has made my HTML a lot cleaner, thanx for that.

    I also tried:

    @Model.AncestorOrSelf()

    But it failed to travers up to the root of the site, maybe a bug?I understand the Razor gear is pretty new.

    And yeah it seems that the last issue is a bug in 4.7.0. I wonder how far away 4.7.1 is?

     

  • Robert Foster 459 posts 1820 karma points MVP 3x admin c-trib
    May 17, 2011 @ 18:56
    Robert Foster
    0

    @Model.AncestorOrSelf() will get the very first Ancestor of the current content node (@Model represents the current page/node in the site) - however, if you have other content at the same level as the first content page, then they won't be found by this script.  Generally, when I put a site together, I have one content node as the root of my site and put everything else below that.  That way all content has a common ancestor at the root of the site.

    Hopefully I'm making myself clear...

  • Mark Johnston 59 posts 111 karma points
    May 17, 2011 @ 18:59
    Mark Johnston
    0

    I have mine setup the same way but it still fails to go to the root. Maybe just verify with my Razor code?

  • Robert Foster 459 posts 1820 karma points MVP 3x admin c-trib
    May 17, 2011 @ 19:01
    Robert Foster
    0

    Post your updated code?  Tip: To have it formatted, change "Paragraph" to "Code" in the dropdown on the editor toolbar...

  • Mark Johnston 59 posts 111 karma points
    May 18, 2011 @ 00:11
    Mark Johnston
    0
      var maxLevelForSitemap = 3;
    
      var values = new Dictionary<string,object>();
      values.Add("maxLevelForSitemap", maxLevelForSitemap) ;
      var items = node.Children.Where("showInFatFooter == true", values).Where("Level <= maxLevelForSitemap", values);
    
    
      foreach (var item in items) {
    
        <li><a href="@item.Url">@item.Name</a>
          @if(item.Children.Count() > 0) {
          <ul>@traverse(item)</ul>
          }
        </li>
      }
    }
    
    <nav id="FatFooter"> 
      <ul>
        <li><a href="@Model.AncestorOrSelf(-1).Url">@Model.AncestorOrSelf(-1).navigationTitle</a></li>
        @traverse(@Model.AncestorOrSelf())
      </ul>
    </nav>
    
    
  • Robert Foster 459 posts 1820 karma points MVP 3x admin c-trib
    May 18, 2011 @ 05:17
    Robert Foster
    0

    Hi Mark,

    just on the first Where condition, you don't need the values parameter - it's optional, and doesn't match anything in the condition at all:

     

    var items = node.Children.Where("showInFatFooter == true").Where("Level <= maxLevelForSitemap", values);

    just makes it a little cleaner is all

    now, with the ancestorOrSelf issue: when I do

    <li><a href="@Model.AncestorOrSelf().Url">@Model.AncestorOrSelf().Name</a></li>

    I get the following (@Model.AncestorOrSelf().Name returns the Title of the page):

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

    which is what I expect - if I put -1 in as the parameter for AncestorOrSelf() I get the following error:

    Error loading Razor Script SiteMap.cshtml
    Cannot perform runtime binding on a null reference

    which is what I would expect.  -1 is not a supported ancestor level.

Please Sign in or register to post replies

Write your reply to:

Draft