Copied to clipboard

Flag this post as spam?

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


  • John C Scott 473 posts 1183 karma points
    Jun 07, 2011 @ 16:15
    John C Scott
    0

    library.hasaccess and position

    Consider the following bit of XSLT I've inherited:

      <xsl:for-each select="$currentPage/publicProject">
        <li>
          <xsl:attribute name="class">
            <xsl:choose>
              <xsl:when test="position() mod 4 = 1">
                <xsl:text>alpha</xsl:text>
              </xsl:when>
              <xsl:when test="position() mod 4 = 0">
                <xsl:text>omega</xsl:text>
              </xsl:when>
            </xsl:choose>
          </xsl:attribute>

    This is a fairly typical technique to change the attribute based upon the position. So every 4 items get a new class.

    However I need to change it.

    I need to add a check to library.hasaccess() so that a "publicProject" is only included in the list if the user has role based permission to see it in the list.

    The problem will be that if I wrap the whole <li> in an <xsl:if...> that checks if the current node hasaccess the position will then be wrong. So if the user could only see items 1,3,5 & 6 these should all fall inside the first four positions. But 1 & 3 will get alpha and 5 & 6 will get omega and the list will look wrong.

    The only solution I can think of is to build a variable up which only has the nodes in it that have permission by looping through all the nodes first and only adding them to the variable if they pass the hasaccess test. Then looping this existing for-each on that variable instead.

    This just feels kind of wrong though.

     

    Ideally I'd like to write something like:

     <xsl:for-each select="umbraco.library.hasaccess($currentPage/publicProject)">

    that would feel more right, but I am not sure how to write something like that.

    Can anyone suggest a better way of doing it? Please :)

     

     

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jun 07, 2011 @ 16:38
    Tom Fulton
    0

    Hi,

    I think you could do something like this to filter your xpath:

    <xsl:for-each select="$currentPage/publicProject [umbraco.library:HasAccess(@id, @path) = true()]">

    -Tom

  • John C Scott 473 posts 1183 karma points
    Jun 07, 2011 @ 16:47
    John C Scott
    0

    Nice idea - that could work. I'll give it a go.

    Getting the odd error:

    Prefix 'umbraco.library' is not defined.

    When I try and save that, never seen that before but that must be another problem with the site. Doesn't work in a simple value-of either.

  • Tom Fulton 2030 posts 4998 karma points c-trib
    Jun 07, 2011 @ 16:51
    Tom Fulton
    0

    That's odd, make sure it's defined in the headers of your XSLT file (should be by default...although since you inherited it the previous dev might have changed the alias)

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE xsl:stylesheet [ <!ENTITY nbsp "&#x00A0;"> ]>
    <xsl:stylesheet
      version="1.0"
      xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
      xmlns:msxml="urn:schemas-microsoft-com:xslt"
      xmlns:umbraco.library="urn:umbraco.library" xmlns:Exslt.ExsltCommon="urn:Exslt.ExsltCommon" xmlns:Exslt.ExsltDatesAndTimes="urn:Exslt.ExsltDatesAndTimes" xmlns:Exslt.ExsltMath="urn:Exslt.ExsltMath" xmlns:Exslt.ExsltRegularExpressions="urn:Exslt.ExsltRegularExpressions" xmlns:Exslt.ExsltStrings="urn:Exslt.ExsltStrings" xmlns:Exslt.ExsltSets="urn:Exslt.ExsltSets"
      exclude-result-prefixes="msxml umbraco.library Exslt.ExsltCommon Exslt.ExsltDatesAndTimes Exslt.ExsltMath Exslt.ExsltRegularExpressions Exslt.ExsltStrings Exslt.ExsltSets ">

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 8x admin c-trib
    Jun 07, 2011 @ 22:50
    Chriztian Steinmeier
    0

    Hi John,

    Tom's suggestions should work (using HasAccess() inside the predicate and the prefix thing) - I'm just curious about the way you set the class attribute... the way you're doing it creates a structure like this (with empty classes on half of the elements) - is that what you want? :

    <li class="alpha"></li>
    <li class=""></li>
    <li class=""></li>
    <li class="omega"></li>
    <li class="alpha"></li>
    <li class=""></li>
    ...

    You can get rid of the empty classes *and* that big fat <xsl:choose> thing by doing it this way:

    <xsl:for-each select="$currentPage/publicProject[umbraco.library:HasAccess(@id, @path) = true()]">
        <li>
            <xsl:if test="position() mod 4 = 1">
                <xsl:attribute name="class">alpha</xsl:attribute>
            </xsl:if>
            <xsl:if test="position() mod 4 = 0">
                <xsl:attribute name="class">omega</xsl:attribute>
            </xsl:if>
        </li>
    </xsl:for-each>
    
    - which is a bit neater, I think... :-)
    You can even put a default class directly on the <li> element (e.g. <li class="beta">) which will be overwritten whenever the other ones kick in.

    /Chriztian

     

  • John C Scott 473 posts 1183 karma points
    Jun 14, 2011 @ 15:52
    John C Scott
    0

    as I say I just inherited it working, and my job was to change it as little as possible

    i'll point Laurie at this and he may learn something from this

    for some reason I don't understand I had to replace umbraco.library: with umb: and the xslt worked fine :)

Please Sign in or register to post replies

Write your reply to:

Draft