Home › Toolset Professional Support › [Resolved] Sort by date post relationship
Problem:
In a many-to-many relationship the client wants to display related posts, sorted by a field on the related posts.
Solution:
The current implementation of many-to-many relationships involves creating an intermediate post type, and then creating a View which returns the intermediate posts with a filter for the parents on one side, while using the id attribute to display content from the parent on the other side.
That View can only filter by fields present on the intermediate post type itself, which means duplicating the field in question from the parent on the intermediate posts.
This will become redundant with the switch to Types 3.0, when it will eventually be possible to filter by fields of related posts.
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.
Sun | Mon | Tue | Wed | Thu | Fri | Sat |
---|---|---|---|---|---|---|
- | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | 7:00 – 14:00 | - |
- | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | 15:00 – 16:00 | - |
Supporter timezone: Europe/London (GMT+00:00)
Related documentation:
This topic contains 26 replies, has 2 voices.
Last updated by olivierF 6 years, 9 months ago.
Assisted by: Nigel.
Hello, I created 3 custom post type 'concert' 'artist' and 'participants' which are a post-relationship.
I try to display in the single page 'artist' concerts that are only in reference to this artist.
It does not work anymore when I want to sort by date of concert. can you help me on this ?
Here is the page where the view should appear : hidden link
This de code of the view
[wpv-layout-start] [wpv-items-found] <section class="agenda"> <div class="row"> <div class="col-xs-12"> <h2>Agenda</h2> </div> </div> <div class="col-xs-12 white-inner"> <!-- wpv-loop-start --> <wpv-loop> <div class="row agenda-row [wpv-post-taxonomy type="type-concert" format="slug" id="$concert"]"> <a href="[wpv-post-url id="$concert"]" class="agenda-link"> <div class="col-sm-2 col-xs-6 agenda-date"> <p>[types field='concert-date' style='text' format='j.F.Y' id="$concert"][/types]</p> </div> <div class="col-sm-3 col-xs-6 agenda-artiste"> <p>[wpv-post-title id="$artiste"]</p> </div> <div class="col-sm-3 col-xs-4 agenda-salle"> <p>[types field='concert-lieu' output='raw' id="$concert"][/types]</p> </div> <div class="col-sm-2 col-xs-4 agenda-lieu"> <p>[types field='concert-ville' output='raw' id="$concert"][/types]</p> </div> <div class="col-sm-1 col-xs-4 agenda-nation"> <p>[types field='concert-pays' output='raw' id="$concert"][/types]</p> </div> </a> <div class="col-sm-1 col-xs-12 agenda-ticket"> <a href="">Ticket</a> </div> </div> </wpv-loop> <!-- wpv-loop-end --> <div class="row"> <div class="col-xs-12"><a href="./agenda" class="full-agenda classic-link">Full agenda</a></div> </div> </div> </section> [/wpv-items-found] [wpv-layout-end]
thanks for your help
Olivier Foguenne
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
Your View is querying the intermediate post type Participants.
You have added a parent post filter, and also a filter for the field Concert Date.
Does the custom field Concert Date belong to the participants post type? Or to the concert post type?
Hi Nigel,
It belongs to the type of concert.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Then that is your problem.
Your View queries participant posts, and so you can only filter by fields of participants. A participant post doesn't know what the concert date is.
As you are probably aware, post relationships are undergoing a major overhaul, and there is a feature request to make it possible to filter by fields of the parent, which would make what you are trying to do possible.
I don't think it will be included in the initial stable release, but my understanding from the developers is that it should be added within one or two subsequent releases.
With the current versions, though, it is not possible.
Is there a other way to display concert (parent post) that only relate to the current artist (child) in a single page (signle page artist) ?
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Have I misunderstood?
You say concert is parent and artist is child.
I understood you to have a many-to-many relationship where concerts and artists were connected via a participants post type like so:
concert artist \ / \ / participant
Is that not the case?
You might find this page helpful for background: https://toolset.com/documentation/beyond-the-basics/post-relationship-concepts/implementing-many-to-many-relationships/
Thank you, this is exactly the same case as me in the link "Display events at which an artist appears" and I use this method.
Except that I have a concert date field and it is apparently impossible to sort by concert date and only show future concerts. It seemed to me something very simple, too bad, I use Toolset for some time and this is the first time I can achieve what I want.
Thank you for your help...
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
Well, currently the only way to output the concerts that relate to the artist being displayed is via a View which queries the intermediate participant posts, and you can only filter by fields of participant posts. The concert date is not a field of participants and so cannot be used.
There are two possible solutions.
One is to duplicate the concert date field on the participant posts. You can then not only use the concert date field to filter the results (only show future concerts) but to order them, too (show upcoming concerts in date order). To save having to manually enter the date in the participant post you could add a little PHP using the save_post hook (https://codex.wordpress.org/Plugin_API/Action_Reference/save_post) so that when a participant post is saved you get the date from the parent concert post and add it to the post meta of the recently saved participant post.
The second does not require any custom code but is more limited. In the Loop Output section of your existing participants View you can wrap the output in a wpv-conditional tag and add a test for the date field, using the same id="$concert" technique to specify that the date field belongs to the parent concert post. For non-matching posts nothing would be output, so you would only see the future concerts. You wouldn't be able to order by the concert dates, though, only by properties of the participant posts.
If you try one of these and need more help do let me know.
I still do not have the solution to sort by date of concert in a many-to-many relationship, it calls into question all my site that works with toolset, my client needs to sort the concert by date of concert in a single page artist, that me seems something basic, is there another solution ?
The many-to-many relationship looks like that:
concert artist
\ /
\ /
participant
Thank you for your hel and support.
Olivier Foguenne
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
Sorry for the delay getting back to you, it was a holiday weekend here in Ireland.
If you require being able to sort the connected concerts by concert date then with the current implementation the only option would the first option I described in my previous post, where you duplicate the concert date field on the intermediate participant posts. Then your View which queries participant posts (to output fields from the parent concert posts) can be filtered and sorted by the concert date.
In terms of an easier workflow you can use the save_post hook to automatically copy the concert date field from the parent concert post when a participant post is saved, rather than have to add it manually a second time.
This will be possible natively within Views when the work on post relationships is complete, but for now you would need to adopt the above methodology.
Hi Nigel,
can you explain how to put in place the "save_post" hook ?
The concerts are already all encoded, will I have to re-encode them all ?
Thank you for your help.
Olivier
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
You can use the following code to duplicate the field from a parent when a child post is saved/updated:
add_action( 'save_post', 'tssupp_duplicate_parent_field', 101, 3 ); function tssupp_duplicate_parent_field( $post_id, $post, $update ){ $child_slug = 'participant'; $parent_slug = 'concert'; $parent_field_slug = 'concert-date'; // is it a child post being updated? if ( $child_slug == $post->post_type ) { // get the ID of the parent post $parent_id = get_post_meta( $post_id, '_wpcf_belongs_' . $parent_slug . '_id', true ); if ( !empty( $parent_id ) ) { // get the parent field $parent_field_value = get_post_meta( $parent_id, 'wpcf-' . $parent_field_slug, true ); // duplicate the parent field on the child post update_post_meta( $post_id, 'wpcf-' . $parent_field_slug, $parent_field_value ); } } }
You will need to edit the slugs.
This won't affect your existing posts.
For that you will need to run some similar code one-time only. You can add the above code to your theme's functions.php file, or using a plugin such as Code Snippets.
I would recommend Code Snippets for the second code sample below, because it has a feature where you can add code and just run it once, which is perfect for when you need to update content in the database.
function tssupp_duplicate_parent_fields_once (){ $child_slug = 'participant'; $parent_slug = 'concert'; $parent_field_slug = 'concert-date'; // Get all of the child posts $args = array( 'post_type' => $child_slug, 'numberposts' => -1, 'post_status' => 'publish' ); $child_posts = get_posts( $args ); if ( !empty( $child_posts ) ) { foreach ($child_posts as $child_post) { // get the ID of the parent post $parent_id = get_post_meta( $post_id, '_wpcf_belongs_' . $parent_slug . '_id', true ); if ( !empty( $parent_id ) ) { // get the parent field $parent_field_value = get_post_meta( $parent_id, 'wpcf-' . $parent_field_slug, true ); // duplicate the parent field on the child post update_post_meta( $post_id, 'wpcf-' . $parent_field_slug, $parent_field_value ); } } } }
Hello Nigel,
I just tried your method but when I try to sort by concert date, nothing is displayed, is there anything else to do ?
How do i know if the date concert field has been duplicated ?
Thanks for your support .
Olivier Foguenne
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
You can look in the database to see whether the concert date field has been duplicated.
Get the ID of one of the participant posts and then using phpMyAdmin look at the wp_postmeta table and search for the post meta entries for that post ID. You can do the same using the ARI Adminer plugin directly in your WordPress backend.
If you like I can do that for you, but I would need access, so let me mark the next reply as private in case you need to share credentials with me.
Languages: English (English ) Spanish (Español )
Timezone: Europe/London (GMT+00:00)
Hi Olivier
I checked in the database and the concert date field is duplicated on the participant posts.
I then checked your View "Agenda_artiste" and it was still set to with order by post date.
I changed that to order by concert date, and that now works on the front end.