Jump to content

How to limit the number of results returned from $pages->find to a particular child level?


kathep
 Share

Recommended Posts

Hi all

I have a folder tree like this:

post-2947-0-59502300-1435186136_thumb.pn

I have set up the main page (template: course.php; title: All Things Media: Design) to show a list of assignments. I want the output to look like this:

post-2947-0-98580000-1435186971_thumb.pn

However, I have a problem. 

When I do this:

$assignments_find = $pages->find("template=quiz|challenge|assignment, course_name_from_list.title=$page->title, sort=assignment_due_date");
Every page with these templates (quiz, challenge, or assignment) is returned, including the archived assignments - not what I want!

I want every page using the course.php template to be able to call only the templates that are children in the first two levels below this instance of course.php. Does anyone know if this is possible? 

I can't see a way from the documentation to use 'child' as a selector, so I'm at a loss.

I currently have this hacky workaround:

$assignments_find = $pages->find("parent=/teach/108/assessment/, course_name_from_list.title=$page->title, sort=assignment_due_date");
But obviously this only works for one page using course.php. I'll need a better solution to accommodate my archived files and other courses I'm currently teaching. 

Any ideas? If you could get me a little closer to figuring this out, please let me know!

Website link, in case it helps.

Link to comment
Share on other sites

I see some things that i would change, for one, i don't get this:

course_name_from_list.title=$page->title

is course_name_from_list a page select? if so you should be able to do

course_name_from_list=$page

i would also research these selectors:

has_parent   (=$page for example)

$page->children($selector)

  • Like 1
Link to comment
Share on other sites

@Macrura

Thank you for the corrections to my bad code.

I don't think either has_parent or $page->children($selector) would work in my use case, as the current course page and the archived course page have the same structure and templates. For example, calling everything with a parent of 'assessment' would give me the exact same problem as my original code snippet.

Please correct me if I'm wrong!

Link to comment
Share on other sites

has_parent   (=$page for example)

$page->children($selector)

I don't think either has_parent or $page->children($selector) would work in my use case, as the current course page and the archived course page have the same structure and templates.

...ok same structure but that is not the problem we search a identifier of active and past courses - so what is unique?

$page->id

What id (s) we need?

$assesments = $pages->get(id);
$archive        = $pages->get(id);

Next step is your finding elements on this two pageojects so you can devide active and past courses...

regards mr-fan

Link to comment
Share on other sites

to put it simply, you only want descendants of the current page,

$allChildren = new PageArray();

foreach($page->children() as $parent) {
   foreach($parent->children() as $child) $allChildren->add($child);
}
$assignments_find = $allChildren->find("template=quiz|challenge|assignment, course_name_from_list=$page, sort=assignment_due_date");
  • Like 1
Link to comment
Share on other sites

Hi @Macrura, @Mr-Fan, and @sephiroth
 

to put it simply, you only want descendants of the current page,

 
No. I only want descendants of the current page, for two levels that fit within certain criteria. I have managed to specify the criteria, but not the two levels down. Perhaps this will make it clearer:

 
Rootparent: Teach

Parent: All things media: design *calls list of assignments two child levels down*
Child Level 1: Assessments
Child Level 2: ***The only assignments I want to show up in the document 'All things media: design'***
Also on child level 2: Archive
Child level 3: All things media design (archive 2015 Spring)
Child level 4: Assessments *calls list of assignments two child levels down*
Child level 5: ***The only assignments I want to show up in the document 'All things media: design (archive)'***
 

limit=5 you can specify that in the selector

 
@Sephiroth I want to specify the number of child levels down. My understanding of 'limit' is that it limits the number of results returned, not the number of child levels. Please let me know if there is another way to use 'limit' that I'm unaware of!

 

...ok same structure but that is not the problem we search a identifier of active and past courses - so what is unique?
 
$page->id
 
What id (s) we need?

$assesments = $pages->get(id);
$archive        = $pages->get(id);
Next step is your finding elements on this two pageojects so you can devide active and past courses...
 
regards mr-fan

Thank you! BUT... page-id is not good, because the template would only work for one page. Eventually I will have 50 archived courses in the 'archive' folder, and the 'course.php' in each archive needs to refer only to the immediate two child levels of that course.

What is unique: The combination of course title (field: course_title_from_list) and semester (field: course_semester_current) will be unique for every instance. 

Is it possible to write in PW/PHP something like 'find the id of the child page of this page called assessments, then get all the immediate children of that page only'?

Link to comment
Share on other sites

Is it possible to write in PW/PHP something like 'find the id of the child page of this page called assessments, then get all the immediate children of that page only'?

i believe that my post above would do what you want.

Link to comment
Share on other sites

It's really hard to tell which page you're working from and what that "course_name_from_list.title" is supposed to be. But if $page is the "All things media" page then use this:

$assignments_find = $pages->find("has_parent=$page, template=quiz|challenge|assignment, sort=assignment_due_date");

If you need it from a child page of "All things media" then use this:

$assignments_find = $pages->find("has_parent=$page->parent, template=quiz|challenge|assignment, sort=assignment_due_date");

or even

$assignments_find = $pages->find("has_parent=".$page->parent($selectorForFindingTheRightParent).", template=quiz|challenge|assignment, sort=assignment_due_date");

This will always give you just the pages in the "All things media" branch you're on.

  • Like 1
Link to comment
Share on other sites

@kathep,

you''ll notice that the has_parent selector limits the find to a certain parent, but recursively includes all children which is why the has_parent selector is being suggested:

has_parent=$page

http://cheatsheet.processwire.com/selectors/built-in-page-selector-properties/has_parent-page/

my experience with processwire has taught me that anytime you are having trouble getting a particular results set of pages, you either have some mis-configuration of your page hierarchy, or you haven't found the exact selector; PW selectors are very powerful, especially with all of the enhancements of the last year or so; In cases where page arrays and selectors don't work, then you can move on to sql commands.

Link to comment
Share on other sites

you could limit the child-levels like that:

$items = your_selector_including_all_levels;
$maxlevel = $page->parents->count() + 2;
foreach($items as $item) {
  if($item->parents->count() <= $maxlevel) {
    // echo your markup
  }
}

that may be not the cleanest solution as you select more data than necessary and remove the unwanted items afterwards, but if performance is not an issue i think that would be an easy solution?

ps: didn't check the code! just wanted to show the idea...

  • Like 1
Link to comment
Share on other sites

@BernhardB Oh wow, I did not know about $maxlevel. Thank you! 

I am very happy to try out this code and see how it works. That makes three solutions I have to try now!

Feeling lucky to be part of such a helpful dev community.

  • Like 1
Link to comment
Share on other sites

there is no "maxlevel" in processwire - that's just the name that i gave the variable.

$page->parents returns a pagearray of all parents of the current page. ->count() counts the number, so you get the level of your current page. you can then add 2 and have your "maxlevel" compared to the given item's level $item->parents->count()

good luck :)

Link to comment
Share on other sites

  • 2 weeks later...

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...