-
greenegirl
I am working on rebuilding a site to remove Toolset from it. I need to recreate a single post template for a CPT Instructor so that it will display Classes taught by the Instructor. This is an example of what an existing Instructor page looks like: https://ftwg.org/instructor/williams-jennifer/
In the current structure, Instructor, Workshops, Mini Classes, and Talks are all CPTs. Instructor is connected to the other 3 through a relationship field, and the query is filtered by relationship. I’ve already seen the various support topics and the code on allowing Query Loop with relationship field, but I’m having a hard time implementing that within a GP Element for a single post template.
In the new structure, Instructor is still a CPT and we have a Classes CPT, which contains all posts that were previously under Workshops, Mini Classes, and Talks. There’s a custom taxonomy with taxonomy terms for workshops, mini classes, and talks that I can use as a filtering parameter.
My problem remains building a Single Post Template in GB Elements with a query loop pulling only the classes that this Instructor is presenting. Even when adding the PHP to allow fields through a relationship, I don’t see how to filter to show only the related posts.
I was thinking about creating a taxonomy of Instructors and designating classes that way, but that route requires the ability to filter where taxonomy term = current post title, and that’s also something that doesn’t exist as a filtering parameter.
Can you point me in the right direction here?
-
David
Hi there,
so the single instructor has a field that contains the classes IDs ?
-
greenegirl
Hmmm. Not sure that’s the case. Does a (CubeWP in this case) relationship field pass the related post ID through? I thought it was a separate field.
-
greenegirl
I switched over to testing this on a site that has ACF installed, so I can work out the issues / my understanding there before muddying the waters with CubeWP.
I copied the code from this support post: https://generate.support/topic/how-to-create-a-query-loop-for-custom-pages/#post-108624 and updated the class and relationship field to match my site. This is the code on my site:
/* Add Ply Article Fields to GB Query Block for Creator Single Post */ //set post type and post per page in the query loop block add_filter( 'generateblocks_query_loop_args', function( $query_args, $attributes ) { // find the block with creator-articles if ( ! empty( $attributes['className'] ) && strpos( $attributes['className'], 'creator-articles' ) !== false && ! is_admin() ) { // get the related post ID $queried_object = get_queried_object () ; $relationship = get_field( "creators_to_ply_articles", $queried_object ); // Merge the current $query_args with the new args return array_merge( $query_args, array( 'post__in' => $relationship, ) ); } return $query_args; }, 10, 2 );
So really my question is What Now?
This is what I’m doing, based on various tutorials and documentation I looked at:
– Create a Block Element of Element Type Loop Template
– Set Location to Creator / All Creators
– Add Container Block with a Query Loop inside of it.This is where I come to my first dilemma. Do I set the Query Loop to Inherit Query from Template? Or do I Select Post Type PLY Articles (the related CPT that I need to pull fields from)? I’ve tried both ways and neither have actually worked for me.
– Add class to the Grid in the Query Loop. In this case, I’m using the class ‘creator-articles’
And here’s the next place I get stuck. How do I actually query the fields from the Ply Articles? For now, I have only created one custom field, a text field called ‘test_field’. I also am trying to pull the post title.
I’ve tried to pull my field by enabling dynamic data on a headline. Data Source Current post, Content Source Post meta, post meta field test_field. No content is displayed on the front end.
I’ve tried pulling post title by enabling dynamic data on a headline. Data source Current post, content source Title, Link Source Single post. This results in a completely blank page on the front end, not even displaying the Post Title for the Creator.
I also tried Data Source Post type, Post Type PLY Articles, Content Source Title, Link Source Single post. It asks me to Select Source Post, but that only lets me pick a specific post and so wouldn’t loop correctly to get all articles by the creator. This option keeps the Creator’s name as the title on the front end, but it returns zero content. In the Post title field on the back end, it says “Post source not selected” because I haven’t designated a specific post.
I’m clearly not understanding something on the implementation side, and I’m hoping it’s something simple. If it helps, this is a dev site and I can easily create a user for you or I can make a short video walking through what I’m seeing.
-
David
Do I set the Query Loop to Inherit Query from Template? Or do I Select Post Type PLY Articles (the related CPT that I need to pull fields from)?
The Query Loop should not use the Inherit Query From Template. That should only be used if the template is an archive or index.
In this case, you would set the query parameters to fulfil your requirements
eg. set the Post Type to your classes post type and set the number of posts.
Make sure the Grid Block within the Query Loop is given the CSS Class used in your PHP snippet condition ie.creator-articles
Now as a long as your snippet is retrieving the values from the correct field it will pass them to the
post__in
parameter of the query. So make sure the ACF relationship field is returing IDS and not post objects.If need be use a ACF Shortcode on a single CPT to see what values the field is returning.
-
greenegirl
It’s taken me some time to review what I was doing and what I needed to do. I think I’ve got what I need now, and am mostly posting here to have a record of it in case it helps anyone else. If you see something that could be done more efficiently, I look forward to hearing it!
I discovered that each ACF Relationship has a toggle to decide whether it returns Post Object or Post ID. I was unaware of this toggle, so all my relationship fields were set at the default of Post Object. I updated them so they are now all set to Post ID.
Some of my relationships are bidirectional. I wasn’t sure if ACF had a separate field that referenced bidirectionally or if I needed to treat them as two one-way relationships. I filed a support request with ACF to ask this question, and they told me to treat them as two one-way relationships, which means that I need to loop the query multiple times.
This site has 12 CPTs, and between them there’s 28 potential relationships (this counts bidirectional relationships twice, since I would need to loop them in each direction). However, I really only need to use the relationship field to pull fields when building archives and templates in GP Elements. If I’m building a page manually, I can filter by taxonomy to refine the single posts. I went back to the drawing board to review which queries will be on archives or templates versus on pages. I determined that there’s a total of 8 one-way relationships that need to be queried on archives or templates.
I knew I was going to need an array for this, but since my PHP skills are rudimentary at best, I dropped the code above into ChatGPT, gave it my list of classes & fields and asked it to rewrite the code. This is what I got:
/* Add Class Fields to GB Query Block for Related CPTS */ //set post type and post per page in the query loop block add_filter( 'generateblocks_query_loop_args', function( $query_args, $attributes ) { // Define an array of class-field pairs $class_field_pairs = array( 'classes-instructors' => 'classes_to_instructors', 'instructors-classes' => 'instructors_to_classes', 'districts-guilds' => 'districts_to_guilds', 'districts-members' => 'districts_to_members', 'districts-presenters' => 'districts_to_presenters', 'districts-events' => 'districts_to_events', 'guilds-members' => 'guilds_to_members', 'guilds-events' => 'guilds_to_events' ); // Check if the block class name matches any in the list and it's not in the admin area if ( ! empty( $attributes['className'] ) && strpos( $attributes['className'] ) && ! is_admin() ) { // Loop through the class-field pairs foreach ( $class_field_pairs as $class => $field ) { // If the class name contains the current class if ( strpos( $attributes['className'], $class ) !== false ) { // Get the related post ID $queried_object = get_queried_object(); $relationship = get_field( $field, $queried_object ); // If relationship is not empty, merge the current $query_args with the new args if ( ! empty( $relationship ) ) { return array_merge( $query_args, array( 'post__in' => $relationship, ) ); } } } } return $query_args; }, 10, 2 );
I haven’t built out all the custom fields yet to be able to test it. I’m doing that now.
-
David
Sound logic 🙂
Let us know how you get on!
-
greenegirl
I’ve built several queries now using the above process and code, and everything is working well!
-
Awesome – glad to hear that
- You must be logged in to reply to this topic.