Diazo Recipes

Diazo and XSL recipes for special usecases.

Add attributes on the fly

The example add target=”_blank” to all links in a portlet with the class portlet-collection-links.

<?xml version="1.0" encoding="UTF-8"?>
<rules
    xmlns="http://namespaces.plone.org/diazo"
    xmlns:css="http://namespaces.plone.org/diazo/css"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform">


    <!-- add target="_blank" to all links in portlet-collection-links -->
    <xsl:template match="//dl[contains(@class,'portlet-collection-links')]//a">
      <a target="_blank"><xsl:apply-templates select="./@*[contains(' href title class rel ', concat(' ', name(), ' '))]"/><xsl:value-of select="." /></a>
    </xsl:template>


    <!-- theme wrapper, to prevent theming ZMI -->
    <rules css:if-content="#visual-portal-wrapper">

      [...]

    </rules>
</rules>

This should also work, but does not if the selected node has already child notes.

 <xsl:template match="//dl[contains(@class,'portlet-collection-links')]//a">
     <xsl:attribute name="target">_blank</xsl:attribute><xsl:copy-of select="." />
</xsl:template>

Then you become the follwing error:

XSLTApplyError: xsl:attribute: Cannot add attributes to an element if children have been already added to the element.

At diazo.org is another way described in the recipes: http://docs.diazo.org/en/latest/recipes/adding-an-attribute/index.html

<?xml version="1.0" encoding="UTF-8"?>
<rules xmlns="http://namespaces.plone.org/diazo"
       xmlns:css="http://namespaces.plone.org/diazo/css"
       xmlns:xsl="http://www.w3.org/1999/XSL/Transform">

    <replace css:theme="#target" css:content="#content" />

    <xsl:template match="a">
        <xsl:copy>
            <xsl:attribute name="target">_blank</xsl:attribute>
            <xsl:copy-of select="@*" />
            <xsl:apply-templates />
        </xsl:copy>
    </xsl:template>

</rules>

Add CSS class depending on existing portal-columns

This adds a css class for every existing portal-column to the body tag. If portal-column-one exist we add col-one, if portal-column-content exsists we add col-content and if portal-column-two exists we add col-two.

<before theme-children="/html/body" method="raw">
  <xsl:attribute name="class"><xsl:value-of select="/html/body/@class" /><xsl:if css:test="#portal-column-one"> col-one</xsl:if><xsl:if css:test="#portal-column-content"> col-content</xsl:if><xsl:if css:test="#portal-column-two"> col-two</xsl:if></xsl:attribute>
</before>

This can be used to change the grid layout like this

The following example shows the scss for compass, which define different grid columns depending on the body classes.

body.col-one.col-content.col-two #content-wrapper {
  @include container;

  #portal-column-content {
    @include column(12);
    @include prepend(4.5);
  }

  #portal-column-one {
    @include column(4.5);
    @include pull(16.5);
  }

  #portal-column-two {
    @include column(4.5, true);
  }
}
body.col-one.col-content #content-wrapper {
  @include container;

  #portal-column-content {
    @include column(16.5, true);
    @include prepend(4.5);
  }

  #portal-column-one {
    @include column(4.5);
    @include pull(21, true);
  }
}

Move plone elements around

Sometimes one need to move Plone elements from one place to another or merge some elements together. In the following example we merge the language flags together with the document actions.

<replace css:content-children=".documentActions > ul">
  <xsl:for-each select="//*[@class='documentActions']/ul/li">
    <xsl:copy-of select="." />
  </xsl:for-each>
  <xsl:for-each select="//*[@id='portal-languageselector']/*">
    <xsl:copy-of select="." />
  </xsl:for-each>
</replace>

Remove the value of the searchButton

Sometimes it is usefull to remove the value (text) of the search button, for example if you whant an image only search button. The following XSL code replace the value of searchButton with an empty string.

<xsl:template match="//div[@id='portal-searchbox']//input[@class='searchButton']/@value">
  <xsl:attribute name="value"></xsl:attribute>
</xsl:template>

This special case can also be solved with pure CSS like so:

.searchButton{
  text-indent: -10000px;
}