Skip to content

Sharing Playlists

Via mbzlists

You can share lists that are hosted on mbzlists in following ways:

  1. Share a view only url.
  2. Share an editable url for lists that you have opened in edit mode. This can be used to edit the list content.
  3. Share a list to be listed on the public lists page of the app.

All these options are available when you click the 'share' button on any playlist.

Via XSPF file

You can share XSPF playlists by directly embedding them in your blog or web pages without depending on mbzlists web app. There are two broad ways to do this. You can either transform the XSPF file statically in HTML to embed, or use the mbzlists-embed library to embed it dynamically.

We will work with this playlist and assume you have the XSPF file downloaded locally.

Warning

Images that are added to a playlist via mbzlists web app are still referenced using their mbzlists urls. This will change in the future.

Dynamic embed is the easiest and recommended way, and we will start from there.

Dynamic embedding

We will use mbzlists-embed library to do this like shown below:

<script src="https://unpkg.com/mbzlists-embed@latest/dist/mbzlists-embed.min.js"></script>

<div data-mbzlists-src="/usage/sample-list.xspf" data-mbzlists-style="fancy"></div>

<script>MbzlistsEmbed.autoEmbed();</script>

This will result in the following output:

You can customize the visual style of the embed. A few examples are here using an older version (v0.1.2) of the library. The library's README contains the latest features and usage instructions.

Static embedding

Instead of using client side scripts, you can use XSLT to transform playlist files to HTML. Here is an example XSL:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:mbzlists="http://docs.lepisma.xyz/mbzlists/ns/1.0/"
                xmlns:xspf="http://xspf.org/ns/0"
                exclude-result-prefixes="mbzlists xspf xs"
                version="2.0">

  <xsl:output method="html" indent="yes" encoding="UTF-8"/>

  <xsl:template match="/">
    <html>
      <head>
        <title><xsl:value-of select="/xspf:playlist/xspf:title"/></title>
        <link rel="stylesheet" href="https://unpkg.com/sakura.css/css/sakura.css" type="text/css"/>
      </head>
      <body>
        <h1><xsl:value-of select="/xspf:playlist/xspf:title"/></h1>
        <p><strong>Creator: </strong> <a href="{/xspf:playlist/xspf:info}"><xsl:value-of select="/xspf:playlist/xspf:creator"/></a></p>
        <p><strong>Date: </strong>
          <xsl:value-of select="format-dateTime(xs:dateTime(//xspf:date), '[MNn] [D], [Y] [H01]:[m01] [PN]')"/>
        </p>
        <xsl:apply-templates select="//mbzlists:blocks/*"/>
      </body>
    </html>
  </xsl:template>

  <xsl:template match="mbzlists:paragraph">
    <p>
      <xsl:value-of select="." disable-output-escaping="yes"/>
    </p>
  </xsl:template>

  <xsl:template match="mbzlists:header">
    <xsl:element name="h{ @level }">
      <xsl:value-of select="."/>
    </xsl:element>
  </xsl:template>

  <xsl:template match="mbzlists:mbrecording">
    <div>
      <p>
        🎵 
        <strong>
          <a href="https://musicbrainz.org/recording/{@mbid}">
            <xsl:value-of select="mbzlists:title"/>
          </a>
        </strong>
        by 
        <a href="https://musicbrainz.org/artist/{mbzlists:artist/@mbid}">
          <xsl:value-of select="mbzlists:artist"/>
        </a>
        — 
        <em>
          <a href="https://musicbrainz.org/release/{mbzlists:release/@mbid}">
            <xsl:value-of select="mbzlists:release"/>
          </a>
        </em>
      </p>
    </div>
  </xsl:template>

  <xsl:template match="mbzlists:list">
    <xsl:choose>
      <xsl:when test="@style='ordered'">
        <ol>
          <xsl:apply-templates select="mbzlists:listItem"/>
        </ol>
      </xsl:when>
      <xsl:when test="@style='unordered'">
        <ul>
          <xsl:apply-templates select="mbzlists:listItem"/>
        </ul>
      </xsl:when>
      <xsl:when test="@style='checklist'">
        <ul>
          <xsl:for-each select="mbzlists:listItem">
            <li>
              <input type="checkbox">
                <xsl:if test="@checked='true'">
                  <xsl:attribute name="checked">checked</xsl:attribute>
                </xsl:if>
              </input>
              <xsl:value-of select="mbzlists:listContent"/>
            </li>
          </xsl:for-each>
        </ul>
      </xsl:when>
    </xsl:choose>
  </xsl:template>

  <xsl:template match="mbzlists:listItem">
    <li>
      <xsl:value-of select="mbzlists:listContent"/>
      <xsl:apply-templates select="mbzlists:list"/>
    </li>
  </xsl:template>

  <xsl:template match="mbzlists:image">
    <figure>
      <img src="{mbzlists:file/@url}"/>
      <xsl:if test="@caption != ''">
        <figcaption><xsl:value-of select="@caption"/></figcaption>
      </xsl:if>
    </figure>
  </xsl:template>

  <xsl:template match="mbzlists:quote">
    <blockquote>
      <p><xsl:value-of select="."/></p>
      <footer><i><xsl:value-of select="@caption"/></i></footer>
    </blockquote>
  </xsl:template>

</xsl:stylesheet>

When run on our example playlist, this HTML is generated. A few more examples of XSL based transformations are in this post.

You can also write extensions in, say, Python and make the conversion step also run a resolver like YouTube so as to embed YouTube links in the HTML.