Copied to clipboard

Flag this post as spam?

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


  • philw 99 posts 434 karma points
    May 02, 2013 @ 14:53
    philw
    0

    Macro for menu with parameter, display item only if content present

    I have some XSLT which generates my menu. It hides from the menu pages which have no content in field "s1". This works:

     

    <xsl:for-each select="$parentNode/*[@isDoc]
      [string(umbracoNaviHide) != '1']
      [string(s1) != '']">
    Now I need to extend that, so I can pass into the macro a parameter which is the name of the content field I want to test. Something like this:
    <xsl:variable name="fieldName" select="/macro/sport"></xsl:variable>
    ...
    <xsl:for-each select="$parentNode/*[@isDoc]
      [string(umbracoNaviHide) != '1']
      [string($fieldName) != '']">
    
    ...which does not work.

    Please can anyone tell me how to have that $fieldName work as intended, so I can pass "s1", "s2" etc in and have that same check made?
    The reason for this is that my site has three "modes", and depending on what mode the user is in they can see only pages which have content relevant to that mode. I can switch the content itself ok, it's just getting the menu to match where content actually is which is causing me some fun.

    Thanks in advance for any help...
     

     

  • Dennis Aaen 4500 posts 18255 karma points admin hq c-trib
    May 02, 2013 @ 15:46
    Dennis Aaen
    0

    Hi philw,

    If I understand your quistion right you only want content to be printed if the parameter has a value.

    I dont know what markup you have in for-each statement, but I think it is a unordered list, with some list items in.

    And only want the list elements to be printed if the paramter has a value right? If so you could try this:

    <ul>
     <xsl:for-each
    select="$parentNode/*[@isDoc and string(umbracoNaviHide) != '1']
     
    <xsl:iftest="$fieldName !=''">
     
    <li><li>
     
    </xsl:test>
     
    </xsl:for-each>
    </ul>

    I don´t hope I am completely misunderstood your question.

    /Dennis


  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    May 02, 2013 @ 15:47
    Chriztian Steinmeier
    1

    Hi philw,

    You can do that using the name() function - like this:

    <xsl:for-each select="$parentNode/*[@isDoc][not(umbracoNaviHide = 1)][not(*[name() = $fieldName] = 1)]">
        <!-- ... -->
    </xsl:for-each>

    /Chriztian

  • philw 99 posts 434 karma points
    May 02, 2013 @ 16:42
    philw
    0

    Perfect, thank you both.

    This is a slight variation on the second of those, and it works perfectly. This is the actual code which works (not simplified as above).

     

       <xsl:for-each select="$parentNode/*[@isDoc][name() != 'Folder'][not(umbracoNaviHide = 1)] [*[name() = $sport] != '']" >

    I could not make it work with the "not" syntax, so I flipped it to a positive check as you see in the last clause there, and that works fine. The menu only shows pages which have content for the specific mode (it's a sport).

    Job done, thanks! 

     

     

  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    May 02, 2013 @ 22:29
    Chriztian Steinmeier
    0

    Hi philw,

    Yes, of course — I didn't catch that you were taking the ones with the property checked (instead of unchecked as it always is with umbracoNaviHide).

    So to be safe from surprises, you should change it to actually test for that, instead of the fuzzy "not equal to <empty string>":

    <xsl:for-each select="$parentNode/*[@isDoc][not(umbracoNaviHide = 1)][*[name() = $sport] = 1]">
            <!-- ... -->
    </xsl:for-each>

     

    /Chriztian 

  • philw 99 posts 434 karma points
    May 02, 2013 @ 23:45
    philw
    0

    Ah, the field is actually "Rich Text" content - the idea is that if they put any content for this sport on this page, then the page appears in the menu. The content is delivered from the Template (master page), but the menu is derived from the XSLT. So the check for empty string is what I think I need. It works as expected.

    ---

    I'm having a different problem with it, which is that my setting for "sport" is actually stored in session backed off in a cookie. I'm trying to pass that into the macro, with the following results:

    1. Pass it as a straight macro parameter (from the Master Page c#). Doesn't work, it's not parsed at all. I can't get a value into a Macro from c# I think.
       
    2. Pass it in the cookie. That works (I can read the value), but I'm "one step behind" in the life cycle with it. So the problem is that when the value changes the cookie isn't actually set until after that XSLT is processed. I tried setting it in OnInit, but that doesn't seem to help. So that almost works.
       
    3. Try to access Session and pull the value from there. I will look at this.
    A final option would be to dump the XSLT and just write a C# menu user control. Assuming I can get the node XLM somehow then that's the same as hacking a standard asp.net sitemap around so I can't see why that would not work,
  • Chriztian Steinmeier 2800 posts 8791 karma points MVP 8x admin c-trib
    May 02, 2013 @ 23:59
    Chriztian Steinmeier
    0

    Okayyy :-)

    Just because people search for stuff and will land here - the *final* (promise :-) real check for that would be to use the normalize-space() function - because (and this is especially true for Rich Texts) it's easy to end up with a field containing only whitespace or, say, three empty <div>'s or <p>'s — and you'd have no clue why stuff isn't working when looking at the field. Here's how:

    <xsl:for-each select="$parentNode/*[@isDoc][not(umbracoNaviHide = 1)][normalize-space(*[name() = $sport])]">
            <!-- ... -->
    </xsl:for-each>

    For the Session/Cookie thing: - Please create a new post - we'll have a much better question+answer rate (and searchability) if we confine a post to a single topic.

    /Chriztian

  • philw 99 posts 434 karma points
    May 03, 2013 @ 00:22
    philw
    0

    normalize-space: crunch whitespace, sounds like a good idea - thanks. These WYSIWYG editors do leave lots of garbage html in there, so that is a good idea. I stuck that it and it works - I'll start another thread for the related issue, I have done more research on that now. 

Please Sign in or register to post replies

Write your reply to:

Draft