Copied to clipboard

Flag this post as spam?

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


  • Greg McMullen 49 posts 195 karma points
    Jun 10, 2013 @ 21:55
    Greg McMullen
    0

    Accessing Descendant Node Property's

    I am having a heck of a time converting to the syntax used in Umbraco v6. Not sure if it's been too long since workign with the backend.

    I'm trying to create a slideshow using 4 different document types. Slider (with slider options), image, text and video. Each with their respective content elements.

    However, I cannot figure out how to actually access the data from these items.

    I have two Partial Views (not even sure if this is where I should be doing it, willing to change w/advice). One (should) load the necessary scripts and call bxSlider if the Slider child exists, not setup that way yet.

    The other is where the content should live, whether it's from the content picker, iframe code for the video or just text. I can figure out that logic later.

    What I need help with is how to traverse the tree with either the new syntax. I've tried @CurrentPage with no luck. Model.Content.Name will reveal "Home" but I cannot traverse anywhere down the tree, nor grab any content from a child page.

    This is a local demo site that I'm building in. Umbraco v6.0.5 using WebMatrix and MVC rendering engine.

    Code Snippets:

    Displays the Slideshow, should include logic regarding if TYPE show PROPERTIES

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>
    <div class="container slider">
        <div class="row">
            <div class="small-12 columns">
                <ul class="bxslider">
                    <li><img src="http://placehold.it/1000x350&text=Image One" title="Caption" /></li>
                    <li><img src="http://placehold.it/1000x350&text=Image Two" title="Caption" /></li>
    <li><img src="http://placehold.it/1000x350&text=Image Three" title="Caption" /></li> </ul> </div> </div> </div><!-- /slider -->
    @inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>
    @{
        var root = Model.Content;
        var slidePage = root.Descendants("Slider");
    
        if(slidePage.Children.Count() > 0)
        {
            <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
            <script src="/scripts/Slider/jquery.bxslider.js"></script>
            <link rel="stylesheet" href="/css/jquery.bxslider.css" />
            <script>
                $(document).ready(function(){
                    $('.bxslider').bxSlider({
                        mode:'fade' // Get values from Slider docType
                    });
                });
            </script>
        }
    }
    
  • Alex Skrypnyk 6133 posts 23952 karma points MVP 7x admin c-trib
    Jun 10, 2013 @ 22:44
    Alex Skrypnyk
    1

    We have a similar problem, it's really not clear how to work with Model and Descendant.

  • Greg McMullen 49 posts 195 karma points
    Jun 10, 2013 @ 22:48
    Greg McMullen
    0

    Agreed! I just wish that documentation would have come through just like the DynamicNodeContext cheat sheet.

  • Greg McMullen 49 posts 195 karma points
    Jun 21, 2013 @ 17:37
    Greg McMullen
    0

    Anyone? Any help or advice out there?

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 22, 2013 @ 11:21
    Jeavon Leopold
    102

    Hey there,

    You should able to use the Descendants method in exactly the same way as you could with DynamicNode, have you found something that doesn't work?

    Anyway, the thing to remember about the .Descendants method is that it will return all items in a flat collection that are descendants, this means you can't really traverse the tree although there are "Is helpers" that be used e.g item.IsAncestor.

    Anyhow, Looking at your sample and assuming that there are no other documents of type Slider in your tree that you don't want in this collection, then this should work:

         var slidePage = Model.AncestorOrSelf(1).Descendants("Slider");
        foreach (var slider in slidePage)
        {
            <p>@slider.GetPropertyValue("myProperty")</p>
        }

    But you will need be passing IPublishedContent when you render your Partial from you View, e.g.

     @Html.Partial("Slider",Model.Content)

    In case you do want to traverse down the tree, below is how I would do it (for a basic nav) by using a Razor helper in a partial view:

     @inherits Umbraco.Web.Mvc.UmbracoViewPage<IPublishedContent>
    
    @helper Traverse(IPublishedContent parent){ 
        <ul>
            @foreach (var page in parent.Children.Where(x => x.IsVisible()).OrderBy(x => x.SortOrder)){
                <li><a href="@page.Url">@page.Name</a>
                @if (page.Children.Any()){
                    @Traverse(page);   
                }               
                </li>         
            }
        </ul>    
    }
    @{        
        var homePage = Model.AncestorOrSelf(1);
        <ul>        
            <li><a href="@homePage.Url">@homePage.Name</a></li>
            @foreach (var page in homePage.Children.Where(x => x.IsVisible()).OrderBy(x => x.SortOrder))
            {
                <li><a href="@page.Url">@page.Name</a>
                @if (page.Children.Any()){                
                    @Traverse(page)                
                }
                </li>
            }
        </ul>     
    }

     Hope that helps you?

    Thanks,

    Jeavon

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 22, 2013 @ 14:30
    Craig100
    0

    Hi,

    I'm having similar issues. I have a Home node with a site beneath, and a parallel Settings node.  I'm trying to output items in the Settings node in a partial view in the Home node's base page. It's actually footer information.  I can access it in the base page with @Html.Raw(Umbraco.Content(1053).googleAnalyticsCode) for instance, but can't in the partial, I can't get the syntax at all and Intellisense isn't helping much.

    The base page calls the partial with @Html.Partial("Footer") and the footer partial view code is currently (there have been MANY iterations):-

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<dynamic>
            <div class="row-fluid">
                <div class="span12">
                    <footer class="muted">
                        <p>@Model.Content(1053).footerText</p>
                        <p class="text-center">Some text</p>
                        <p class="text-center">&copy; Copyright 2013 Some company. All rights reserved.</p>
                    </footer>
                </div>
            </div>

    This particular iteration gives the error: 'Umbraco.Web.Models.PublishedContentBase' does not contain a definition for 'Content' 

    Any advice would be appreciated.

    Cheers,

    Craig

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 22, 2013 @ 14:34
    Craig100
    0

    Why does it always happen this way?

    Once I put the question up I stumbled on the answer. Change @Model.Content(1053).footerText to @Umbraco.Content(1053).footerText.

    Though if there's a better way of accessing the Settings node without using the NodeID I'd love to hear it.

    Cheers,

    Craig

     

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 22, 2013 @ 23:28
    Jeavon Leopold
    0

    Hey Craig,

    Maybe something like get a sibling of your homepage by a certain document type:

     Model.AncestorOrSelf(1).Sibling("SettingsDocType").GetPropertyValue("footerText")

     But you will need to strongly type your partial (i'm not sure how to do it with dynamics), change your inherits to:

     @inherits Umbraco.Web.Mvc.UmbracoViewPage<IPublishedContent>

    Thanks,

    Jeavon

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 22, 2013 @ 23:33
    Jeavon Leopold
    0

    Forgot to add that then you need to pass the the model to the partial, e.g.

     @Html.Partial("Footer",Model.Content) 
  • Craig100 1136 posts 2523 karma points c-trib
    Jun 23, 2013 @ 10:47
    Craig100
    0

    Tried it but got 'Umbraco.Web.Models.PublishedContentBase' does not contain a definition for 'AncestorOrSelf', changed to AncestorsOrSelf, then there's no Sibling. changed to Siblings then got "No overload for method 'Siblings' takes 1 arguments". So reverting back to nodeID for now.

    Cheers,

    Craig

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 23, 2013 @ 11:22
    Jeavon Leopold
    0

    Hi Craig,

    I'm pretty sure you are getting that error because you are not passing IPublishedContent as the model to the partial. Can you check the below?

    Inherits on your partial is like this:

      @inherits Umbraco.Web.Mvc.UmbracoViewPage<IPublishedContent>

    and when you render the partial from your view it is like this:

     @Html.Partial("Footer",Model.Content)

    Cheers,

    Jeavon

  • Craig100 1136 posts 2523 karma points c-trib
    Jun 23, 2013 @ 11:56
    Craig100
    0

    That's totally weird. Reset it all and now it works. Must have been an unspotted typo as I had set up all the bits you mentioned initially. C'est la vie.

    This is really useful as I've always been unhappy using nodeID's as they can change.

    Thanks,

    Craig

  • Greg McMullen 49 posts 195 karma points
    Jun 24, 2013 @ 17:38
    Greg McMullen
    1

    While I haven't implemented the slideshow in my dev, I have been able to figure out some other hangups with your code. Thanks Jeavon!

  • Greg McMullen 49 posts 195 karma points
    Jun 26, 2013 @ 21:31
    Greg McMullen
    0

    I am still having issues with this. I'm not sure what I'm doing wrong. I've tried to follow the logic of your navigation but I get errors stating "Using a method.." or "this method does not exist in..."

    If I use the code in block 1, I can get a list of all items. But if I use the latter block of code, which should render all nodes under "Slider" I only get HomePage and Slider. Any thoughts?

    Block 1 - Outputs Homepage / Slider

    foreach (var item in Model.DescendantsOrSelf("Slider")){
    @item.Name
    }

    Block 2 - Outputs Homepage / Slider / Image 1 / Image 2 / Video 1

    foreach (var item in Model.DescendantsOrSelf(0)){
    @item.Name
    }

    Obviously what I want is to pull the properties from the respective children of "Slider." But at this point, I'd be happy just getting them to show up in the count of items.

    Thanks in advance.

  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 26, 2013 @ 21:55
    Jeavon Leopold
    0

    Hi Greg, I think you are talking about something like

    foreach(var item in Model.DescendantsOrSelf("Slider").First().Children){
    @item.Name
    }

    I've not been able to test this as I'm currently mobile but i think its correct, let me know.

    Jeavon

  • Greg McMullen 49 posts 195 karma points
    Jun 27, 2013 @ 16:09
    Greg McMullen
    0

    Awesome. Thank you Jeavon! I've finally got the d@mn thing working the way it was intended to! It's a complete mess from a code perspective and I plan to remove myself from it for a few days and then tackle the clean-up process. But it works, at least in my dev site!

    Thanks for all of the help and snippets!

    "Final" Code:

    @inherits Umbraco.Web.Mvc.UmbracoViewPage<IPublishedContent>
    <div class="row slideshow">
         <div class="small-12 columns">
              <div class="bxslider"><!-- I am here to contain the entire slider -->
    @helper MediaImage(IPublishedContent mediaImage){
         var imageUrl = mediaImage.GetPropertyValue("umbracoFile").ToString();
         @imageUrl
         }
    @{
    var slider = Model.AncestorsOrSelf(1);
    var i = 0;
    foreach (var item in Model.DescendantsOrSelf("Slider").First().Children.Where(x=>x.IsVisible())){
                   <div class="slider-item">
                        <div class="image">
                        @if (item.HasValue("videoEmbedCode")) {
                             <a href="#video-@i" title="Video: @item.GetProperty("slideTitle").Value" rel="modal"><img src="@MediaImage(Umbraco.TypedMedia(item.GetPropertyValue("slideImage")))" alt="@Umbraco.TypedMedia(item.GetPropertyValue("slideImage")).Name" title="Video For: @item.GetProperty("slideTitle").Value" /></a>
                        } else if (item.HasValue("slideLink")) {
                             <a href="@item.GetProperty("slideLink").Value" title="Full Story: @item.GetProperty("slideTitle").Value"><img src="@MediaImage(Umbraco.TypedMedia(item.GetPropertyValue("slideImage")))" alt="@Umbraco.TypedMedia(item.GetPropertyValue("slideImage")).Name" title="@item.GetProperty("slideTitle").Value" /></a>
                        } else {
                             <img src="@MediaImage(Umbraco.TypedMedia(item.GetPropertyValue("slideImage")))" alt="@Umbraco.TypedMedia(item.GetPropertyValue("slideImage")).Name" title="@item.GetProperty("slideTitle").Value" />
                        }
                        </div>
                        <div class="caption">
                        @if(item.HasValue("videoEmbedCode")) {
                             <h2><a href="#video-@i" rel="modal" title="Video: @item.GetProperty("slideTitle").Value">@item.GetProperty("slideTitle").Value</a></h2>
                        } else if (item.HasValue("slideLink")) {
                             <h2><a href="@item.GetProperty("slideLink").Value" title="Full Story: @item.GetProperty("slideTitle").Value">@item.GetProperty("slideTitle").Value</a></h2>
                        } else {
                             <h2>@item.GetProperty("slideTitle").Value</h2>
                        }
                        @if(item.HasValue("slideCaption")) {
         <p class="hide-for-small">@item.GetProperty("slideCaption").Value</p>
                        }
                        </div>
                   </div>
    i++;
    }
                   }
              </div><!-- slider container -->
              @{
                   var j=0;
                   foreach (var item in Model.DescendantsOrSelf("Slider").First().Children){
                        if(item.HasValue("videoEmbedCode")){
                        <div class="modal slideVideo" id="video-@j">
                             @Html.Raw(item.GetProperty("videoEmbedCode").Value)
                        </div>
                        }
                        j++;
                   }
              }
         </div><!-- 12 Columns on all devices-->
    </div><!-- Slideshow Row -->
  • Jeavon Leopold 3072 posts 13628 karma points MVP 10x admin c-trib
    Jun 27, 2013 @ 16:27
    Jeavon Leopold
    0

    Awesome, glad you're up and running! 

Please Sign in or register to post replies

Write your reply to:

Draft