Skip Navigation

[Resolved] sort loop output of children of the post set by parent view

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Tagged: 

This topic contains 5 replies, has 2 voices.

Last updated by Brad 4 years, 10 months ago.

Assigned support staff: Luo Yang.

Author
Posts
#345928

Hi Luo,

I worked through the steps you showed me in https://toolset.com/forums/topic/how-to-display-deduplicated-list-of-parents-of-children-of-parents-of-children/#post-344509.

In your Step 1, post type Officers was not supposed to be a child of post type Units. That was a leftover relationship from an earlier design when I believed that an Officer would never be assigned to more than one Unit. I later changed the design to follow the many-to-many approach that would provide the needed flexibility for an Officer to belong to more than one Unit. I have now removed the child relationship of Officers to Units. The post relationships are now as I described in my post at https://toolset.com/forums/topic/how-to-display-deduplicated-list-of-parents-of-children-of-parents-of-children/#post-343809.

I also changed the nested Template for Officers to use the same syntax that you used in your Step2b. For example, [wpv-post-body view_template="OfficerListTemplate5" id="$officers"].

This now produces a list of Officers who are assigned to any Units deployed to the current Area post type.

However, the Officers are not sorted by rank as I need them to be. I have a custom Types field "Numeric Rank" for each Officer, but I cannot see how I can sort the loop output to show the Officers sorted by that Numeric Rank field. The Ordering settings in the OfficerListView5 view apply to the Assignments, not the Officers, if I understand correctly.

The hierarchy of Templates and Views is now as follows:

AreaTemplate5
-UnitAreaView5 ; This gets Deployments. These are children of Areas and Units.
--UnitListTemplate5
---OfficerListView5 ; This gets Assignments. These are children of Units and Officers. Here in the loop I use [wpv-post-body view_template="OfficerListTemplate5" id="$officers"].
----OfficerListTemplate5

How can I sort the loop output to show Officers sorted by Numeric Rank?

Brad

#346003

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Dear Brad,

You are right, the custom field "Numeric Rank" is in the parent post type "officers", but the second level view is selecting child "Assignments" posts, if you need order the child "Assignments" posts by parent fields, please try Views filter hook wpv_filter_query_post_process, for example this thread:
https://toolset.com/forums/topic/order-view-on-multiple-keys/#post-320747

More help:
wpv_filter_query_post_process
When displaying a View listing posts, this filter is applied after the WP_Query has been run.
https://toolset.com/documentation/user-guides/views-filters/wpv_filter_query_post_process/

#348053

Hi Luo,

I made progress but still need help. I see that the sort is now taking place, but because the Numeric Rank field is a select field, it seems to be sorting on the display text value, rather than the custom field content number as desired. What should I change in the comparison function? Here is what I have:

add_filter( 'wpv_filter_query_post_process', 'sort_query_func', 10, 3 );
function sort_query_func( $query, $view_settings, $view_id ) {
if ( !empty( $query->posts ) && $view_id == 5290) {
usort($query->posts, "cmp");;
}
return $query;
}
function cmp($a, $b)
{
$res = strcmp(get_post_meta($a->ID, 'wpcf-numeric_rank', true), get_post_meta($b->ID, 'wpcf-numeric_rank', true));
if ( $res == 0) {
$res = strcmp(get_post_meta($a->ID, 'wpcf-officer_name', true), get_post_meta($b->ID, 'wpcf-officer_name', true));;
}
return $res;
}

Thanks.

#348055

On second thought, it doesn't appear to be sorted by text value either. The sort had an effect, because the captain is now displayed fourth, whereas before I put in the filter, he displayed first in the output. So, something changed, but I am not sure what the filter is doing.

#348112

Luo Yang
Supporter

Languages: English (English ) Chinese (Simplified) (简体中文 )

Timezone: Asia/Hong_Kong (GMT+08:00)

Thanks for the details, I have modified the codes in your custom plugin file crimeboard.php, as below:

add_filter( 'wpv_filter_query_post_process', 'sort_query_func', 10, 3 );
function sort_query_func( $query, $view_settings, $view_id ) {
    if ( !empty( $query->posts ) &&  $view_id == 5290) {
       usort($query->posts, "cmp");;
    }
    return $query;
}
function cmp($a, $b)
{
	$officers_a_id = get_post_meta($a->ID, '_wpcf_belongs_officers_id', true);
	$officers_a_rank = get_post_meta($officers_a_id, 'wpcf-numeric_rank', true);
	$officers_b_id = get_post_meta($b->ID, '_wpcf_belongs_officers_id', true);
	$officers_b_rank = get_post_meta($officers_b_id, 'wpcf-numeric_rank', true);
	$res = 0;
    if ( $officers_a_rank < $officers_b_rank) {
       $res = 1;
    }
    return $res;
}

Please test again, check if it is fixed or not

#348126

Luo, that works perfectly. Thank you! I never would have managed that change to the comparison function without you.

I'll mark this issue resolved. My next step will be to assign one of the four officers displayed to an additional unit, then deploy that unit to the Little Italy area. I expect I will see two instances of the officer displayed. To eliminate this duplication, I will add a deduplication function to run after the sort but before returning the $query (just after line 4 in your excerpt above). I'll open a new issue if I have trouble with that.

My sincere thanks once again.