Skip Navigation

[Resolved] Displaying post relationship items on a single post page (without using views)

This thread is resolved. Here is a description of the problem and solution.

Problem: I have a CPT called "Products" and have setup a post relationship with another CPT called "Stockists". On the single-product.php page, I want to output the Stockists that are children of that particular Product. In the output of each Stockist, I want to display an image that is stored as a custom field on the Stockist post. I want to be able to do this in PHP without using Views.

Solution: Use the toolset_get_related_posts API to query for related Stockist posts. Then loop over those results with a foreach statement. In that loop, echo the custom field image using the types_render_field API, and reference the current Stockist post ID in the array of params.

$product_id = get_the_ID();
$relationship_slug = 'product-stockist';
$stockists = toolset_get_related_posts(
  $product_id, // the known item id
  $relationship_slug, // the relationship slug
  'parent', // the known item role in the relationship
  1000000, // a positive integer is required here for the limit
  0, // zero-based index page number
  array(), // no additional params are required here
  'post_id', // whether you want to return an array of post IDs or post objects
  'child' // the role you want to return
);
foreach($stockists as $stockist) {
  echo types_render_field( "stockist-logo", array( "raw"=>"true", "id"=>$stockist ) );
}

Relevant Documentation:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
https://toolset.com/documentation/customizing-sites-using-php/functions/

This support ticket is created 5 years, 10 months ago. There's a good chance that you are reading advice that it now obsolete.

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
8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 8:00 – 12:00 - -
13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 13:00 – 17:00 - -

Supporter timezone: America/New_York (GMT-04:00)

Tagged: 

This topic contains 8 replies, has 2 voices.

Last updated by CraigS3893 5 years, 10 months ago.

Assisted by: Christian Cox.

Author
Posts
#1189014

I have a CPT called "Products" and have setup a post relationship with another CPT called "Stockists".

On the single-product.php page, I want to output the stockists that have been set for that particular product.

I don't want to use Views, I need to do this programatically.

Can you let me know how this is done?

#1189233

You can do this in PHP with or without Views, using the Post Relationships API or using the Views API. I'm not clear if you're saying you want to avoid Views altogether, so I'll give you both scenarios:

Post Relationships, no Views
Use the toolset_get_related_posts API to get all the Stockist posts related to the current Product post:
https://toolset.com/documentation/customizing-sites-using-php/post-relationships-api/#toolset_get_related_posts
Then loop over those results and output the desired information from each Stockist. I can provide code examples if necessary.

Views API
Create a View of Stockist posts, related to the current post being displayed (current Product). Use the render_view API to render the View programmatically. https://toolset.com/documentation/programmer-reference/views-api/#render_view
I can provide code examples if necessary.

#1189267

Hi Christian
Thanks for the reply. I'm doing it programatically so would be avoiding Views altogether.

Could you provide a code example? I've got a loop within the single post where the stockists need to display but it's returning nothing. I've tried a few things from the API page but can't get this working. Not sure what the post_type should be - (product-stockist is the relationship name), I tried it with the 'stockist' post_type but this returns all stockists, rather than just the ones associated with the single product in question.

<?php
$args = array(
'order' => 'ASC',
'post_type' => 'product-stockist',
'post_status' => 'publish',
'posts_per_page' => -1
);
$postslist = get_posts($args);
foreach ($postslist as $post) :
setup_postdata($post); ?>

<img src="<?php echo (types_render_field('stockist-logo', array('raw' => 'true'))); ?>" alt="<?php
echo (types_render_field('stockist-name', array())); ?>" />

<?php endforeach; ?>
<?php wp_reset_query(); ?>

#1189305

I assume Product is the parent and Stockist is the child, correct? If so, then you can do something like this:

$product_id = 12345; // replace this with the current product ID
$relationship_slug = 'product-stockist';
$stockists = toolset_get_related_posts(
  $product_id, // the known item id
  $relationship_slug, // the relationship slug
  'parent', // the known item role in the relationship
  1000000, // a positive integer is required here for the limit
  0, // zero-based index page number
  array(), // no additional params are required here
  'post_id', // whether you want to return an array of post IDs or post objects 
  'child' // the role you want to return
);
foreach($stockists as $stockist) {
  echo types_render_field('stockist-logo');
}
#1189631

Hi Christian,
Thanks again. Tried this but it's still returning blank. I echoed the $product_id variable to make sure it was using the correct parent ID (product ID). Tried it returning 'post_id' and 'post_object' in the arguments too but same result, no stockists are displayed. Can you see what's wrong with this?

<?php
$product_id = get_the_ID(); // replace this with the current product ID
$relationship_slug = 'product-stockist';
$stockists = toolset_get_related_posts(
$product_id, // the known item id
$relationship_slug, // the relationship slug
'parent', // the known item role in the relationship
1000000, // a positive integer is required here for the limit
0, // zero-based index page number
array(), // no additional params are required here
'post_id', // whether you want to return an array of post IDs or post objects
'child' // the role you want to return
);
foreach($stockists as $stockist) {

echo $product_id ?>

<img src="<?php echo (types_render_field("stockist-logo", array("raw"=>"true"))); ?>" alt="<?php echo (types_render_field('stockist-name', array())); ?>" />

<?php } wp_reset_query(); ?>

#1189775

When you say no stockists are displayed, can you be more specific? Check the markup in the page source. Is the img tag generated but the src attribute is empty or invalid? In that case, you probably need to add the current stockist ID (from the foreach loop) to the types_render_field options array, since the types_render_field API isn't targeting the global $post:

<img src="<?php echo (types_render_field("stockist-logo", array("raw"=>"true", "id"=>$stockist))); ?>" alt="<?php echo (types_render_field('stockist-name', array("id"=>$stockist))); ?>" />

Is the img tag not generated at all? In that case, the problem is in the post relationship query, and I'll need to take a closer look.

#1189790

Hi
That worked! Thanks, the addition of - "id"=>$stockist - fixed it.

Out of interest, what would be the procedure using Views API? I'm not using Views on this site as I'm on a deadline and having to stick with methods I (mostly) know - I do aim to suss out Views when I get a chance though, I'm guessing it'd make the process a bit easier?

#1189889

Okay great. With Views, you use a GUI in wp-admin to select the list content type, add filters, specify number of results / pagination options, AJAX loading options, and so forth. Then you can design the output of those results using your own custom markup/CSS/JS and Toolset shortcodes, or you can insert Toolset shortcodes in one of the predefined Loop templates. Normally you would insert that View in your post content or Content Template using a Toolset shortcode. Or you would use a View block in the block editor if you prefer the Gutenberg-style editor.

The Views API bypasses that last step by rendering an existing View directly in PHP without the need for a shortcode. This is helpful if you're creating a plugin or a theme template file in PHP. You would create the View normally in wp-admin, as though you would insert it in some content as a shortcode. Then call the render_view API in PHP to display that View dynamically. You have the ability to pass in context or other shortcode attributes as needed. More info about these concepts is available here:
https://toolset.com/documentation/post-relationships/how-to-display-related-posts-with-toolset/
https://toolset.com/documentation/user-guides/digging-into-view-outputs/
https://toolset.com/documentation/programmer-reference/views-api/#render_view

#1190344

That's great, thanks for your help.