Copied to clipboard

Flag this post as spam?

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


  • Wade 43 posts 159 karma points
    Sep 02, 2014 @ 00:55
    Wade
    0

    Umbraco 7 - Multi Node Tree Picker - Display children as separate items in list

    Hi, This is the first time I've tried using the MultiNodeTreePicker, and I'm having a really difficult time trying to get things to display properly. I have followed several different tutorials on it, but I can't get any information to display when I follow them.

    I have managed to get the correct nodes showing, but not in the way I want.

    My tree structure is this:

    Home
    -Site pages
    --Site subpages

    Footer
    -ListOfLinksForFooter (1)
    -ListOfLinksForFooter (2)

    On the ListOfLinksForFooter pages I have a MultiNodeTreePicker (footerLinks) that selects nodes of the site, so the client can choose what he wants to link to around the site.

    My xslt file returns this:

    <div>
      <h3>footerListTitle</h3>
      <ul>
        <li><a>footerLinks,footerLinks,footerLinks,footerLinks (max of 5)</a>
        </li>
      </ul>
    </div>
    

    the footer links on display the node id rather than the niceurl, and they are all listed as one list and link, rather than separate list items and separate links.

    I need them listed like this:

    <div>
      <h3>footerListTitle</h3>
      <ul>
        <li><a>footerLinks (niceUrl)</a></li>
        <li><a>footerLinks (niceUrl)</a></li>
        <li><a>footerLinks (niceUrl)</a></li>
        <li><a>footerLinks (niceUrl)</a></li>
      </ul>
    </div>
    

    I have read that I should put in /MultiNodePicker/nodeId to get the list, but I have never been able to get any information when I do that.

    Some links I've tried looking at are:
    http://www.sumac.uk.com/blog/production/umbraco-%E2%80%93-the-ucomponent-multi-node-tree-picker-guide
    http://pimpmyxslt.com/articles/multipicker/

    My xslt is:

      <xsl:template match="/">
    
        <xsl:variable name="linksPage" select="$currentPage/ancestor-or-self::root//Footer/ListOfLinksForFooter" />
    
        <xsl:if test="$linksPage">
            <xsl:for-each select="$linksPage">
                <div class="col-sm-4">
                    <h3><xsl:value-of select="footerListTitle" /></h3>
                    <ul>
                        <li> <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="footerLinks"/></a>  </li>
                    </ul>
                </div>
            </xsl:for-each>
        </xsl:if>
    
    </xsl:template>
    

    Any help would be appreciated.
    Thanks,
    Wade.

  • Dennis Aaen 4499 posts 18254 karma points admin hq c-trib
    Sep 02, 2014 @ 01:21
    Dennis Aaen
    0

    Hi Wade,

    Have you seen the documentation for the Multi Node Tree Picker, there are two different ways of doing this in XSLT, depending on which format you save your data in.

    You can save data in XML or in CSV. The XML version looks like this:

    <xsl:if test="$currentPage/mntpFeaturePicker/MultiNodePicker/nodeId">
        <xsl:for-each select="$currentPage/mntpFeaturePicker/MultiNodePicker/nodeId">
            <xsl:variable name="currentnode" select="umbraco.library:GetXmlNodeById(.)" />
            <!-- render only published nodes -->
            <xsl:if test="count($currentnode/error) = 0">          
                <p><xsl:value-of select="$currentnode/@nodeName" /></p>
            </xsl:if>          
        </xsl:for-each>
    </xsl:if>

    And the CSV version looks like this.

    <xsl:if test="string-length($currentPage/mntpFeaturePicker) > 0">  
      <xsl:variable name="items" select="umbraco.library:Split($currentPage/mntpFeaturePicker,',')" /> 
      <xsl:for-each select="$items//value">
        <xsl:variable name="currentnode" select="umbraco.library:GetXmlNodeById(.)" />
        <!-- render only published nodes -->
        <xsl:if test="count($currentnode/error) = 0">          
            <p><xsl:value-of select="$currentnode/@nodeName" /></p>
        </xsl:if>                      
      </xsl:for-each>    
    </xsl:if>

    You can find the documenation and the XSLT examples here and how to configure the Multi Node Tree Picker. http://our.umbraco.org/documentation/Using-Umbraco/Backoffice-Overview/Property-Editors/Built-in-Property-Editors/Multi-Node-Tree-Picker

    Hope this helps,

    /Dennis

  • Wade 43 posts 159 karma points
    Sep 02, 2014 @ 03:46
    Wade
    0

    Hi Dennis, Thanks for the quick reply. I forgot to mention that I have actually tried the xml version of what you posted. I originally put in the code exactly as you have posted here, but I got no content coming through at all. Then I realised that these two lines

    <xsl:if test="$currentPage/mntpFeaturePicker/MultiNodePicker/nodeId">
        <xsl:for-each select="$currentPage/mntpFeaturePicker/MultiNodePicker/nodeId">
    

    look for a child of the current page. The page that the MultiNodePicker is on is not a child of the current page. It has it's own page in the structure of the content (see above). So I thought I'd try changing the lines to the following to get the page that the MultiNodePicker is on.

    <xsl:if test="$currentPage/ancestor-or-self::root//Footer/ListOfLinksForFooter/mntpFeaturePicker/MultiNodePicker/nodeId">
        <xsl:for-each select="$currentPage/ancestor-or-self::root//Footer/ListOfLinksForFooter/mntpFeaturePicker/MultiNodePicker/nodeId">
            <xsl:variable name="currentnode" select="umbraco.library:GetXmlNodeById(.)" />
            <!-- render only published nodes -->
            <xsl:if test="count($currentnode/error) = 0">           
                <p><xsl:value-of select="$currentnode/@nodeName" /></p>
            </xsl:if>           
        </xsl:for-each>
    </xsl:if>
    

    I still get no content at all when I do this though. I assume that I have to get the node that the MultiNodePicker is on before I add on the /mntpFeaturePicker/MultiNodePicker/nodeId? (Which is what I have tried to do... "...ListOfLinksForFooter/mntpFeaturePicker/MultiNodePicker/nodeId")

    Cheers, Wade.

  • Dennis Aaen 4499 posts 18254 karma points admin hq c-trib
    Sep 02, 2014 @ 08:35
    Dennis Aaen
    0

    Hi Wade.

    One thing I notice is that you maybe have a problem with the propertyAlias of the document type. From the first post, you have posted to me it looks like your propertyAlias is named ListOfLinksForFooter if so, I think your code should look likes this:

    <xsl:if test="$currentPage/ancestor-or-self::root//Footer/ListOfLinksForFooter/MultiNodePicker/nodeId">
        <xsl:for-each select="$currentPage/ancestor-or-self::root//Footer/ListOfLinksForFooter /MultiNodePicker/nodeId">
            <xsl:variable name="currentnode" select="umbraco.library:GetXmlNodeById(.)" />
            <!-- render only published nodes -->
            <xsl:if test="count($currentnode/error) = 0">          
                <p><xsl:value-of select="$currentnode/@nodeName" /></p>
            </xsl:if>          
        </xsl:for-each>
    </xsl:if>

    BUT check the propertyAlias of your Multi Node Tree Picker for the page.

    If it not works, then I would recommend you to break your code down in small steps, and make sure that you grab the right data, if so then you can take the next step. This is the way I do it when I don´t get data I expect

    Here is a video that expain proppertyAlias http://umbraco.tv/videos/umbraco-v7/implementor/fundamentals/document-types/properties/

    Hope this helps,

    /Dennis

  • Wade 43 posts 159 karma points
    Sep 02, 2014 @ 11:52
    Wade
    0

    Hi Dennis,

    I've got a handle on the Document types and data, it's just I don't know how to call the information from the multi mode picker. I'm not sure what I should be calling it from.

    The document type's alias is 'ListOfLinksForFooter'.

    The propertyAlias on that document type is called 'footerLinks' (the data type of 'footerLinks' is called Footer List Picker, which is a Umbraco.MultiNodeTreePicker)

    To get the data do I need to find "$currentPage.../ My Document type (ListOfLinksForFooter) / My propertyAlias (footerLinks) / mntpFeaturePicker / MultiNodePicker / nodeId"?

    Or do I need to rename the mntpFeaturePicker or MultiNodePicker to the name that I have given my MultiNodeTreePicker (which is Footer List Picker) which would give me...

    "$currentPage.../ My Document type (ListOfLinksForFooter) / My propertyAlias (footerLinks) / FooterListPicker / nodeId"
    

    I'm assuming it's neither as I've tried both and none give me any data! I've created the content already, and have managed to get the list of data coming through, but that is whenever I don't add the /mntpFeaturePicker / MultiNodePicker / nodeId to the end of the $currentPage line. If I add those then no output is generated at all! This is where I am confused. All documentation says to add the "/mntpFeaturePicker / MultiNodePicker / nodeId", but if I do, no data is generated

  • Wade 43 posts 159 karma points
    Sep 18, 2014 @ 00:39
    Wade
    0

    Nobody has any ideas?

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 18, 2014 @ 01:13
    Chriztian Steinmeier
    0

    Hi Wade,

    If the footerLinks properties are saved as "XML" (not CSV) you should be able to use this code (based on your initial posting):

    <xsl:template match="/">
        <xsl:variable name="linksPage" select="$currentPage/ancestor::root/Footer/ListOfLinksForFooter" />
        <xsl:if test="$linksPage">
            <xsl:for-each select="$linksPage">
                <div class="col-sm-4">
                    <h3><xsl:value-of select="footerListTitle" /></h3>
                    <ul>
                        <xsl:for-each select="id(footerLinks/MultiNodePicker/nodeId)">
                            <li>
                                <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName" /></a>
                            </li>
                        </xsl:for-each>
                    </ul>
                </div>
            </xsl:for-each>
        </xsl:if>
    </xsl:template>
    

    Let me know if you'd like me to explain it further - but maybe, let's just make sure it works first :-)

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 18, 2014 @ 04:03
    Wade
    0

    Hi Chriztian, Thank you very much for getting back to me. It's a great solution, and I get the title coming through fine. It finds the node, and then the title, but I still get no data coming through from the MultiNodePicker with this code. I am not sure whether it is saving it as xml or csv as I am building in Umbraco 7, and in the default settings there aren't any xml/csv options. It looks like in the old version there was, but it this version there isn't.

    Everything is coming through ok until I get to here:

    <xsl:for-each select="id(footerLinks/MultiNodePicker/nodeId)">
    

    I've tried changing it to <xsl:for-each select="id(footerLinks/FooterListPicker/nodeId)"> in case I needed to rename the MultiNodePicker to the name I had given it however that doesn't work...

    In the documentation it says I should put mntpFeaturePicker/MultiNodePicker/nodeId but that doesn't work either.

    Any thoughts?

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

    Aha - so that's why. Umbraco 7 saves mostly in JSON format, which is pretty much useless from XSLT...

    Ok - new plan - I'll come back with something.

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 18, 2014 @ 11:25
    Wade
    0

    Ah! That does make it difficult then, but it also explains why none of the solutions I tried worked. Thanks Chriztian.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 18, 2014 @ 11:33
    Chriztian Steinmeier
    0

    Yes - and I really should have read that from the topic title, right? :-)

    Oh well - there's an extension in Umbraco 7 that you can use to get XML from the JSON structure: umbraco.library:JsonToXml() - it will give you a pretty generic output, but you should be able to get the IDs nonetheless.

    Maybe try this first, to get an idea of the data returned:

    <textarea><xsl:copy-of select="umbraco.library:JsonToXml(footerLinks)" /></textarea>
    

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 18, 2014 @ 23:45
    Wade
    0

    Ha, no worries Chriztian! I'm just glad that someone is willing to take the time to help.

    I put the code in as this:

     <xsl:template match="/">
        <xsl:variable name="linksPage" select="$currentPage/ancestor::root/Footer/ListOfLinksForFooter" />
        <xsl:if test="$linksPage">
            <xsl:for-each select="$linksPage">
                <div class="col-sm-4">
                    <h3><xsl:value-of select="footerListTitle" /></h3>
                    <ul>
                            <li>
                                <textarea><xsl:copy-of select="umbraco.library:JsonToXml(footerLinks)" /></textarea>
                            </li>
                    </ul>
                </div>
            </xsl:for-each>
        </xsl:if>
    
    </xsl:template>
    

    And I get this back in the text area:

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 18, 2014 @ 23:49
    Chriztian Steinmeier
    0

    Oh - what a mess; try skipping the JsonToXml() extension and let's just see what's inside that footerLinks beast then:

    <textarea><xsl:copy-of select="footerLinks" /></textarea>
    

    And then we can act accordingly...

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 19, 2014 @ 00:00
    Wade
    0

    If I put in the <xsl:copy-of select="footerLinks" /> or <xsl:value-of select="footerLinks" /> it returns everything as this:

    <ul>
        <li>footerLinks,footerLinks,footerLinks,footerLinks</li>
    </ul>
    

    So right now, it returns:

    Grand Hotel Extras (TITLE)
    1118,1103,1099,1117,1100 (Node IDs)

    This is basically what I was able to get at the beginning, so I know that the data is able to be seen, but the problem arises when trying to add the /MultiNodePicker/nodeId. When that is added everything goes blank. As you said, it must be because of the way Umbraco 7 saves the data.

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 19, 2014 @ 00:06
    Chriztian Steinmeier
    100

    Ahaa! ... It's not even JSON then...

    Back to my code then:

    <xsl:template match="/">
        <xsl:variable name="linksPage" select="$currentPage/ancestor::root/Footer/ListOfLinksForFooter" />
        <xsl:if test="$linksPage">
            <xsl:for-each select="$linksPage">
                <div class="col-sm-4">
                    <h3><xsl:value-of select="footerListTitle" /></h3>
                    <ul>
                        <xsl:for-each select="id(translate(footerLinks, ',', ' '))">
                            <li>
                                <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName" /></a>
                            </li>
                        </xsl:for-each>
                    </ul>
                </div>
            </xsl:for-each>
        </xsl:if>
    </xsl:template>
    

    (This is the only line that's changed: <xsl:for-each select="id(translate(footerLinks, ',', ' '))"> - make sure to get the commas and apostrophes right :-)

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 19, 2014 @ 00:19
    Wade
    0

    Thank you Chriztian! You are the master! That's pulling in the data perfectly.

    I have one little issue, which is strange. It's not showing them in the correct order. The sorting doesn't seem to work. I can live with it, but if you might happen to know why it might be happening it would be helpful.

    Thanks again!

  • Chriztian Steinmeier 2798 posts 8788 karma points MVP 7x admin c-trib
    Sep 19, 2014 @ 00:44
    Chriztian Steinmeier
    0

    Oh, but of course I know why — XSLT is just too fast at picking them by id... (not really :-)

    They're returned in what's called "document order", which is of course one of the reasons that makes it a fast operation for the processor. But fear not, we'll just pull a really sneaky trick to sort them with; try this:

    <xsl:for-each select="id(translate(footerLinks, ',', ' '))">
        <xsl:sort select="string-length(substring-before(footerLinks, current()/@id))" data-type="number" order="ascending" />
        <li>
            <a href="{umbraco.library:NiceUrl(@id)}"><xsl:value-of select="@nodeName" /></a>
        </li>
    </xsl:for-each>
    

    Now, this will fail if you have an id like 1234 and another one like 61234 - where one id contains another, and they're both in the same sequence - but I'll you'll be the judge about the chances of that happening in your install.

    /Chriztian

  • Wade 43 posts 159 karma points
    Sep 19, 2014 @ 07:05
    Wade
    0

    Hmm, not working... still too fast maybe! =P

    I actully came across this, so maybe the bug still hasn't been fixed?

    http://issues.umbraco.org/issue/U4-4053

Please Sign in or register to post replies

Write your reply to:

Draft