Copied to clipboard

Flag this post as spam?

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


  • Scott Robinson 54 posts 75 karma points
    Jun 28, 2013 @ 22:07
    Scott Robinson
    0

    Find nodes by doc type and list properties

    Hi,

    I'm new to Razor and and putting together a multi-language site from various snippets and trying to learn Razor along the way. I created a partial that looks for items select from a multi-page picker and the lists out the properties. the result is a list of office locations I can use across various language sites without duplication content. However this solution is not ideal as for each site I still need to "pick" the items to appear on the page.

    What I need is to find any nodes with a doctype of "location" and render it's properties. As this is multi-language the root is (-1) from wherever the search is happening. How would I do this in Razor??? The code I have to grab the properties is :

     

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

    @{

        Layout = null;

        var nodeIds = Model.GetPropertyValue<string>("globalLocations").Split(',');

        List<IPublishedContent> panels = new List<IPublishedContent>();

     

        foreach(var nodeId in nodeIds)

        {

            if(!String.IsNullOrEmpty(nodeId))

            {

                var publishedContent = Umbraco.NiceUrl(Convert.ToInt32(nodeId));

                if (!String.IsNullOrEmpty(publishedContent) && publishedContent!="#")

                {

                    panels.Add(Umbraco.TypedContent(nodeId));

                }

            }

        }

     

    }

    @if(panels.Count() > 0)

    {

    <ul class="large-block-grid-2 small-block-grid-2">

            @foreach (var panel in panels)

            {

     

    if (panel != null)

                {

                 <li>

    @if(panel.HasValue("locationImage")){

    var mediaItem = Umbraco.TypedMedia(panel.GetPropertyValue("locationImage"));  

      <img src="@mediaItem.GetPropertyValue("umbracoFile")" alt="@mediaItem.GetPropertyValue("Name")"/>

    }

    <h5 class="subheader">@Html.Raw(panel.GetPropertyValue<string>("locationCountry"))</h5>

      <h6>@Html.Raw(panel.GetPropertyValue<string>("locationAddress"))</h6>

      <h6>Visit the <a href="http://ebiquity-test.azurewebsites.net/@Html.Raw(panel.GetPropertyValue<string>("locationWebsite"))">local website</a></h6></li>

                }

            }

        </ul>

    }

     

    @{

    }

     

    Thanks for any help offered :)

     

    Soctt

  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Jun 28, 2013 @ 23:02
    Jeavon Leopold
    1

    Hi Scott,

    I'm not 100% clear on your content structure, could you confirm if this example is correct:

    HomeUS
      Page1
      Page2 (doctype location)
        SubPage1 (doctype location)
      Page3 (doctype location)
    HomeFR
      Page4
      Page5 (doctype location) 

    Asuuming it is and you are looking to select page2, subpage1 and page3 if rendering on any page in the HomeUS tree and page5 if in the HomeFR tree, then this should work:

    var locationNodes = Model.AncestorOrSelf(1).Descendants("location");

    If I've understood your structure wrong please let me know.

    Thanks,

    Jeavon

  • Rich Green 2246 posts 4008 karma points
    Jun 29, 2013 @ 09:26
    Rich Green
    0

    Might be best to post an screenshot of your content tree.

    Rich

  • Scott Robinson 54 posts 75 karma points
    Jun 29, 2013 @ 22:13
    Scott Robinson
    0

    Thanks for you replies. I  think my initial idea is too limiting. My structure is:

    Content
    - EN (doctype globalSite)
    -- Hompege
    --- Page

    - DE (doctype globalSite)
    -- Homepage
    --- Page

    - LocalOffices
    -- UK (doctype localSite)
    --- Homepage
    ---- Page
    -- DE (doctype localSite)
    --- Homepage
    ---- Page

    - Locations
    --Location

    Basically my instance has 2 separate types of site that need to share information. Global (also broken down by language, EN, DE etc), and Local (which are essentially microsites for local office information. These are broken down by country UK, DE etc).

    I though I would store address information in a separate folder so it can be access by a page within my global site (basically a list of all local head offices). However, I'm being a bit dim. It would make a lot more sense to store the information on the DocType "localSite" or have a location folder within each office. That way local offices can use:

    var locationNodes =Model.AncestorOrSelf(1).Descendants("location");

    and Global sites could use what???

    var locationNodes =Model.AncestorOrSelf(-1).Descendants("location");

    Would that work?

    Once I've found the nodes is it just a case of rendering out the properties?

     

  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Jul 02, 2013 @ 11:13
    Jeavon Leopold
    0

    Hi Scott,

    I have been thinking about this as I don't think it's quite as easy as perhaps it should be to find all descendants of all root nodes, this is what I have come up with so far:

     @{
        var allRootNodes = Umbraco.TypedContentAtRoot(); //returns collection of all root nodes
        IEnumerable<IPublishedContent> allDesc = Enumerable.Empty<IPublishedContent>();
    
        allDesc = allRootNodes.Aggregate(allDesc, (current, publishedContent) => current.Concat(publishedContent.Descendants("location")));
    
        foreach (var publishedContent in allDesc.OrderBy(x=>x.Level)) //order by whatever you like
        {
            <p>@publishedContent.Name</p>
        }   
    }

    If anyone has any other ideas I would love to see them

    Jeavon

  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Jul 04, 2013 @ 10:47
    Jeavon Leopold
    1

    Hi Scott,

    I have just discovered a new and awesome method on the Umbraco helper called TypedContentAtXPath which solves this issue as you can execute any Xpath expression on the entire tree

    e.g

    var locationNodes = Umbraco.TypedContentAtXPath("//location");

    Thanks,

    Jeavon

  • Scott Robinson 54 posts 75 karma points
    Jul 08, 2013 @ 10:55
    Scott Robinson
    0

    Thanks for the replies. I will investiagte and post result :)

  • Scott Robinson 54 posts 75 karma points
    Jul 24, 2013 @ 14:55
    Scott Robinson
    0

    Hi,

    Thanks for the feedback. How exactly would I implement XPath. I've tried the following but get an error:

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage
            @{
                var locations = Umbraco.TypedContentAtXPath("//Location");
            }
               
                @foreach (var location in locations) {
                                     
                <li>
                     @location.Name
                </li>
            }

  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Jul 24, 2013 @ 16:22
    Jeavon Leopold
    0

    Hi Scott,

    What error do you get? Just to confirm, are you using v6.1 or above? Additionally are you trying to select all documents of the document type "Location", check the casing of the alias in Umbraco also as it is sensitive.

    Thanks,

    Jeavon

  • Scott Robinson 54 posts 75 karma points
    Aug 02, 2013 @ 13:10
    Scott Robinson
    0

    Hi Jeavon,

    I'm using 6.0.6. Is that an issue?

    This is the error I'm getting:


    Compilation Error Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.

    Compiler Error Message: CS1061: 'Umbraco.Web.UmbracoHelper' does not contain a definition for 'TypedContentAtXPath' and no extension method 'TypedContentAtXPath' accepting a first argument of type 'Umbraco.Web.UmbracoHelper' could be found (are you missing a using directive or an assembly reference?)

    Source Error:

    Line 7: @{ Line 8: @var locations = Model.Content.AncestorOrSelf().Descendants("Location");@ Line 9: var locations = Umbraco.TypedContentAtXPath("//Location"); Line 10: @var locations = Umbraco.TypedContentAtXPath("//Location");@ Line 11: }


    The code I'm using:


    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage @{ Layout = "EBGlobalMaster.cshtml"; }

    @inherits Umbraco.Web.Mvc.UmbracoTemplatePage @{ @var locations = Model.Content.AncestorOrSelf().Descendants("Location");@ var locations = Umbraco.TypedContentAtXPath("//Location"); @var locations = Umbraco.TypedContentAtXPath("//Location");@ }

            @foreach (var location in locations) {
    
            <li>
                 @location.Name
            </li>
        }
    
  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Aug 02, 2013 @ 13:13
    Jeavon Leopold
    0

    Hi Scott,

    Yes indeed, to use the TypedContentAtXPath method you will need to upgrade to the latest v6.1.3 as it was added in v6.1.0.

    Thanks,

    Jeavon

  • Scott Robinson 54 posts 75 karma points
    Aug 02, 2013 @ 14:48
    Scott Robinson
    1

    Oh :)

    Looks like I'm due for an update this afternoon.

    Thanks for the reply.

    Scott

  • Scott Robinson 54 posts 75 karma points
    Aug 06, 2013 @ 08:53
    Scott Robinson
    0

    I've upgraded Umbraco and can now render a list of locations.

    One final question. I'm not used to targeting nodes in this way. How would I get property data from this node and not just @location.Name ? A description field (textString) for example and url?

    Thanks so much for your help. With this bit of knowledge I can to automatically propogate my language dropdowns, location dropdowns and lists without relying on hard-coding, great.

    Scott

  • Dennis Aaen 4492 posts 18178 karma points admin hq c-trib
    Aug 06, 2013 @ 09:02
    Dennis Aaen
    0

    Hi Scott,

    Now that I can see you full code, will I try to help the best I can.

    But if you get the name, bye this @location.Name, you should be able to something like.

    @location.ProppertyAlias to get custom filed. If you have a field with a proppery alias of description, this code should work for you.

    @location.Description 

    And the exaple with the url you can do it like this;

     @location.Url  

    I hope this helps you

    /Dennis

  • Scott Robinson 54 posts 75 karma points
    Aug 06, 2013 @ 09:12
    Scott Robinson
    0

    Brilliant, thanks for your help Dennis

  • Jeavon Leopold 3042 posts 13382 karma points MVP 9x admin c-trib
    Aug 06, 2013 @ 09:16
    Jeavon Leopold
    0

    Hi Scott, to be able to request properties in the way that Dennis has shown you will need to use ContentAtXPath method instead of TypedContentAtXPath as the example is using dynamics. To use TypedContent you would need to do something like @item.GetPropertyValue("Description") Take at look at this documentation for examples of both dynamic and typed access http://our.umbraco.org/documentation/Using-Umbraco/Backoffice-Overview/Property-Editors/Built-in-Property-Editors/Textbox

    Jeavon

Please Sign in or register to post replies

Write your reply to:

Draft