Copied to clipboard

Flag this post as spam?

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


  • Murray Roke 503 posts 966 karma points c-trib
    Sep 07, 2011 @ 06:07
    Murray Roke
    0

    Testing existance of children

    Hi it seems it is ver difficult to easly test that child properties exist in DynamicNode DynamicXml

    I have this code:

    @if (Model.textRotator.GetType() == typeof(DynamicXml))
    {
      foreach (var textValue in Model.textRotator.value)
      {
        <li>@textValue.InnerText</li>
      }
    }

    I have this XML:

    <LandingPage ... >
          <textRotator>
            <values />
          </textRotator>

    and my razor script shows this error: 'umbraco.MacroEngines.DynamicXml' does not contain a definition for 'value' (because there aren't any value nodes).

    How do I test for this?

  • MK 4 posts 55 karma points
    Sep 08, 2011 @ 11:22
    MK
    0

    I use those two functions:

     

    public static bool HasProperty(this DynamicXml node, string name)
    {
        var element = node.BaseElement.FirstNode;
    
        while (element != null)
        {
            var xElement = element as XElement;
            if (xElement != null && xElement.Name == name)
            {
                return true;
            }
    
            element = element.NextNode;
        }
    
        return false;
    }
    
    public static bool PropertyHasValue(this DynamicXml node, string name)
    {
        return node.HasProperty(name) && !String.IsNullOrWhiteSpace(node.BaseElement.Elements(name).First().Value);
    }

    I have a blog where I put those kinds of things: http://whatis.goingle.me/dynamicxml-propertyhasvalue-implementation-um.

     

    Does this help?

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Sep 12, 2011 @ 17:35
    Sebastiaan Janssen
    1

    First of all, make sure you're using a recent version of the 4.7.1 macro engine, grab a recent nightly and copy the umbraco.MacroEngines.dll over to your bin folder.

    Then it should be fairly easy, here's an extra safe sample (it checks is the TextRotator property actually exists, and if it's not empty AND if the count of values is more than 0):

    @if (Model.HasProperty("TextRotator") && Model.GetPropertyValue("TextRotator") != string.Empty && Model.TextRotator.Count() > 0) {
    foreach (var textValue in Model.TextRotator) {
    <li>@textValue.InnerText</li>
    }
  • andrew shearer 510 posts 659 karma points
    Sep 12, 2011 @ 23:21
    andrew shearer
    0

    hi Sebastiaan, would your code work if there was only one item in that rotator?

    i've discovered a problem with our use of dynamicNode and ucomponents multinode picker XML:

    @foreach (var x in Model.featureHeaderPromos.nodeId)

     

    if the xml only has one node then its dynamically resolved to one string rather than a collection of node strings. This means that the loop will iterate over the string i.e. the chars that make up the string.

     

  • andrew shearer 510 posts 659 karma points
    Sep 12, 2011 @ 23:48
    andrew shearer
    0

    Gareth Evans mentions the use of multinode pickers in part 5 of this razor article:

    http://umbraco.com/follow-us/blog-archive/2011/3/13/umbraco-razor-feature-walkthrough-part-5.aspx/

    We've added another couple of overloads to MediaById and NodeById
    that take List<object> and params object[]
    These let you return multiple nodes as a list.
    The intention for these methods is to give better support when working with the uComponents multi node tree picker.
    MediaById returns a new type, DynamicMediaList

     

    var nodes = @Model.NodeById(Model.multiChildPicker);

     

    that doesn't seem to work for me.

     

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Sep 13, 2011 @ 00:14
    Sebastiaan Janssen
    0

    @andrew in your first snippet, remove NodeId from the foreach.. 

    Something like this works fine:

    @if (Model.GetPropertyValue("UcMultiNodeTreePicker") != string.Empty && Model.UcMultiNodeTreePicker.Count() != 0)
    {
        <ul>
        @foreach (var nodeId in Model.UcMultiNodeTreePicker)
        {
            @* The nodeId is an XML node of which we need to get the text to get the real ID *@
            var contentItem = Model.NodeById(nodeId.InnerText);
            <li>@contentItem.Name</li>
        }
        </ul>
    }

    The second sample doesn't work for me either and I don't see why it would be useful, the method is called NodeById, not NodesById (with an s), so I would expect only one node to be returned, not multiple (and therefore, you'd also only put one nodeId in it).

    Refer to the above example though, to loop through 1 or multiple nodes.

  • andrew shearer 510 posts 659 karma points
    Sep 13, 2011 @ 00:26
    andrew shearer
    0

    @sebastiaan, thanks for that example, i had something every similar in my original code but i found that if theres only one item selected in the multinode picker then Model seems to change the type being returned from a collection of strings to a single string. this means it tries to loop through the chars of the string rather than the collection of string values.

    can you let me know how you get on with one item selected in your picker? thanks

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Sep 13, 2011 @ 00:30
    Sebastiaan Janssen
    0

    That code works perfectly with one item, which is why I added it ;-)

    Remember though, that I'm using the most recent nightly version of umbraco.MacroEngines.dll, can't speak for the 4.7.0 release or interim builds.

  • andrew shearer 510 posts 659 karma points
    Sep 13, 2011 @ 00:36
    andrew shearer
    0

    yep, i had updated to the latest 4.7.1 build assembly. strange that it didn't work for me.

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Sep 13, 2011 @ 00:38
    Sebastiaan Janssen
    0

    Make sure not to include the .nodeId in the foreach is all I can think of! Try again adapting the sample code above, would love to know if that helps!

  • Murray Roke 503 posts 966 karma points c-trib
    Sep 13, 2011 @ 02:07
    Murray Roke
    0

    @Sebastiaan, your example is not checking the nodes are published.

    In your example that check would need to be added to the first line to ensure the ul is not output if there are  no published nodes.

  • Sebastiaan Janssen 5058 posts 15520 karma points MVP admin hq
    Sep 13, 2011 @ 08:37
    Sebastiaan Janssen
    0

    @Murray That was what the test for != string.Empty is for, however, I could've expressed that better with Model.HasValue("TextRotator").

    Here is an ULTRA safe version, which also first tests if any of the nodes that have been picked (if any) are actually published. In reality, it's unlikely that you'll need to go to that extreme:

    @if (Model.HasProperty("TextRotator") && Model.HasValue("TextRotator") && Model.TextRotator.Count() != 0 && AreAnyNodesInMultiNodeTreePickerPublished(Model.TextRotator))
    { <ul> @foreach (var nodeId in Model.TextRotator) { var contentItem = Model.NodeById(nodeId.InnerText); <li>@contentItem.Name</li> } </ul> } @functions { private bool AreAnyNodesInMultiNodeTreePickerPublished(dynamic MultiNodePicker) { foreach (var nodeId in MultiNodePicker) { var contentItem = Model.NodeById(nodeId.InnerText); if (contentItem.Name != string.Empty) { return true; } } return false; } }
  • andrew shearer 510 posts 659 karma points
    Sep 16, 2011 @ 07:16
    andrew shearer
    0

    i have some code to convert the contents of a multinodepicker property into a list of published nodes here:

    http://our.umbraco.org/forum/developers/razor/24098-dynamic-and-razor-@functions

    any help converting this working code into a @function would be appreciated.

    thanks

     

Please Sign in or register to post replies

Write your reply to:

Draft