xmlxsltaudio

Embed audio player in xml xslt


I'm trying to add an html audio player for my rss xml with an xml stylesheet. THIS "works" by adding the <audio scr= in the description if the item.

<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" href="template.xsl" ?>
<rss version="2.0" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd"  xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
    <title><![CDATA[TruTheater Radio]]></title>
    <link>https://trutheaterradio.com/</link>
    
    <description><![CDATA[Audio Drama Meets Long Form Discussions. Hollywood and the main stream media has taken over the minds of the masses. However, many have become wise to this fact and have turned to alternative sources to seek truth to asend to greater heights of conciousness. This has left something lacking in the truth seeking movement. Trutheater Radio is stepping in the fill the void. Dramatization through audio to make us laugh, cry, uplift and inspire while discussing the deeper truths and mysteries of this realm. Join us in our assent]]></description>
    <lastBuildDate>Sun, 09 Apr 2023 02:51:18 GMT</lastBuildDate>
    <language>en</language>
    <copyright><![CDATA[Trutheater Radio 2022]]></copyright>
    <itunes:image href="https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/Podcast%20Files/Polish_20221103_043417458.png"/>
    <image>
      <url>https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/Podcast%20Files/icon/icon.jpg</url>
      <title>TruTheater Radio</title>
      <link>https://trutheaterradio.com/</link>
    </image>
    <itunes:author>Joshua and Jonah Earl</itunes:author>
    <itunes:owner>
      <itunes:name>Joshua and Jonah Earl</itunes:name>
  <itunes:email>trutheaterradio@gmail.com</itunes:email>
    </itunes:owner>
    <itunes:explicit>true</itunes:explicit>
    <itunes:type>episodic</itunes:type>
    <itunes:category text="Fiction">
      <itunes:category text="Drama"/>
    </itunes:category>
    <itunes:category text="Spirituality">
      <itunes:category text="Spirituality"/>
    </itunes:category>
    <atom:link href="https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/Podcast%20Files/Feed/feed.xml" rel="self" type="application/rss+xml" />



<item>
 
      <title><![CDATA[Writer's Block]]></title> 
      <itunes:title><![CDATA[Writer's Block]]></itunes:title> 
      <description>

<![CDATA[<p><audio controls style="width: 500px;" src="https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/s01e07%20_Writers_Block/s01e07_Writers_Block_FULL.mp3" preload="none" controls=""></audio></p><p> Writer’s block is real and it sucks. But, what if the writer is being blocked by himself.TruTheaterRadio.comFeatured in the Cast were:Jonah Earl as Himself Joshua James Earl as Himself Writen by: Jonah Earl Edited by: Jonah Earl Music: The Awakening by: Caio Barbosa (ABRAMUS) 100% Publisher: Estudio Kali (ABRAMUS) 100% LICENSE GENERATED BY: TuneReel E-mail Address: license@tunereel.com Memory And Forgetting Ft. Cicely Parnas (Instrumental) by: Spearfisher Produced by: Jonah Earl and Joshua James Earl of TruTheater RadioTruTheaterRadio © 2023 license@tunereel.com TuneReel</p><p></p><p><a href="http://www.TruTheaterRadio.com">www.TruTheaterRadio.com</a></p><p><a href="mailto:Trutheaterradio@gmail.com">Trutheaterradio@gmail.com</a></p>]]></description> 
      <guid>https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/s01e07%20_Writers_Block/s01e07_Writers_Block_FULL.mp3</guid> 
      <enclosure url="https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/s01e07%20_Writers_Block/s01e07_Writers_Block_FULL.mp3" length="47326366" type="audio/mpeg"/> 
      
      <itunes:image href="https://filedn.com/lmon024IRoRuy3dTE9iFItm/TruTheater%20Radio%20Public%20Folder/s01e07%20_Writers_Block/cover/cover.jpg"/> 
      <itunes:duration>2886</itunes:duration> 
      <itunes:episodeType>full</itunes:episodeType> 
      <itunes:episode>8</itunes:episode> 
     <itunes:season>1</itunes:season> 
<itunes:explicit>true</itunes:explicit> 
      <pubDate>Sun, 16 Jul 2023 23:49:07 GMT </pubDate> 
    </item>

</channel>
</rss>
<?xml version="1.0" encoding="utf-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:itunes="http://www.itunes.com/dtds/podcast-1.0.dtd">
    <xsl:output method="html" version="1.0" encoding="ISO-8859-1" indent="yes"/>
    <xsl:template match="/">

        <html xmlns="http://www.w3.org/1999/xhtml">
            <head>              
                <title><xsl:value-of select="/rss/channel/title"/> - RSS</title>
                <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
                <style type="text/css">
                    @import url('https://fonts.googleapis.com/css?family=Montserrat:300,400,500,600');
                    @import url("https://use.fontawesome.com/releases/v5.8.1/css/all.css");

                    body {
                        font-family: 'Montserrat', sans-serif;
                        font-size: 14px;
                        color: #545454;
                        background: #E5E5E5;
                        line-height: 1.5;
                    }
                    .explanation {
                        font-style: italic;
                        font-size: 10px;
                        color: #9E9E9E;
                        text-align: center;
                    }
                    a, a:link, a:visited {
                        color: #005C82;
                        text-decoration: none;
                    }
                    a:hover {
                        color: #000;
                    }
                    h1 {
                        margin-top: 0;
                         margin-bottom: 0;
                         font-weight: 300;
                         font-size: xx-large;
                    }

                    h2, h3 {
                        margin-top: 0;
                        margin-bottom: 0px;
                        font-weight:300;
                    }
                    h2 {
                        margin-top: 20px;
                    }

                    h3 {
                        font-size:small;
                        font-weight: 500;
                    }

                    img {
                    max-width: 100%;
                    } 
                    
                    #content {
                        max-width: 900px;
                        margin: 0 auto;
                        background: #FFF;
                        padding: 30px;
                        border-radius: 1em;
                        padding-top: 0px;
                        box-shadow: 0px 0px 2px #5D5D5D;
                    }
                    #channel-image {
                        float: right;
                        width: 200px;
                        margin-bottom: 20px;
                    }
                    #channel-image img {
                        width: 200px;
                        height: auto;
                        border-radius: 3px;
                        margin-left: 10px;
                    }
                    #channel-header {
                        margin-bottom: 20px;
                        padding-top: 20px;
                        margin-left: -10px;
                    }
                    .channel-item {
                        clear: both;
                        border-top: 2px solid #E5E5E5;
                        margin: 10px;
                        overflow-wrap: break-word;
                        word-wrap: break-word;
                        hyphens: auto;
                    }

                    .episode-image {
                         float: right;
                         width: 300px;
                         margin-right: 10px;
                         margin-bottom: 10px;
                         margin-top: 10px;

                    }

                    .episode-image img {
                        width: 300px;
                        height: auto;
                        border-radius: 5px;
                    }
                    
                    .episode-title {
                        margin-bottom:20px;
                    }

                    .episode_meta {
                        font-size: 11px;
                        font-weight: 500;
                        margin-top: 20px;
                        margin-bottom: 10px;
                    }
                    .channel-description {
                        margin-bottom: 10px;
                        overflow-wrap: break-word;
                        word-wrap: break-word;
                        hyphens: auto;

                    }
                     .channel-copyright {
                             text-align: center;
                             margin: 10px;
                             font-size: small;

                    }
                     .channel-author {
                         font-size: small;
                         font-weight: 600;
                         margin-bottom: 10px;                    
                    }
                     .channel-subtitle {
                         font-size: small;
                         font-weight: 500;
                         margin-bottom: 20px;                    
                    }
                    .fa, .far, .fas {
                         font-family: "Font Awesome 5 Free";
                         margin-left: 5px;
                         margin-right: 5px;
                         display: initial;
                    }
                </style>
            </head>
            <body>
                <p class="explanation">
                        This is a podcast RSS feed generated by <xsl:value-of select="/rss/channel/generator"/>. It is meant for consumption by podcast feed readers using the URL in the address bar.
                    </p>
                <div id="content">
                    
                    <div id="channel-header">
                        <h1>
                            <xsl:if test="/rss/channel/image">
                                <div id="channel-image">
                                    <img>
                                            <xsl:attribute name="src">
                                                <xsl:value-of select="/rss/channel/image/url"/>
                                            </xsl:attribute>
                                            <xsl:attribute name="title">
                                                <xsl:value-of select="/rss/channel/image/title"/>
                                            </xsl:attribute>
                                        </img>                                  
                                </div>
                            </xsl:if>
                            <xsl:value-of select="/rss/channel/title"/>
                        </h1>
                        <div class="channel-subtitle">
                            <xsl:value-of select="/rss/channel/itunes:subtitle" disable-output-escaping="yes"/>
                        </div>
                        <div class="channel-description">
                            <xsl:value-of select="/rss/channel/description" disable-output-escaping="yes"/>
                        </div>
                        <div class="channel-author">
                            <xsl:value-of select="/rss/channel/itunes:author" disable-output-escaping="yes"/>
                        <a style="font-size: large;font-weight: 600;">
                                <xsl:attribute name="href">
                                    <xsl:value-of select="/rss/channel/link"/>
                                </xsl:attribute>
                                <xsl:attribute name="target">_blank</xsl:attribute>
                                <i class="fas fa-globe"></i>
                            </a>
                        </div>
                        
                           
                        
                    </div>
                    <xsl:for-each select="/rss/channel/item">
                        <div class="channel-item">
                           <div class="episode-title">
                            <h2>
                                <a>
                                    <xsl:attribute name="href">
                                        <xsl:value-of select="link"/>
                                    </xsl:attribute>
                          
                                    <xsl:attribute name="target">_blank</xsl:attribute>
                                    <xsl:value-of select="title"/>
                                </a>
                                <div class="episode-image">
                                     <img>
                                            <xsl:attribute name="src">
                                                <xsl:value-of select="itunes:image/@href"/>
                                            </xsl:attribute>
                                            <xsl:attribute name="title">
                                                <xsl:value-of select="title"/>
                                            </xsl:attribute>
                                      </img>
                                </div>

                            </h2>



                            <h3>
                                 <xsl:if test="itunes:author">
                                     <xsl:value-of select="itunes:author" disable-output-escaping="yes"/>
                                 </xsl:if>
                            </h3>
                           </div>
   
                         
                            <div class="episode-description">
                                
                            <xsl:if test="description">
                                <p>
                                    <xsl:value-of select="description" disable-output-escaping="yes"/>
                                </p>
                            </xsl:if>
                           
                            </div>



                            <p class="episode_meta">                                   
                                    <a>
                                        <xsl:attribute name="href">

                                            <xsl:value-of select="enclosure/@url"/>?ref=new_window
                                        </xsl:attribute>
                                        <xsl:attribute name="target">_blank</xsl:attribute>
                                        <i class="fas fa-download"></i>                           
                                        <xsl:value-of select='format-number(number(enclosure/@length div "1024000"),"0.0")'/>MB
                                    </a> | <i class="fas fa-stopwatch"></i>
                                    <xsl:value-of select="itunes:duration" disable-output-escaping="yes"/> | <i class="far fa-calendar"></i>

                                    <xsl:value-of select="pubDate" />
                            </p>
                        </div>
                    </xsl:for-each>
                </div>
                <div class="channel-copyright">
                    &#x24B8; <xsl:value-of select="/rss/channel/copyright"/>
                </div>
            </body>
        </html>
    </xsl:template>
</xsl:stylesheet>

For starters I want to know if this is kosher or if there is a better way of doing this by adding an audio player in the xsl file that would be dynamic for each post that would play the enclosed:url. #noob


Solution

  • You could add something like this into your template:

    <audio controls="controls" src="{enclosure/@url}" preload="none"></audio>
    

    This would be more general in that it would work even for feeds which do not have an audio player tag in their description.

    This uses controls="controls" instead of just controls is used to make it well-formed XML.