Make relationship between articles from different container

Hi, I have two article containers named “Programs” and “Artist”.
Now I would like to assign the artist to the programs.
Could anyone tell me how is this possible to do?
Thanks in advance.

What exactly are these “article containers”?


If both “Programs” and “Artists” are normal MODX resources, then you could use a TV of input type “Listbox (Multi-Select)” and use a @-binding (for example @SELECT) for the field “Input Option Values”.

Or you could try the extra SuperBoxSelect (if there are a lot of “Artist” resources):

https://extras.modx.com/package/superboxselect

These are containers of “Article” Extra.

[[pdoResources?
    &parents=`3`
    &tpl=`program_item`
    &includeTVs=`assign_artist, article_type, date_from, expire_date, articlestags, post_feature_image`
    &processTVs=`1`
    &where=`{
        "assign_artist: LIKE ": "%[[*id]]%"
    }`
]]

And this code works for display the related articles in the author page.
But now the problem is “multiselect” tv field display selected item’s id instead of value/label.
Input Assigned to : [[+tv.assign_artist]]
Output Assigned to : 35||36
Expected output Assigned to : James Jonathon, Mark Neel
image

You need to run pdoResources a second time to query the names of the artists.

For example if [[+tv.assign_artist]] is 35||36, then use the output modifier “replace” to convert the value into a comma separated list of IDs: [[+tv.assign_artist:replace=`||==,`]]35,36.

Then use this for the " &resources" property of the pdoResources call like this (if the artist name is stored in the field “pagetitle”):

[[pdoResources?
    &tpl=`@INLINE {{+pagetitle}}`
    &resources=`[[+tv.assign_artist:replace=`||==,`]]`
    &parents=`0`
    &outputSeparator=`, `
    &limit=`0`
]]

This can give you wrong results. For example if the value of [[*id]] is 1, if will also match values like 11, 12, 21 etc.

What’s the solution of this?

There are different solutions. One is to use FIND_IN_SET instead:

[[pdoResources?
    ...
    &includeTVs=`assign_artist, article_type, date_from, expire_date, articlestags, post_feature_image`
    &where=`FIND_IN_SET([[*id]], REPLACE(assign_artist, '||', ',')) > 0`
]]

Yes, It displays the selected value(pagetitle), but how to add url to this name?

You have to change the template &tpl.

Use &tpl=`@INLINE <a href="{{~{{+id}}}}">{{+pagetitle}}</a>` (or [[~[[+id]]]] in a separate chunk).

Thank you so much for your help. I genuinely appreciate the time and effort you put into assisting me. Your support has been invaluable.

@halftrainedharry
I am facing a problem with this.
When no artist is selected it shows all the artists from the list.

[[!pdoResources:!empty=`
    <li>
        Artist: 
        <span>
            [[!pdoResources?
                &tpl=`@CODE:<a href="{{~{{+id}}}}">{{+pagetitle}}</a>`
                &resources=`[[+tv.assign_artist:replace=`||==,`]]`
                &parents=`0`
                &outputSeparator=`, `
            ]]
        </span>
    </li>
`?
    &tpl=`@CODE:<a href="{{~{{+id}}}}">{{+pagetitle}}</a>`
    &resources=`[[+tv.assign_artist:replace=`||==,`]]`
    &parents=`0`
    &outputSeparator=`, `
]]

You probably have to test the value of the TV, instead of the result from pdoResources.

Something like this:

[[+tv.assign_artist:!empty=`
    <li>
        Artist: 
        <span>
            [[pdoResources?
                &tpl=`@CODE:<a href="{{~{{+id}}}}">{{+pagetitle}}</a>`
                &resources=`[[+tv.assign_artist:replace=`||==,`]]`
                &parents=`0`
                &outputSeparator=`, `
            ]]
        </span>
    </li>
`]]

(No need to call pdoResources uncached here!)

Thanks for your kind.
It works now.

[[pdoResources:empty=`
    <h3 class="bg-white pb-10 pl-[15%] pt-5">No artist found!</h3>
`?
    &parents=`17`
    &includeTVs=`article_type, date_from, expire_date, post_feature_image, artist, artist_type`
    &where=`[[!getArtist]]`
    &tpl=`artist_item_tpl`
    &sortby=`pagetitle`
    &sortdir=`ASC`
    &limit=`20`
]]

getArtist

<?php
$where = [];
//read search parameter
$search_string = $_GET['search'] ?? ''; 

//do some sanitizing
$search_string = $modx->sanitizeString($search_string);
$search_string = strip_tags($search_string);
$search_string = trim($search_string);

if (mb_strlen($search_string) > 2){ //check min search length
    //filter by search term
    $where[] = ["pagetitle:LIKE" => "%" . $search_string . "%", "OR:content:LIKE" => "%" . $search_string . "%" ];
}


return json_encode($where);

Is this possible to add pagination using pdoResources?
or I need to use pdoPage?
If so, how can I do so?

Use pdoPage.
pdoPage internally uses pdoResources by default. Keep all the properties from the pdoResources call.
And just add the pagination specific properties.

When I use pdoPage it shows an error.
Is it because I am using an Article Container?

[[pdoPage:empty=`
  <h3 class="bg-white pb-10 pl-[15%] pt-5">No artist found!</h3>
`?
  &parents=`17`
  &includeTVs=`article_type, date_from, expire_date, post_feature_image, artist, artist_type`
  &where=`[[!getArtist]]`
  &tpl=`artist_item_tpl`
  &sortby=`pagetitle`
  &sortdir=`ASC`
  &limit=`20`
]]
[[!+page.nav]]


Check the server error log. What is the exact error message?

No, this should still work.


Unrelated to the error, but pdoPage always has to be called uncached (with the ! in the tag → [[!pdoPage? ...]]

This code works but pagination is not working properly.
I have more than 100 items, If I set the limit is equal 5, it shows 2 page numbers. But If I set limit to 10 doesn’t show any pagination.
Is this because of the Article container?
I also changed the value of “Pages Limit” to 999.

[[!getPage:empty=`
    <h3 class="bg-white pb-10 pl-[15%] pt-5">No artist found!</h3>
`?
    &element=`pdoResources`
    &parents=`17`
    &includeTVs=`article_type, date_from, expire_date, post_feature_image, artist, artist_type`
    &where=`[[!getArtist]]`
    &tpl=`artist_item_tpl`
    &sortby=`pagetitle`
    &sortdir=`ASC`
    &limit=`5`
]]
[[!+page.nav]]

Are these 100 items with or without the filter conditions you add in &where=`[[!getArtist]]` ?
Or ask differently, how many items are returned without getPage and the property “limit” set to “0” → &limit=`0`?

It could be that if the pdoResources query only returns (let’s say) 7 results, you would get 2 pages (if one page is limited to max. 5 results). And no pagination (if one page is limited to max. 10 results, because everything would fit on one page).

I also have search field, that’s because I had to write getArtist snippet.

<form action="" method="get" class="search-form relative flex">
    <input type="text" name="search" placeholder="Type search key" class="flex-1" value="[[!searchValueSnippet]]">
</form>

Snippet, getArtist

<?php
$where = [];
//read search parameter
$search_string = $_GET['search'] ?? ''; 

//do some sanitizing
$search_string = $modx->sanitizeString($search_string);
$search_string = strip_tags($search_string);
$search_string = trim($search_string);

if (mb_strlen($search_string) > 2){ //check min search length
    //filter by search term
    $where[] = ["pagetitle:LIKE" => "%" . $search_string . "%", "OR:content:LIKE" => "%" . $search_string . "%" ];
}

return json_encode($where);

Try this: Add the property &setTotal=`1` to the snippet call.

[[!getPage?
    &element=`pdoResources`
    &setTotal=`1`
    ...
]]

I believe this is necessary, if you combine “pdoResources” with “getPage” (instead of “pdoPage”).


Maybe also (temporarily) add the placeholder [[!+total]] to the resource, to check if the total amount of results is set correctly.