MODX Community

Filter getResources results when value of TV matches a defined criteria

Summary

I am looking for some assistance in using getResources to look at the contents of a TV (lets say its called “matchedValue” and only display results from a parent IF the TV matches a value I define in the call. The TV contains an array of ID numbers separated by a comma - so “12,14,70” for example.

I was thinking using &tvFilters=matchedValue==%14% would mean that of the results getResources returned - it would only display those matching “matchedValue” TV with value “14” included in the TV output… but this doesnt seem to work… it returns all results…?

Any ideas how I can get it to only show the results that match the defined variable value?

1 Like

You do have this, right?

&includeTVs=`1`

Also, make sure the &tvFilters property has back-ticks:

&tvFilters= `matchedValue==%14%`

And if your TV doesn’t have a prefix, you need this:

&tvPrefix=``
1 Like

and be aware, this would also show results with values for example like 140 or 114, everthing which contains 14

1 Like

Yeh, code I have is:

[[!getCache? &element=`getResources` &resources=`2` &tvFilters=`matchedValue ==%14%` &tpl=`myTpl` &depth=`0` &limit=`10` &includeTVs=`1` &processTVs=`0` &tvPrefix=`` &sortby=`RAND()` &first=`15` &dummyproperty=`[[!SessionIDContents]]` &includeTVList=`TV1,TV2, TV3` ]]
1 Like

Thanks - I just want a way to ONLY return results that match the value I specify of the TV matchedValue - is there a way? This might not the right approach I think perhaps?

1 Like

First, try adding backticks and taking out the space:

&tvFilters=`matchedValue==%14%`

You could certainly do it with a custom snippet. It depends a little on how badly you need the bells and whistles of getResources.

1 Like

Thanks Bob - I am already using the correct formatting - it just didnt paste well into this new forum :wink:

how do you paste in code correctly?

1 Like

Put three back-ticks above and below the code or indent the code by 4 spaces.

1 Like

OK - code is as below:

[[!getCache? &element=`getResources` &resources=`2` &tvFilters=`matchedValue==%14%` &tpl=`myTpl` &depth=`0` &limit=`10` &includeTVs=`1` &processTVs=`0` &tvPrefix=`` &sortby=`RAND()` &first=`15` &dummyproperty=`[[!SessionIDContents]]` &includeTVList=`TV1,TV2, TV3` ]]

It’s not working - as its displaying results that have no value on the TV ‘matchedValue’ … or… is that the issue… for results that have no value for this TV??? so they are displayed???

Confirmed still doesn’t work even if TV has a value of something that is not 14

Bruno - how can I get it to work, so that it only shows results for value ‘14’ - e.g. not ‘1’,‘140’,‘114’ etc… ??

Hi Bob - I need it to be a getResources call as it pulls in the relevant results to display - how could I use a custom snippet to refine the getResources selection?

I can’t think of any way to get the resources you want without either using a regular expression search, or pulling all the TV values and using PHP’s explode() function to convert them to an array. Unfortunately, I also can’t think of an easy way to integrate either of those methods with getResources.

Most of the actions of getResources are not all that difficult to duplicate in code. I could try to write you something that would work, but I’m confused by your use of the word ‘parent’ in your initial post. Do you want to display resources where the TV matches your value, or do you want to show the parent of each such resource?

Also, do you just want to display information from the resources, or do you need links to them?

It would help a lot to see your Tpl chunk.

Hi Bob.

So the current code it:

[[!getCache? &element=`getResources` &resources=`[[*Top10Featured]]` &tvFilters=`matchedValue==%14%` &tpl=`myTpl` &depth=`0` &limit=`10` &includeTVs=`1` &processTVs=`0` &tvPrefix=`` &sortby=`RAND()` &first=`15` &dummyproperty=`[[!SessionIDContents]]` &includeTVList=`TV1,TV2, TV3` ]]

So, basically - getResources looks at the TV “Top10Featured” which contains a comma seperated listed of resource IDs, These resource IDs are the resources it uses as the results, I then want to filter these results - Looking at these resource IDs, I only want getResources to outut those that have the value of TV “matchedValue” as 14, if for example they have no value, or another value that is not 14 (TV “matchedValue” is also a comma seperated list of resource IDs), then they are not to be displayed in the results getResources outputs - then the code has simple TPL and max results of 10 which are to be displayed in random order and I include the list of TVs I want the content to be displayed in the TPL I state “myTPL”. Does that make sense?

myTPL chunk is:

<!-- ITEM -->
<div class="workIndexGridItem">
<div class="workIndexGridItemProjectDeets">
<a title="Read more about [[+pagetitle]]" href="[[~[[+id]]]]">
<h4 class="workGridTitle">[[+pagetitle]]</h4>
<p class="workGridSubtext">[[+ELEMENT-2019Project-WorkIndexProjectBlurb]]</p>
</a>
</div>
<div class="workIndexProjectImageWrapper">
<a title="Read more [[+pagetitle]]" href="[[~[[+id]]]]"><img src="[[+ELEMENT-2019Project-WorkIndexCoverImage]]" alt="Read more about [[+pagetitle]]" title="Read more about [[+pagetitle]]" class="workindexProjectImage"></a>
</div>
<!-- Mobile text -->
<div class="workIndexGridItemMobileText">
<a title="Read more about [[+pagetitle]]" href="#">
<h4 class="workGridTitle">[[+pagetitle]]</h4>
</a>
</div>
<!-- end of Mobile text -->
</div>
<!-- end of ITEM -->

Give this a try:

[[!GetTopTen]]

Create a snippet called GetTopTen with this code:

/* GetTopTen snippet */
$output = '';
$tv1_id = 12; // correct this to ID of TV with 14 in it
$tv2_id = 13; // correct this to ID of ProjectBlurb TV
$tv3_id = 14; // correct this to ID of Image TV

$docs = $modx->getOption('resources', $scriptProperties, '', true);
$docs = explode(',', $docs);
$criteria = array();
$criteria['modTemplateVarResource.tmplvarid'] = $tv1_id;
$criteria['modTemplateVarResource.value:LIKE'] = '%14%';
$criteria['modTemplateVarResource.contentid:IN'] = $docs;

$criteria = $modx->newQuery('modTemplateVarResource', $criteria);
$criteria->limit(10);
$criteria->sortby('RAND()');
$tvrs = $modx->getCollectionGraph('modTemplateVarResource', '{"Resource":{}}', $criteria);

foreach($tvrs as $tvr) {
    $val = $tvr->get('value');
    $values = explode(',', $val);

    if (in_array('14', $values)) { /* make sure TV contains exactly 14 */
        /* Set resource placeholders */
        $placeholders = $tvr->Resource->toArray();
        
        /* Set ProjectBlurb placeholder */
        $val = $tvr->Resource->getTVValue($tv2_id);
        $placeholders['ELEMENT-2019Project-WorkIndexProjectBlurb'] = $val;
        
        /* Set image placeholder */
        $val = $tvr->Resource->getTVValue($tv3_id);
        $placeholders['ELEMENT-2019Project-WorkIndexCoverImage'] = $val;

        /* Add results to output */
        $output .= $modx->getChunk('myTpl', $placeholders);
    }
}

return $output;

Basically, this gets all TV1s containing 14 along with their resources, then it skips resources where TV1 contains 214, 140, etc.

Since you’re sorting at random, I don’t think getCache makes sense, but you can add it if you think you need it. Try this as is first, though.

FYI, this is a great example of why you should never use comma-separated TVs to hold data that you will be searching for. :wink:

you could also work with multiple ORs

which filters for
matchedValue LIKE '14,%' OR matchedValue LIKE '%,14' OR matchedValue LIKE '%,14,%' OR `matchedValue = '14'

Thanks bob / Bruno - I will give these 2 approaches a try…

Thanks Bob - Thanks for the code example - Afraid I dont think it will work as I dont think my explanation of what I need was clear enough - the use of TV1, TV2 was just to force getResources to inlclude the data of those TVs in the TPL that getResources uses to display the results - they are nothing to do with the selection of which resources to output as results. Below is the full call with all TV names as I am using them - I had made them general to help try and make it simpler to follow - so please ignore previous and use these blocks of code as what I am using:

[[!getCache? &element=`getResources` &resources=`[[*ELEMENT-WorkIndex-Top10Featured]]` &tvFilters=`ELEMENT-2019Project-WorkIndexSelections==%729%` &tpl=`ELEMENT-2019Work-Grid-ProjecTpl` &depth=`0` &limit=`10` &includeTVs=`1` &processTVs=`0` &tvPrefix=`` &sortby=`RAND()` &first=`15` &dummyproperty=`[[!SessionIDContents]]` &includeTVList=`ELEMENT-2019Project-WorkIndexCoverImage,ELEMENT-2019Project-WorkIndexProjectBlurb` ]]

And ELEMENT-2019Work-Grid-ProjecTpl code is:

<!-- ITEM -->
<div class="workIndexGridItem">
<div class="workIndexGridItemProjectDeets">
<a title="Read more about [[+pagetitle]]" href="[[~[[+id]]]]">
<h4 class="workGridTitle">[[+pagetitle]]</h4>
<p class="workGridSubtext">[[+ELEMENT-2019Project-WorkIndexProjectBlurb]]</p>
</a>
</div>    
<div class="workIndexProjectImageWrapper">
<a title="Read more [[+pagetitle]]" href="[[~[[+id]]]]"><img src="[[+ELEMENT-2019Project-WorkIndexCoverImage]]" alt="Read more about [[+pagetitle]]" title="Read more about [[+pagetitle]]" class="workindexProjectImage"></a>
</div>
<!-- Mobile text -->
<div class="workIndexGridItemMobileText">
<a title="Read more about [[+pagetitle]]" href="#">
<h4 class="workGridTitle">[[+pagetitle]]</h4>
</a>
</div>
<!-- end of Mobile text -->
</div>
<!-- end of ITEM -->

So - What I want in a nutshell - is to get GetResources to look at the contents of the TV called “ELEMENT-WorkIndex-Top10Featured” - which contains a comma sperated list of IDs, and then look at each of those resources from their IDs and check the value of TV called “ELEMENT-2019Project-WorkIndexSelections” (which again is a comma seperated list of IDs) and ONLY output them as results IF they match the value of TV “ELEMENT-2019Project-WorkIndexSelections” as written in the getResources call. So in this example, let say TV “ELEMENT-WorkIndex-Top10Featured” has a value of “10,20” - getResources looks at resources with ID 10 and 20, and looks at the TV “ELEMENT-2019Project-WorkIndexSelections” for each, lets say resource ID 10 has value of 730 for “ELEMENT-2019Project-WorkIndexSelections” and resource ID 20 has value of 729,730. This would mean, that getResources should output just resource ID 20, as this is the only resource ID from TV “ELEMENT-WorkIndex-Top10Featured”, that has TV “ELEMENT-2019Project-WorkIndexSelections” value matching the one on the call - e.g. 729.

What currently happens, is that getResources outputs BOTH resource IDs 10 and 20… so the scruntinising of TV “ELEMENT-2019Project-WorkIndexSelections” is not working…

Does that make sense?

Bruno - thanks for you example - I cant seem to work out how that would work in practice - any chance of an example? Would that approach work with the updated scenario i have outlined in this post?

P.S. Just had a play and got the “ELEMENT-2019Work-Grid-ProjecTpl” Chunk template to out the value of the resources TV “ELEMENT-2019Project-WorkIndexSelections” and its displaying as “729||730||740” rather than comma seperated as I have instructed that TV to output with… ? Is this the underlying issue perhaps? When I view the value of TV “ELEMENT-2019Project-WorkIndexSelections” on the actual resource front-end page it shows as “729,730,740” e.g. comma seperated…???

Also, If I change the getResources call to update

 &tvFilters=`ELEMENT-2019Project-WorkIndexSelections==%729%`

to become

 &tvFilters=`ELEMENT-2019Project-WorkIndexSelections==ABC`

Nothing changes… still outputs the same resources… so I dont think the &tvFilters element is doing anything!

OK, I think my snippet is very close to what you want, though it appears that the code needs to deal with four TVs, not three.

Please give me the IDs of these four TVs and I will modify the code.

ELEMENT-WorkIndex-Top10Featured
ELEMENT-2019Project-WorkIndexProjectBlurb
ELEMENT-2019Project-WorkIndexSelections
ELEMENT-2019Project-WorkIndexCoverImage

I’m afraid this makes no sense – they are the same TV and would always match:

check the value of TV called “ELEMENT-2019Project-WorkIndexSelections” (which again is a comma-separated list of IDs) and ONLY output them as results IF they match the value of TV “ELEMENT-2019Project-WorkIndexSelections”.

I assume that the second one is a property in the snippet tag rather than a TV and has a single value rather than a comma-separated list. I’m also assuming that you mean the TV ‘contains’ the value of the property rather than matching it. Let me know if I’m wrong.

Bruno’s suggestion is just a better way to specify the criteria for my search. It would eliminate the need for the validation loop.

Thanks Bob - re: the bit making no sense :wink: it does if you read on a few more words (see bolden bit)

check the value of TV called “ELEMENT-2019Project-WorkIndexSelections” (which again is a comma seperated list of IDs) and ONLY output them as results IF they match the value of TV “ELEMENT-2019Project-WorkIndexSelections” as written in the getResources call

So in the getResources call - I change the value I specifiy on differnet pages to fetch back different results - so in the example I have sent I am looking for matches of value 729 - on another page with anothet getResources call this value to match will be set as 734 for example.