Relationship Fields with Pods

Update: I changed my theme and moved a lot of stuff around and thumbnails might looks a bit off… sorry ūüôā

when I get a chance I will fix them…

Relationship Fields

Continuing from the last post, the only custom field in pods I have not spoken much about is the relationship field. It’s a big subject so I gave it its own section.

This custom field allows you to relate two post types or tables in WordPress. Under your post, there will be a custom field asking you to point to something else, be it another post from another post type, a custom list, a user from your database… There is a lot you can do with the relationship field. So lets start with a real world example: My site.

Here I have a blog using the post type ‘post’. I started making a tutorial on Pods and decided to break it up and link them all together using a new post type. So I made a new post type called ‘series’. As discussed in the first, article, I use a prefix, set some advanced options including allowing a featured image and, add a new custom field, ¬†this time with relationship as the type.

So after setting the custom field to relationship, I get new options. Because I will be relating the series to my blog, I chose ‘post’ in the ‘related to’¬†dropdown.

As you can see, there are a lot of things to choose from when choosing from the¬†‘related to:’. For now, as per our example, I chose the post type ‘Post’.

While making a relationship field, there is an option for bi-directional field. This is not available until we make another relationship field from the other pod we chose, in this case the ‘post’ post type. Only then can we make this a two-way relationship. We will get back to this soon. For now if you click the¬†‘additional field options’, you will notice I changed the selection type to¬†‘multiple select’. This is because¬†there are to be many posts related to one series. I want to be able to input more than one post into this field. This is called a one to many relationship. I also set it to autocomplete, which leads to the formats.

Formats

  • Checkbox – You will be able to check off different posts to include in this series… imagine having 100 posts to choose from to check off! …ummm no! So I didn’t choose that!
  • Multi Select – a list where you can select more than one. Better for our structure, but not as awesome as autocomplete!
  • Autocomplete¬†– autocomplete shows an input text box, and as you type it can find the post your looking for and add it in. Because we set it to multiple select, we can add more than one by pressing enter after each one. But autocomplete can do even more!
    • Autocomplete also has a sweet option for¬†‘taggable’. This means we can add new values -that is -new posts! So if I know what new posts I plan on creating I can create them here and now by just entering a title and, when I save and go to posts, the new posts will exist, although they will be empty, except for the title we made.
    • Autocomplete can be reordered. You can drag the buttons inside around and this will actually affect the order in which they are output should you retrieve them in your template files.
here i added the post hello world, and I am adding another one
Here i added the post hello world, and I am adding another one

Save the Pod and go add a new series. In it you will be able to add posts, and create new posts in the custom field we created.

Bi-Directional Relationships

Now the post type, ‘post’ is not aware of this relationship we have created, unless you create a relationship from that side. Only then will they be linked. Then when you update the series relationship field, so will the post relationship field be updated.

So first we need to make a new pod. this time we are using the post type ‘post’. This post type exists already so we will be extending a post type.

Extending a Post Type

So we go to the Pods admin and hit¬†‘Add New’, and this time choose extend. Choose the post type to extend, in our case its ‘Post’. Now when extending a post type, you wont get as much options as when making a new one. All we can do is add custom fields. Use the images above to guide you. At this point you should be a pro!¬†You can see I have created a new custom field, set it to relationship and related it to ‘Series’. This time under ‘Bidirectional Field’¬†we can select what it finds, which is the other field we made earlier for ‘Series’.

You do not need to go back to the ‘Series’ pod and fill the bi-directional field there. It will do this automagically for you!

(Wow automagically, turns out is a real word in the dictionary now! I did not know that!)

Now, as I said before this relationship is a one to many. There are supposed to be many posts¬†to one Series. So we need to make this field capable of having only one¬†Series. So make sure to leave it as ‘Single Select’ under the¬†‘additional field options’ tab. And because there is only one, I left the format as a dropdown.

And were done!

Now its all done in the back-end! We can create new posts and add them to a series via the dropdown. The Series would have to exist first for it to be in the dropdown. Or you can go make a new Series and make new posts right in the autocomplete field.

And that’s all there is to making relationships fields and connecting two tables in the WordPress database. You can relate more than just post types, but before I move on to that, lets see how we can get our related¬†fields in our templates.

Retrieving relationship fields From the Many side (Series)

If you have followed till now, you know about the ways of echoing out your fields in your theme files. If you don’t you missed my post on custom fields with pods. You also know that media and relationship fields echo an array when using field() or get_post_meta(), and display() outputs the field in some nice format that is useful.

Well today you will see how display() is not the best choice for the job. Lets test them all again!

So I now have a post type ‘series’ so I created an archive page you can view at saltnpixels.com/series. I wanted to show all the posts attached to each series on the archive page. In my archive-snp_series.php, I wrote the following in my loop.

using display():

//in my loop

//the title to this series
the_title();

//first we get the series post as a pod
$related_posts = pods('snp_series', get_the_ID() );

//then we display it
$related_posts = display->('snp_posts_in_this_series' );
echo $related_posts;

What you will get will be a sentence of all the posts we put in that field.

“the first post in the series and the second post in the series and…”

Yup… not as useful. What if we wanted to actually output those posts! On my Series archive I output the title of the archive and then output¬†all the posts for that series.

You will need to use field() or get_post_meta(). These will, of course give us an array but if you var_dump() the array you will see there is actually an array of arrays, (two-dimensional array) each one holding another post. This is because we allowed a series to hold multiple posts.

the array of posts
the array of posts

This array can be quite long if you have many posts, but it gives us an insight as what is going on. The biggest help for me and probably for you is the ID. Yes the ID is the first thing in each post in the array. It is the ID to the post and with that we can do anything! If we can get the ID’s for each post we can loop through them and output whatever we want.

Attaching ID to get¬†just the ID’s

So if you have already read my last article of getting custom fields you know we can do this when it comes to media and relationships:

//get the pod in the loop
$related_posts = pods('snp_series', get_the_ID() );

//get the ID's in the field. NOTE: the ID attached at the end.
var_dump( $related_posts->field('snp_posts_in_this_series.ID') );

Unlike media where we did¬†field('snp_posts_in_this_series.guid');¬†and it gave us the path to the image file, here we will get an array of ID’s. Just one array, holding all the posts ID’s of the posts in the custom field! I used var_dump to make sure it was getting the right stuff. It returned an array of ID’s. Good! So now we can remove var_dump() and instead go through it and do as we want.

//in my loop
the_title();

//get the pod in the loop
$related_posts = pods('snp_series', get_the_ID() );

//get the ID's in the field
$related_posts = $related_posts->field('snp_posts_in_this_series.ID');

if (! empty ($related_posts) ){  //make sure we first get some id's

 foreach($related_posts as $post_id){
 
 //get the thumbnail from the posts ID
 if(has_post_thumbnail($post_id)){
 $thumbnail = get_the_post_thumbnail($post_id);
 }
 
//otherwise use the series post thumbnail
 else{
 $thumbnail = get_the_post_thumbnail();
 }

echo $thumbnail; 
 } //end foreach
} //end if there are id's
 

So whats going on here?
Well here I am as before getting the field with the ID attached. This way it gives me an array of ID’s. Then I check to make sure it’s not an empty array being returned. Then I do a foreach() loop and now I can¬†use any regular WP¬†function that takes the post ID.

Here I told it to get the posts thumbnail. And if the post does not have a thumbnail, it should get the thumbnail for the Series and use that instead. I have done something like this on my site. You can check out how it looks on my site here. I got the thumbnails and the title for each.

And that is how you get related fields and manipulate them as you wish. For me the key is to get the ID’s from the array and in a foreach loop do as you want with them.

Retrieving relationship fields from the one side (post)

On the post side of things, if for some reason you wanted to output that this post was part of a certain Series, you would do a very similar thing. Except because we chose a single select, meaning a post can only be part of ONE series, we wouldn’t have to go through a foreach() loop.

If you remember we extended the post type ‘Post’. We added a custom field of ‘snp_part_of_a_series’. This field is a dropdown that takes one series.

//in my post loop
the_title();
the_content();

//get this post via pods
$related_posts = pods('post', get_the_ID() );

//get the ID's in the field 
echo $related_posts->field('snp_part_of_a_series.ID');

A single select will return an array of one¬†post.¬†Attaching ID at the end would output an integer of one ID. it will not output an array at all with .ID attached.¬†You can of course then do anything with that ID like above. However there would be no need to loop through anything as there is only one ID. And using display() would output the title of the one post. I guess it’s a bit easier on this side of things.

How to know when to use a loop?

The best take away is to always var_dump() and see what you get back and then you will know what needs to be done as to whether it is returning an array, a 2 dimensional array, or just one ID. From playing around I know this:

  • A single select relationship field, using field() will always return an array of the post. Attaching ID will return one integer.
  • A multiple select will return a 2 dimensional array of posts,¬†even when there is only one post found.¬†Attaching ID will return an array of ID’s, also¬† even when one post is found.
  • Custom lists are different and a bit scary: if there are 2 items (multiple select) it returns an array. One item, even on a multiple select will return a string. No array! Beware.

I haven’t discussed a custom list relationship have I? sigh‚Ķ ok here goes‚Ķ I thought this post was over‚Ķ

relating to a list

You can, as I said relate more than just posts. You can relate your list of users to a post, you can relate a taxonomy, you can even relate a post type to itself!

More interestingly you can create a custom list. This is when you want to make a custom field relate to a simple list as opposed to a huge table of real data. The list is very simple to make and output.

a custom list field

As you can see, I have¬†chosen under¬†‘related to:’ a custom defined list. Then I make the list by writing a value, pipeline, and then a label. So in my post I will see this list, perhaps in a dropdown where I can simply choose one of the options (labels) I created. The value is necessary should I need it in my template files.

simple custom list with relationship field
simple custom list with relationship field

Now to show this, is quite simple. Using display() will output the label or labels. So if I choose¬†‘My first option’,¬†the out put would be ‘My first option’. If I had chosen multiple I would get¬†‘My first option and my last option’.

field() will return a string with the value we chose. In my case it will return ‘0’.¬†If there is more than one string it will return an array of the strings. Beware, as noted above, that if you use multiple select, it can still return one string with no array. So check before doing a loop because it may not work.

Well that’s it for now. I think I was pretty thorough with relationship fields. If there is something I missed let me know!

I hope this helped somebody out there…

 

One thought on “Relationship Fields with Pods

  1. Masivuye Bafana Webs says:

    I have a predefined lists of states “Gauteng,Eastern Cape” and Western Cape”, if someone choose western Cape how do I filter the relationship and display only wp elements?

Leave a Reply

Your email address will not be published. Required fields are marked *