x First time here? Check out the FAQ

Come work for Umbraco - The Umbraco HQ are hiring Project managers, .NET developers and DevOps people!

  • Avatar228posts309karma

    Generate comma separated list of nodepropertys

    Kasper Dyrvig started this topic August 31, 2010 @ 08:14, Go directly to the topic solution

    Hi all!

    I am working on my new website ware I want to create a "playlist". The playlist should contain 7 urls for some mp3 files. The first and the last url is always the same, the middle 5 should be gathered from the top-five newest nodes that are childes to id=1103.

    Exsample of the final output:

    /media/mp3/intro.mp3 , /media/mp3/file01.mp3 , /media/mp3/file02.mp3 , /media/mp3/file03.mp3 , /media/mp3/file04.mp3 , /media/mp3/file05.mp3 , /media/mp3/final.mp3

    After the list string i collected I will put it in to an audio player on the page.


  • Lee Kelleher posted this reply August 31, 2010 @ 10:25

    Hi Webspas,

    Is node Id "1103" a content or media node?

    Either way, a simple XSLT macro can produce the output you need.  Let us know the node type and we'll show you an example.

    Cheers, Lee.


  • Chriztian Steinmeier posted this reply August 31, 2010 @ 10:29

    Hi Webspas,

    I'd think something like this would be a good start:

    <?xml version="1.0" encoding="utf-8" ?>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umbraco.library="urn:umbraco.library"
        exclude-result-prefixes="umb"
    >
    
        <xsl:output method="text" indent="no" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
        <xsl:variable name="mediaRoot" select="$siteRoot//*[@id = 1103]" />
    
        <xsl:variable name="firstFile" select="'/media/mp3/intro.mp3'" />
        <xsl:variable name="lastFile" select="'/media/mp3/final.mp3'" />
        <xsl:variable name="middleCount" select="5" />
    
        <xsl:template match="/">
            <xsl:variable name="mediaTopNode" select="umbraco.library:GetMedia($mediaRoot, true())]" />
    
            <xsl:value-of select="$firstFile" />
            <xsl:text>, </xsl:text>
    
            <xsl:for-each select="$mediaTopNode/*[umbracoExtension = 'mp3']">
                <xsl:sort select="@createDate" data-type="text" order="descending" />
                <xsl:if test="position() &lt;= $middleCount">
                    <xsl:value-of select="umbracoFile" />
                </xsl:if>
                <xsl:text>, </xsl:text>
            </xsl:for-each>
    
            <xsl:value-of select="$lastFile" />
    
        </xsl:template>
    
    </xsl:stylesheet>
    

    /Chriztian


  • Avatar228posts309karma
    Comment with ID: 45250
    Kasper Dyrvig posted this reply August 31, 2010 @ 10:31

    #Lee: Deal! :-)

    "1103" is a page node.

    By the way: I would like to use the list string somewhere else inside the same XSLT file.


  • Lee Kelleher posted this reply August 31, 2010 @ 10:35

    Chriztian beat me to it! ;-) (XSLT legend!)


  • Chriztian Steinmeier posted this reply August 31, 2010 @ 10:38

    He - thought about asking that too, Lee - should have, I can see :-)

    @Webspas: So is the file an "Upload" datatype, or a Media Picker? 


  • Chriztian Steinmeier posted this reply August 31, 2010 @ 11:27

    Hi Webspas,

    I've updated the code above, in case you might have used it as a starting point.

    (There was a couple of "hurry-up, must. beat. Lee. post. now!" errors in the first draft :-)

    /Chriztian 


  • Avatar228posts309karma
    Comment with ID: 45270
    Kasper Dyrvig posted this reply August 31, 2010 @ 11:37

    Well, first I upload the file to Umbraco. Then I make a page for the file with additional information and pick the file. On another page I want to present the five newest files.

    Does that answer your question?


  • Chriztian Steinmeier posted this reply August 31, 2010 @ 02:19

    Hi again,

    Here's something that actually "works on my machine":

    You'll have to replace the names in the first few lines (bolded for your convenience) with the names of the actual Doctype and propertyName you're using 

    <?xml version="1.0" encoding="utf-8" ?>
    <!DOCTYPE xsl:stylesheet [
        <!ENTITY DocumentTypeAlias "Mp3File">
        <!ENTITY mediaPickerAlias "mediaFile">
    ]>
    <xsl:stylesheet
        version="1.0"
        xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
        xmlns:umbraco.library="urn:umbraco.library"
        exclude-result-prefixes="umbraco.library"
    >
    
        <xsl:output method="text" indent="no" omit-xml-declaration="yes" />
    
        <xsl:param name="currentPage" />
        <xsl:variable name="siteRoot" select="$currentPage/ancestor-or-self::*[@level = 1]" />
    
        <xsl:variable name="mediaRoot" select="$siteRoot//*[@id = 1103]" />
    
        <xsl:variable name="firstFile" select="'/media/mp3/intro.mp3'" />
        <xsl:variable name="lastFile" select="'/media/mp3/final.mp3'" />
        <xsl:variable name="middleCount" select="5" />
    
        <xsl:template match="/">
    
            <xsl:value-of select="$firstFile" />
            <xsl:text>, </xsl:text>
    
            <xsl:for-each select="$mediaRoot/&DocumentTypeAlias;">
                <xsl:sort select="@createDate" data-type="text" order="descending" />
                <xsl:if test="position() &lt;= $middleCount">
                    <xsl:apply-templates select="&mediaPickerAlias;" />
                    <xsl:text>, </xsl:text>
                </xsl:if>
            </xsl:for-each>
    
            <xsl:value-of select="$lastFile" />
    
        </xsl:template>
    
        <xsl:template match="&mediaPickerAlias;">
            <xsl:variable name="mediaNode" select="umbraco.library:GetMedia(., false())" />
            <xsl:value-of select="$mediaNode/umbracoFile" />
        </xsl:template>
    
    </xsl:stylesheet>

    /Chriztian


  • Avatar228posts309karma
    Comment with ID: 45352
    Kasper Dyrvig posted this reply August 31, 2010 @ 07:57

    Thank you very much! So far so good.

    Now there is only one thing left, and as far I see it there are 2 possibilities:

    The list that is created must be placed inside a Javascript in order to be played for the user. Can it be done by...

    • placing the output from the list-XSLT in the macro parameters for the player-XSLT (in the template)?

    ... or...

    • parsing the final list string further down in the same XSLT and create the player there?

    Or is there something else? I appreciate your replies!


  • Chriztian Steinmeier posted this reply August 31, 2010 @ 08:44

    Hi Webspas,

    You can just wrap a variable instruction around the template body to create the result as a string for reuse later on, e.g.:

       <xsl:template match="/">
            <xsl:variable name="playListCSV">
                <xsl:value-of select="$firstFile" />
                <xsl:text>, </xsl:text>
    
                <xsl:for-each select="$mediaRoot/&DocumentTypeAlias;">
                    <xsl:sort select="@createDate" data-type="text" order="descending" />
                    <xsl:if test="position() &lt;= $middleCount">
                        <xsl:apply-templates select="&mediaPickerAlias;" />
                        <xsl:text>, </xsl:text>
                    </xsl:if>
                </xsl:for-each>
    
                <xsl:value-of select="$lastFile" />
            </xsl:variable>      
    
            <!-- Lots of XSLT going on... -->
    
            <script type="text/javascript">
                var playlist = "<xsl:value-of select="$playListCSV" />";
    
                // Lots of JS processing...
    
                alert(playListCSV);
            </script>
        </xsl:template>

    Also, change the output instruction and ask for CDATA output of script elements:

    <xsl:output method="xml" indent="yes" omit-xml-declaration="yes" cdata-section-elements="script" />

    /Chriztian


Pages:

Please login or Sign up To post replies