Search

I've been running into some problems with the Tag field as noted here. Whilst all things rev6 are developing, I'm wondering if it's possible to achieve the same results in another way.

I've been using the Tag field to generate a list of separate nodes which I can then manipulate into a simple unordered list in XHTML. It doesn't seem that any of the other fields spit out entered data this way, right? (Would love to be wrong on this point...)

If so, is there a 'Oh my, XSLT is truly amazing' way to break up a comma separated list of data from a Textarea field into separate list items? I'm guessing there might be but my mojo ain't that strong yet.

Thanks in advance for any help, guidance, or counseling ;)

Best, Clayton

Are you using a text-formatter like Textile? If yes, you could set up a textfield and enter your data separated by pipes. Using Textile, your content (e. g. one | two | three) will be converted into a table that can be parsed with XSLT.

Thanks Nils! That's interesting. I've been using Markdown, but could setup Textile if needed. So in this case I would be yanking the content out of <td> elements within a parent XML node?

A slightly modified template I found through the oh-so-useful Google:

<xsl:param name="tags" select="'Information Architechure, Cheese, Symphony, Overture'"/>

<xsl:template match="/">

  <ul>
    <xsl:call-template name="tokenize">
      <xsl:with-param name="tags" select="$tags"/>
      <xsl:with-param name="delim" select="', '"/>
    </xsl:call-template>
  </ul>

</xsl:template>


<xsl:template name="tokenize">

  <xsl:param name="tags"/>
  <xsl:param name="delim"/>

  <xsl:choose>
    <xsl:when test="contains($tags, $delim)">
      <li><xsl:value-of select="substring-before($tags, $delim)" /></li>
      <xsl:call-template name="tokenize">
        <xsl:with-param name="tags" select="substring-after($tags, $delim)"/>
        <xsl:with-param name="delim" select="$delim"/>
      </xsl:call-template>
    </xsl:when>
    <xsl:otherwise>
      <li><xsl:value-of select="$tags"/></li>
    </xsl:otherwise>
  </xsl:choose>

</xsl:template>

I created some templates that will take comma separated values and use recursion to create a list of select options. Perhaps you can use something like this:

<xsl:template match="data">
    <select name="fields[type]">
        <xsl:call-template name="content-type-options">
            <xsl:with-param name="csv" select="'Intro, Section, Subsection, Subsubsection, Appendix'"/>
            <xsl:with-param name="selected" select="type/item"/>
        </xsl:call-template>
    </select>
</xsl:template>

<xsl:template name="content-type-options">
    <xsl:param name="csv" select="'Intro, Section, Subsection'"/>
    <xsl:param name="selected" select="'Body'"/>
    <xsl:param name="options">
        <xsl:call-template name="option-values">
            <xsl:with-param name="input" select="$csv"/>
            <xsl:with-param name="selected" select="$selected"/>
        </xsl:call-template>
    </xsl:param>
    <xsl:copy-of select="$options"/>
</xsl:template>

<xsl:template name="option-values">
    <xsl:param name="selected" select="'Section'"/>
    <xsl:param name="input"/>
    <xsl:param name="value">
        <xsl:choose>
            <xsl:when test="contains($input,',')">
                <xsl:value-of select="normalize-space(substring-before($input,','))"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="normalize-space($input)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="remaining-values" select="normalize-space(substring-after($input,','))"/>
    <option value="{$value}">
        <xsl:if test="$value = $selected">
            <xsl:attribute name="selected">selected</xsl:attribute>
        </xsl:if>
        <xsl:value-of select="$value"/>
    </option>
    <xsl:if test="$remaining-values != ''">
        <xsl:call-template name="option-values">
            <xsl:with-param name="input" select="$remaining-values"/>
            <xsl:with-param name="selected" select="$selected"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

So, to create list items, you would need something like this:

<xsl:template match="data">
    <ul>
        <xsl:call-template name="csv-to-list-items">
            <xsl:with-param name="csv" select="'Intro, Section, Subsection, Subsubsection, Appendix'"/>
            <xsl:with-param name="selected" select="type/item"/>
        </xsl:call-template>
    </ul>
</xsl:template>

<xsl:template name="csv-to-list-items">
    <xsl:param name="csv" select="'Intro, Section, Subsection'"/>
    <xsl:param name="selected" select="'Body'"/>
    <xsl:param name="options">
        <xsl:call-template name="list-items">
            <xsl:with-param name="input" select="$csv"/>
            <xsl:with-param name="selected" select="$selected"/>
        </xsl:call-template>
    </xsl:param>
    <xsl:copy-of select="$options"/>
</xsl:template>

<xsl:template name="list-items">
    <xsl:param name="selected" select="'Section'"/>
    <xsl:param name="input"/>
    <xsl:param name="value">
        <xsl:choose>
            <xsl:when test="contains($input,',')">
                <xsl:value-of select="normalize-space(substring-before($input,','))"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="normalize-space($input)"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:param>
    <xsl:param name="remaining-values" select="normalize-space(substring-after($input,','))"/>
    <li id="nav_{$value}">
        <xsl:if test="$value = $selected">
            <xsl:attribute name="class">selected</xsl:attribute>
        </xsl:if>
        <xsl:value-of select="$value"/>
    </option>
    <xsl:if test="$remaining-values != ''">
        <xsl:call-template name="list-items">
            <xsl:with-param name="input" select="$remaining-values"/>
            <xsl:with-param name="selected" select="$selected"/>
        </xsl:call-template>
    </xsl:if>
</xsl:template>

I haven't tested this, but see how far this takes you.

Oh, I'd forgotten I had already posted something like this: CSV to XML Template, which is a much more abstracted template that can output whatever element you specify with the element-name parameter.

Thanks Egor! Thanks Stephen! Let me see if I can wrap my head around these. They look like they may be exactly what I need.

Best, Clayton

Hey Clayton,

I just realized data-source filtering would be a little trickier with the above methods, if you required that. But then, perhaps this could work?

Thanks Egor. Thankfully, DS filtering won't be an issue for this particular data but I do appreciate the pointer on the regexp option. Regexp is definitely something I need to learn more about...

Create an account or sign in to comment.

Symphony • Open Source XSLT CMS

Server Requirements

  • PHP 5.3-5.6 or 7.0-7.3
  • PHP's LibXML module, with the XSLT extension enabled (--with-xsl)
  • MySQL 5.5 or above
  • An Apache or Litespeed webserver
  • Apache's mod_rewrite module or equivalent

Compatible Hosts

Sign in

Login details