Search

Hi,

Im trying to filter a data source for all entries where a field != “something”

I cant seem to get it right.

help please :)

Jeff

(Topic title changed to be more descriptive — hope that’s cool. Nick.)

What does the whole line of code look like?

I’m sure something similar to this would work for you.. not sure though.. worth a try for my first time out giving back to the community of symphony so take it all with a pinch of salt!

  <xsl:choose>
        <xsl:when test="a-field != 'something'">        
            <p>Something Else</p>
        </xsl:when>
        <xsl:otherwise>
            <p>Something</p>
        </xsl:otherwise>
    </xsl:choose>

Hi Jeff,

Unfortunately this is a limitation of Data Sources — there is no “not” operator. Sometimes you can work around this, for example a Date field you can specify the reverse range for the one you don’t want; or a Number field if you don’t want entries more than 10 you can filter less than 9.

If you’re using a Text field, filtering on a plain text value, then you might be able to use a regular expression. A filter matching on something might look like:

regexp:^nick

This will filter entries where the text value begins with (^) the phrase nick. The reverse of this might look like:

regexp:^(?!nick)

(from here and here).

Therefore let’s say you’re passing a URL querystring parameter to a page ?omit=Nick and on this page you want to filter your People data source removing anyone called Nick (why oh why would anybody want to do that…?!):

regexp:^(?!{$url-omit})

I think. I haven’t tried it so, you know, it may not work at all. But in theory…

Some other references for using the regexp: in filters:

If filtering in the Data Source itself doesn’t work, then moonoo2’s suggestion is the next best thing. What you lose in performance (since your Data Source is returning all entries from the database) you gain in flexibility of filtering whatever way you wish in the XSLT.

If you are using the TextBox field extension you can use the not: prefix to filter entries on that field.

Moonoo I want the data source to remove them to keep the xml limited.

brendo its a select box field, would that still work?

regexp:^(?!nick) doesnt seem to be working Im gonna go grab a coffee and try some more.

Thanks for all your help :)

I’ve just checked the code and the Select Box certainly supports the regexp:... syntax. Definitely Select Box and not Select Box Link?

I wasn’t entirely sure of the “not” syntax. What if you try a simpler starter:

regexp:^abc

See if that filters those starting with abc.

regexp:^abc this works.

but this doenst regexp:^(?!abc)

Remember you need to use MySQL regex, not perl. Not trying to imply that is why your regex isn’t working, but could be the cause.

not regexp^abc doesnt work either

NOT REGEXP '^abc' ?

And no, Textbox field is simply a an extended Text Input field, Select Box Link is something entirely different.

nope, ill just do it another way i guess.

Unfortunately this is a limitation of Data Sources — there is no “not” operator.

Is this still the case, I need to remove a Featured Article from a list of articles?

If it’s just one article, I’d do it in XSLT.

Core team: I understand this is built in to Symphony 3, which is great. How hard would this be to get into the final 2 release? It seems to be a regular request…

If it’s just one article, I’d do it in XSLT.

I don’t want the results list to have a record less on the first page. I might implement a checkbox to make a article the featured article and then filter on this value being No.

Did you see this thread? I modified the core code to add a notregexp: option to satisfy a similar need.

Thanks @wisolman assume modifying the core means you need to be careful when updating? Would you be willing share a code example?

At about line 228 in class.field.php replace this

protected static function isFilterRegex($string){
    if(preg_match('/^regexp:/i', $string)) return true;             
}

with this

protected static function isFilterRegex($string){
    if(preg_match('/^regexp:/i', $string) || preg_match('/^notregexp:/i', $string))
        return true;
}

At about line 65 in field.textarea.php replace this

if (self::isFilterRegex($data[0])) {
    $this->_key++;
    $pattern = str_replace('regexp:', '', $this->cleanValue($data[0]));
    $joins .= "
        LEFT JOIN
            `sym_entries_data_{$field_id}` AS t{$field_id}_{$this->_key}
            ON (e.id = t{$field_id}_{$this->_key}.entry_id)
    ";
    $where .= "
        AND t{$field_id}_{$this->_key}.value REGEXP '{$pattern}'
    ";

with this

if (self::isFilterRegex($data[0])) {
    $this->_key++;
    if (preg_match('/^regexp:/i', $data[0])) {
        $pattern = str_replace('regexp:', '', $this->cleanValue($data[0]));
        $regex = 'REGEXP';
    } else {
        $pattern = str_replace('notregexp:', '', $this->cleanValue($data[0]));
        $regex = 'NOT REGEXP';
    }
    $joins .= "
        LEFT JOIN
            `sym_entries_data_{$field_id}` AS t{$field_id}_{$this->_key}
            ON (e.id = t{$field_id}_{$this->_key}.entry_id)
    ";
    $where .= "
        AND t{$field_id}_{$this->_key}.value {$regex} '{$pattern}'
    ";

Now you can use notregexp: in the DS filter field in a similar manner as regexp:. Note that this will only allow you to filter on a textarea field. If you want to filter on other fields you will have to make a similar modification to the file for that field.

I’ve hacked this together for a specific project, but I’ve been meaning to put together a more comprehensive solution, in my datasource I have the following in a tag list filter:

{$category!all}

This says, if the category parameter does not exist, assume that it is “all” - ie, if the $category parameter exists, and it is not “all”, use it to filter, otherwise ignore the filter.

This required a little core hacking (beware, the following is messy and was only intended for the purpose of a single website)

in /symphony/lib/toolkit/class.datasource.php::__processParametersInString I added the following conditional and code around the colon handler:

                // conditional added by Liam Egan June 18
                // added support for ! switch for if a value is equal to something, omit it
                // should be extended to support everything that the : switch does (arrays, dunamic values etc.).
                if(strpos($cleaned, '!') > 0)
                {
                    $bits = preg_split('/!/', $cleaned, -1, PREG_SPLIT_NO_EMPTY);

                    $var = trim($bits[0],'$');
                    $notval = $bits[1];

                    $replacement = $this->__findParameterInEnv($var, $env);

                    if($replacement == $notval)
                    {
                        $replacement = '';
                    }

                    if($escape == true) $replacement = urlencode($replacement);
                    $value = str_replace($source, $replacement, $value);

                } else
                {
                        ...

Thanks for the examples really appreciate your help. I have just implented @wisolman example.

Many Thanks

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