Copied to clipboard

Flag this post as spam?

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


  • Scott 69 posts 146 karma points
    Sep 06, 2013 @ 22:35
    Scott
    0

    Comparing results of two library:split calls

    I'm using xslt to iterate nodes to build a navigation menu.Without going into a lot of detail, as I'm looping through my nodes, I have the result of two library:split functions, one is the result of a properties in the node, and the second from a session variable. I want to basically return true, and show the nodes link if any 1 of the items from those two lists match. 

    I have everything working, using <xsl:for-each loops,  with one loop inside the other. Problem is if I get more than one match, then my link is going to show twice. I have a feeling I need use templates and matching but I just dont have a grasp on it yet.

     

    Thanks

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 07, 2013 @ 07:27
    Chriztian Steinmeier
    0

    Hi Scooter,

    What are the values? Are they node ids for the childnodes you need to show?

    /Chriztian

  • Scott 69 posts 146 karma points
    Sep 09, 2013 @ 14:36
    Scott
    0

     At the top level I am iterating through some nodes that are potential menu links for a navigation menu. For each node I'm looking at a CheckBox value. I'm attempting to compare the value(s) returned from the checkbox value against the values I'm pulling from a session value. What I'm attempting to do is only show links for the nodes my logged in user is allowed to see. The session value is the list of groups the user is in. The checkbox values are the groups allowed to see that particular node. i.e my user logs in and is assigned the groups "AuthenticatedUser,SalesMan". The available checkboxes for a node might be "AuthenticatedUser","SalesMan","Accountant","Custodial". If salesman are allowed to see a node, the "SalesMan" checkbox would be checked in the properties of the node. So as my xslt runs and I iterate through my nodes, when I split the checkbox values for this node I would be returned:

    <values>
       
    <value>SalesMan/value>
    </values>

     then when I split the values of the groups my user is in I would be getting

    <values>
       
    <value>RegisteredUser</value>
       
    <value>SalesMan</value>
    </values>

    Because SalesMan is found in both return values, my "test" should pass and I should display a link for this node. The way I'm doing it now, where I run a for-each loop against one, and inside that loop run another for-each loop against the other, if multple entries match, then the link will be displayed multiple times,once for each match. And there are instances where the link needs to be made available to multiple groups, and one person might be in multiple groups. For example there might be a link made available to both Accountants and Custodial. User xyz is an accountant and makes a little money on the weekends cleaning. So he's in both groups. With my nested for-each loops he's going to match twice, and the link for that node would show twice. Not what I want obviously.

    Just to help, here's what I have currently, that doesn't work for me:

     <xsl:variable name="GroupNameMultiPicker" select="umbraco.library:Split(./groupNameMultiPicker,',')" /> 
     <xsl:for-each select="$GroupNameMultiPicker//value">
        <xsl:variable name="pageGroupName" select="current()" />
           <xsl:for-each select="$GroupNames//value">
            <xsl:variable name="userGroupName" select="current()" />  
            <xsl:if test="$pageGroupName = $userGroupName">
              <li>
               <href="{umbraco.library:NiceUrl($NiceUrlID)}">
               <xsl:value-of select="$NodeName"/> [<xsl:value-of select="$userGroupName" />]
               </a>
             </li>
            </xsl:if>
        </xsl:for-each>
    </xsl:for-each>

  • Scott 69 posts 146 karma points
    Sep 09, 2013 @ 17:26
    Scott
    0

    Just a quick FYI while I would still like to do this in what I consider the correct way (if thats possible) using pure xsl with templates or whatever it takes, in the interim I used a custom function (i.e. http://our.umbraco.org/wiki/reference/xslt/extend-your-xslt-with-custom-functions)  in C# and I'm just taking my two comma seperated values, reading them into arrays, iterating through one, and looking for its value in the other. It works, but it just seems like overkill IF I can do it in xsl.

     

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 09, 2013 @ 18:44
    Chriztian Steinmeier
    0

    Hi Scooter,

    And just a short "Yes, we can" from me (I'm only on a mobile right now so can't really post longer code samples).

    It's totally doable (and usually surprisingly simple) with templates and an XPath expression that selects the right nodes.

    /Chriztian

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 09, 2013 @ 23:23
    Chriztian Steinmeier
    100

    Hi Scooter,

    I'm back with an answer :-)

    So if I'm getting this right, something like this should do the trick — the XPath really just says: "Give me all the nodes that have a value in groupNameMultiPicker equal to a value in the GroupNames variable" - check it out:

    <xsl:param name="currentPage" />
    <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
    <!-- You get this from Session, I guess? Here I've just hardcoded it... -->
    <xsl:variable name="GroupNames" select="'AuthenticatedUser'" />
    
    <!-- Split that one just once for efficiency -->
    <xsl:variable name="GroupNameValues" select="umbraco.library:Split($GroupNames, ',')" />
    
    <xsl:template match="/">
        <!-- Grab all potential nodes (here just all children of the Home node) -->
        <xsl:variable name="nodes" select="$siteRoot/*[@isDoc][not(umbracoNaviHide = 1)]" />
    
        <ul>
            <!-- Process all nodes that are allowed for this user's groups -->
            <xsl:apply-templates select="$nodes[umbraco.library:Split(groupNameMultiPicker, ',')/value = $GroupNameValues/value]" />
        </ul>
    </xsl:template>
    
    <!-- Template for displaying an actual node -->
    <xsl:template match="*[@isDoc]">
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}">
                <xsl:value-of select="@nodeName" />
            </a>
            (<xsl:value-of select="groupNameMultiPicker" />)
        </li>
    </xsl:template>
    

    Of course, as you've hinted at, the beauty of this is that you have the benefit of a very clean template for the actual node rendering. And if you have more than one type of node (e.g. Textpage and NewsItem nodes) in the mix, it's very simple to display them differently by just supplying a separate template for each Document Type.

    /Chriztian

  • Scott 69 posts 146 karma points
    Sep 10, 2013 @ 17:20
    Scott
    0

    Well that was easy. Works like a charm. THANKS!

Please Sign in or register to post replies

Write your reply to:

Draft