Jump to content

Sorting by Related Page Count

Recommended Posts

Hey folks, I'm attempting to order a list of subjects based on the number of pages (not child pages) that link to each subject. The end result will look like this:

portrait — 120 items

landscape — 78 items

trees — 42 items 

beards — 8 items


I've been digging through the archive here, but I can't seem to find a solution. The issue is that I'm using wire('page')->find to get the list of subjects, and then getting the number of linked items inside the foreach — here's my code:

$subjects = wire('page')->find("template=subject, sort=title");
foreach ($subjects as $subject) {
$artwork = rendersubjectArtworkList(findartworks("subjects=$subject, limit=1"));
$count = findartworks("subjects=$subject")->count;

I can't figure out how to either combine my queries or re-sort the list after the call. Any ideas? 

Thanks so much for any help!

Share this post

Link to post
Share on other sites

How have you linked the pages to the subjects? WIth which field(s)? Do you use an InputfieldPage for that?

What does this function do: findartworks("subjects=$subject, limit=1") ?  You call it two times.

Share this post

Link to post
Share on other sites

Assuming your artworks have a template named 'artworks' and a select/ multiselect field 'subjects' of type page, where you define the type (subject) you could do the following:

$subjects = $pages->find("template=subject, sort=title")->each('title'); // get the titles of subjects (pages)
foreach ($subjects as $subject)
$artworks = $pages->find("template=artworks, subjects=$subject");
 echo $subject.' — '.$artworks->count;
  • Like 4

Share this post

Link to post
Share on other sites

Hi Horst! Excellent questions — 

I've got pages with two different templates: artworks, and subjects. On the artwork pages, I'm using a page field (set to allow multiple pages using AsmSelect) to link to 


kixe — that does work, but the end result is still ordered by title, and I'm attempting to reorder the list by $artworks->count; from highest to lowest. 

I'll kick it around more today, thanks for your input!

Share this post

Link to post
Share on other sites

I think this must work:

$pa = new PageArray();                                     // use a PageArray to collect all subject pages
foreach($pages->find("template=subject") as $subject) {    // iterate over all subject pages
    $subject->set('myCount', $pages->find("template=artworks, subjects=$subject")->count);   // add a temporary property to it that holds the total number of linked items
    $pa->add($subject);                                    // add it to the PageArray
foreach($pa->sort("-myCount") as $item) {                  // sort the PageArray descending by total number and echo the title and count
    echo "<li>{$item->title} ({$item->myCount})</li>";
  • Like 3

Share this post

Link to post
Share on other sites

horst — many thanks!

This worked perfectly. It's a pretty hefty database call, so I've limited the number of subjects to 20 to keep the TTFB down. But it works! And @Macrura, thanks for your thoughts as well - I'll keep that solve in mind — 

Here's my final function:

function rendersubjectlistsort($pages) {
	$out .="<div class='listWrapper'><div class='imageList'>";

	$pa = new PageArray();
	foreach($pages->find("template=subject, limit=20") as $subject) {
	    $subject->set('myCount', findartworks("subjects=$subject")->count);   
	    $subject->set('myImg', rendersubjectArtworkList(findartworks("subjects=$subject, limit=1"))); 
	foreach($pa->sort("-myCount") as $item) {
		$out .= "<a class='listItem' href='{$item->url}'>" . 
					$item->myImg .
					"<div class='itemInfo'>" .
						"<h3>{$item->title}</h3>" . 
						"<span class='dates'>{$item->myCount} images</span>" .
						"<div style='clear:both;'></div>" .
					"</div>" .


	$out .="<div style='clear:both;'></div></div></div>";
	return $out; 


Thanks again!

  • Like 1

Share this post

Link to post
Share on other sites

Only you have to keep in mind that it doesn't scale if you do this for more and more pages.

Also note that if only counting a $pages->count(selector) is more efficient. Instead of $pages->find()->count

What I do on a shop category tree, is calculate it every time a product is saved and write the count to a integer field on the category pages. So it's like cached.

You could also use markup cache to cache the output and only let rebuild it when a product is changed.

  • Like 1

Share this post

Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By louisstephens
      So I don't know how many have noticed yet, but Youtube has depreciated "rel=0" at the end of the embedded url in September 2018. For some reason, I just noticed today on a site I was working on. If you do not use the rel, you will get related videos across youtube, but if you use it, you will only get related videos from the same channel. Just wanted to share in case people did not know and they needed to make a change on whatever they were working on.
    • By louisstephens
      I have done a bit of searching, but I can not seem to find an actual answer. I have a list of services as child pages under "Services". I can output the services just fine, but I cant wrap my head around how to group them "alphabetically" like:
      Services A - Service "A" 1 - Service "A" 2 - Service "A" 3 B - Service "B" 1 - Service "B" 2 - Service "B" 3 C - Service "C" 1 - Service "C" 2 - Service "C" 3 Has anyone achieved this type of functionality before?
    • By Sanyaissues
      After enable the Tags File Compiler module, echoing variables with brackets syntax doesn't work. I try something simple like {page.title} and is displayed like the tag isn't parsed:
      {page.title} This problem happens with PW 3.0.108, i have another installation with 3.0.82 and it works. Any Ideas? thanks.
    • By nickngqs
      How do you guys sort according to the order of page listing?

      My template is sort order none, so I assume it would return according to order of page listing.
    • By sww
      Hey there,
      is there really no way to turn the OR logic into an AND logic when selecting pages by (e.g.) tags?
      so instead of
       $pages->find("template=exhibitions, tags=foo|bar") something like
       $pages->find("template=exhibitions, tags=foo&&bar") so the pages needs to have all requested tags, not just any of them.
  • Create New...