Search

If I want to display one example of recent work on a page, selected from the five most recent entries, is there a way to filter one datasource to accomplish this, or would I limit one datasource to 5 entries, then send an output parameter from this DS to filter another one?

I think you'll need two datasources.

  1. Limit to 5 ordered by date and output parameter system-id
  2. Filter by output parameter from first with sort order set to random.

Thanks, Lewis; I thought that might be right.

You could do the limit to five and use a DS Filter results as you mention, then maybe do a math.random on the position() of the $ds.datasource.id's in the param pool which would give you one of your filtered Id's to work with?

Math.random solution here: http://getsymphony.com/discuss/thread/81429/

Lewis' much simpler :)

Cheers, moonoo2. It's always nice to know how to do it the hard way!

Mark's solution is simpler, though Andrew's solution is more efficient.

Mark's method requires two (chained) data sources, which in turn requires more processing and several more DB queries to achieve.

Andrew's approach requires one data source and a little bit of XSLT magic.

Ninja! :) almost.

Doing it the 'more efficient' way, don't I have to output 4 extra unwanted items in my XML (or should I be less concerned about this than the extra SQL queries)?

If so, is this the idea:

<xsl:variable name="randonetofive"><xsl:value-of select="(floor(math:random()*5) mod 5) + 1" /></xsl:variable> <xsl:value-of select="testrand/entry[position() = $randonetofive]" />

If not, please could you maybe explain Comment #5 in a little more detail?

Ta,
D

Yes, I believe that you have got the principles down here.

Ace.

You could use the datasource as is, and then customise it after the entries have been returned, and only return the single random entry.

I've done this quite a few times. Not very difficult.

This should work:

public function grab(&$param_pool = NULL)
{
    $result = new XMLElement($this->dsParamROOTELEMENT);

    try{
        include(TOOLKIT . '/data-sources/datasource.section.php');
    }
    catch(FrontendPageNotFoundException $e){
        // Work around. This ensures the 404 page is displayed and
        // is not picked up by the default catch() statement below
        FrontendPageNotFoundExceptionHandler::render($e);
    }
    catch(Exception $e){
        $result->appendChild(new XMLElement('error', $e->getMessage()));
        return $result;
    }

    // Create a new root element
    $newresult = new XMLElement($this->dsParamROOTELEMENT);

    // Get the entries
    $entries = $result->getChildren();

    // Choose a random key
    $key = array_rand($entries, 1);

    // Append it to the new root element
    $newresult->appendChild($entries[$key]);

    // Unset the old one
    unset($result);

    if($this->_force_empty_result) $newresult = $this->emptyXMLSet();

    // Return the new root
    return $newresult;
}

Edited: Removed code from the function I copied, silly me.

Thanks, designermonkey -- I'll look at that when I've got a spare afternoon (it looks a bit scary to me).

Forgot to mention, you need to change the allowEditorToParse function to return false, to block overwriting by the UI.

It's not too scary, just replace the function in your datasource. It is untested though.

You could also let the DS select the newest few items and use the following XSLT to shuffle them:

<xsl:template match="data">
    <xsl:apply-templates select="testrand/entry">
        <xsl:sort select="math:random()" />
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="testrand/entry">
    <xsl:value-of select="content"/>
</xsl:template>

<xsl:template match="testrand/entry[position() &gt; 1]" />

This iterates over all the items, orders them randomly and then picks the first one only.

Be sure to add the math namespace to your XML first though:

<xsl:stylesheet version="1.0"
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:math="http://exslt.org/math"
    extension-element-prefixes="math">

@phoque

Good stuff is simple and elegant. Your solution is good :)

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