Skip Navigation

[Resolved] Connecting Related Posts

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

Problem: I would like to use Toolset's one-to-many post relationships to link posts of the same post type.

Solution: Toolset's relationship system doesn't support relationships among posts of the same post type. You can work around this by using a custom taxonomy. Create terms in the taxonomy that correspond to each post's slug. Then assign the related terms' slugs to each related post. This can be automated with some custom code.

This support ticket is created 5 years, 5 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)

This topic contains 22 replies, has 2 voices.

Last updated by martinE-4 5 years, 5 months ago.

Assisted by: Christian Cox.

Author
Posts
#1260483
Edit_Resource_‹_ICASC_MIgration_1_—_WordPress.jpg
Edit_Resource_‹_ICASC_MIgration_1_—_WordPress 2.jpg

i find different behavior in the back-end for connecting existing posts in a one-to-many relationship that is set up between posts of the same type on my custom post type='resource'. (My 'resource' posts are research articles and I have a one-to-many relationship to allow a 'resource' to be connected to other related 'resources'. On a single post template, I have successfully displayed a 'resource' along with a view of its related 'resources'. So that part works.)

This relationship has been created during a migration of a Drupal to WordPress site using the FG Drupal to WordPress plugin.

But, some posts show possible 'resources' to connect and some do not show any choices. [See screen grabs.]

Is this intended behavior in the back-end? If so, why?

When I try to setup another Relationship as a test, Types doesn't allow a same post relationship (ie between posts of same custom type "Resource"). What is going on? How does the FG Drupal to WordPress plugin set it up if it is not allowed?

#1260505

Post relationships between posts of the same post type are not supported in Toolset, so I'm not sure how you were able to set this up. If the FG Drupal to WordPress plugin allows it, they should update their software. If you try to create such a relationship in Toolset, it will not be allowed. Since the third-party tool somehow allowed it, the system is now having trouble implementing it. That doesn't surprise me, it's corrupted data. It won't work.

#1260541
Edit_Related_Resources_-_Relationships_‹_ICASC_MIgration_1_—_WordPress.jpg

Wow. I emailed them right away. (image above shows what was erroneously set up).

How should such a relationship be setup properly then? I guess unfortunately Drupal allowed that sort of thing. What is the approach for a same post type relationship in Types? This is pretty important because it effects all the people like me that want to migrate off Drupal to WordPress using Toolset.

I want to allow manual linking of my 'resource' posts to other 'resource' posts (depending on a human judgement call, not on any key field). I guess for a given post this would be a one to many relationship. However, since this relationship should technically allow any one resource post to be related to one or more other resource posts, that would be a many to many relationship, I think.

many thanks

#1260579
Datastan_Meets_Storyland__Surfing_the_Zeitgeist_Without_Wiping_Out_–_ICASC_MIgration_1.jpg

Real pity, because the View I created showing the related resources for each resource (on a single content template) came out beautifully. (see image) Is there any way to salvage this situation? I have several hundred resources (articles) imported from my Drupal database and they all have the related articles as setup by the relationship created by the FG Drupal to WordPress plugin.

Only problem is, adding future related resources doesn't work because the relationship is invalid. (sigh)

many thanks for thinking about this!

#1261199

How should such a relationship be setup properly then?
There is no way to set up a Toolset Relationship that links posts in the same post type. It simply isn't possible in the current system. The alternatives currently supported are:
- A custom taxonomy
- A custom field

One way to achieve this with a custom taxonomy is to create a term that corresponds to each post. For simplicity, I would copy the post slug. Let's say you want to link Post B and Post C to Post A, so that B and C show up on A, and A shows up on B and C. You would create 3 terms, one for each post. On the post template, you would insert a View of posts that is filtered by the custom taxonomy, where the term is set by one shortcode attribute. You will place the current post's slug inside that shortcode attribute. So now any post with post A's term assigned will show up in the results. So in Post B and Post C, you must add Post A's term. In Post A, you must add Post B and Post C.

#1261609

Ok, I will put in a feature request to implement/re-implement self-relationships for posts.

For the workaround, here is my pseudocode logic approach:
1. Taxonomy approach sounds good. I wonder if there is a way to set this up bi-directionally for ease of use? (see step 3 below)
2. I assume I need to use Toolset Forms to create a post-picker (similar to how a relationship in the back-end currently works). Is this possible? I haven't used Forms yet but I'm keen to try...
3. After choosing a post to link to (with the picker), I would need a button that would have a script to assign the current post A slug to the taxonomy of post B and vice-versa. In that way I would be linking post A to B and vice versa. Is there some code you can suggest?
4. I also have to worry about the current data and assigning it to the correct taxonomies of the linked posts. Perhaps the easiest way will be to create the form (steps 2-3 above) and then manually go through my 400 posts (referring to my view which shows the linked posts) to assign the correct taxonomy, unless you think of an easier approach...

Thanks so much for your support on this workaround,
Martin

#1261641

2. I assume I need to use Toolset Forms to create a post-picker (similar to how a relationship in the back-end currently works). Is this possible? I haven't used Forms yet but I'm keen to try...
I haven't implemented this on the front-end with Forms before. You're welcome to try. It would probably be easier to implement a simple taxonomy input field, but that assumes you have knowledge of the other posts' slugs. Implementing a post select field will be tricky, especially if you let people edit posts with Forms.

3. After choosing a post to link to (with the picker), I would need a button that would have a script to assign the current post A slug to the taxonomy of post B and vice-versa. In that way I would be linking post A to B and vice versa. Is there some code you can suggest?
You can use the cred_save_data hook to capture the selection, then apply the terms using wp_set_object_terms.
https://codex.wordpress.org/Function_Reference/wp_set_object_terms
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data

Perhaps the easiest way will be to create the form (steps 2-3 above) and then manually go through my 400 posts
Easiest is subjective here. The Toolset way would be to use Forms. Another approach would be to use a custom script that queries all the posts, loops over them, and applies the proper terms. Depending on your level of comfort with custom code, that might be easier.

#1261711

Since the slugs are lengthy things that the user would have no idea of, it would be imperative to have a front-end form with a post-picker to select posts (you call it a post select field). are these links a good start?
https://toolset.com/forums/topic/display-post-relationship-fields-in-cred-form/
https://toolset.com/forums/topic/cred-form-dropdown-with-custom-posts/
https://toolset.com/forums/topic/auto-populate-dropdown/

This is how I see the pseudocode of the approach to build a front-end form to assign related posts (using an auto-populated dropdown) with your taxonomy method.
1. Create an edit form for my custom post type 'Resource' which will be accessed via a link on the single post content template for resource (visible to editors only)
2. Create a view of all my resource posts with JSON output.
3. On the CRED edit form, Insert a Generic Field, choose "Select", and enter the shortcode to the View (2 above) which produces the JSON listing. This view should allow the user to cycle through the posts in the dropdown and pick the one to link. (Since I have 400 posts it would be nice to also search the view but first things first...)
4. then a button to execute the cred_save_data hook should capture the selection and also apply terms using wp_set_object_terms to the post selected and to the current post (can I put two scripts in a button or do I need two buttons - select and apply?)

Am I on the right track? Any further documentation or example would be wonderful...

many thanks

#1264177

This view should allow the user to cycle through the posts in the dropdown and pick the one to link.
You can't use a post relationships field, unfortunately, if you decide to go down the taxonomy route. As you mentioned, you will have to create a picker manually using a generic field. The generic field types offered in Forms are relatively simple. You can use a select field or a multiple select field, but there is no front-end filter or search mechanism to modify the options in that field. Also there is no typeahead or auto-suggest field type. You'll have access to a simple select field or multiple select field, including all the options provided by the View. You'll have to be able to handle previously selected items, in case you need to make changes later.

can I put two scripts in a button or do I need two buttons - select and apply?
You will have one "submit" button in the Form. That single submit button triggers the form submission and, if the contents are validated successfully, then triggers the cred_save_data hook. You can add multiple lines of code into the callback function, so that could include all the term inspection and assignment operations.

Any further documentation or example would be wonderful...
Set taxonomy terms based on a generic field value from $_POST:
https://toolset.com/forums/topic/fixed-taxonomy-category-values-in-form/#post-805454
Get terms previously assigned to a given post:
https://codex.wordpress.org/Function_Reference/wp_get_object_terms/

#1266373

I've successfully made a simple one field CRED form with a generic select dropdown field containing a view showing all Resource posts.

Now I'm working on getting the selected post slug from the generic field so I can assign it to the taxonomy of the current edited post.

I'm looking at your link:
https://toolset.com/forums/topic/fixed-taxonomy-category-values-in-form/#post-805454
but I'm stuck with your advice here:
... an example where the generic select field has the slug generic-select-term:

add_action('cred_save_data', 'set_term_from_generic_select',100,2);
 
function set_term_from_generic_select($post_id, $form_data) {
  $forms = array( 12345 );
  if( in_array( $form_data['id'], $forms) ){
    $taxonomy = 'adverts';
    $tag = $_POST['generic-select-term'];
    wp_set_object_terms( $post_id, $tag, $taxonomy, true );
  }
}

Is this the function I would need to construct my taxonomy term from the related post slug and assign it to the current post?

#1266679

Yes, these two lines get the value of the generic select field from the Form, then use it to set a term on the post:

    $tag = $_POST['generic-select-term'];
    wp_set_object_terms( $post_id, $tag, $taxonomy, true );

The value should be the post slug / term slug since they are identical. Then you must also get the slug of the newly created post and apply that as a term to the selected post.

#1268373

Sorry, the function:

/**
 * add function for CRED form edit Resource with Related Resource
 */
  
function set_term_from_generic_select( $post_id, $form_data ) {
  $forms = array( 10191 );
  if ( in_array( $form_data['id'], $forms ) ) {
    $taxonomy = 'related';
    $tag = $_POST['related-resource'];
    wp_set_object_terms( $post_id, $tag, $taxonomy, true );
  }
}
add_action('cred_save_data', 'set_term_from_generic_select',100,2);

gives this error when in functions.php:
( ! ) Parse error: syntax error, unexpected 'function' (T_FUNCTION) in /app/public/wp-content/themes/generatepress/functions.php on line 70

Line 70 is the function line

Also, would the code to relate the current newly created post to the selected post be (for the reverse bi-directional case):

    $post_id_selected = ??  /* need id of selected post....?
    $tag_selected = $_POST[$post_id];  /* need slug of current post
    wp_set_object_terms( $post_id_selected, $tag_selected, $taxonomy, true );
#1268415

There's nothing inherently invalid in the syntax you have there. If I copy it and paste into my own functions.php file, it does not throw an error. That could mean something before the functions line is not terminated correctly, or you have added code outside the closing PHP tag, or something else I can't predict.

/app/public/wp-content/themes/generatepress/functions.php on line 70

The path here seems to indicate you have added code directly in the generatepress theme's functions.php file. Was that intentional? That could be part of the problem, but I'm not sure. You should always create a child theme and put custom code in the child theme's functions.php file. Otherwise your code will be lost next time the theme is updated.

#1268527

I was going to do a child theme after I got this working...
I tried the Code Snippets plugin which has a nice parse error feature on each line and some of the lines required retyping to get rid of parse errors. Weird there must have been invisibles hidden when I copied your code off my browser. Anyways its working fine after retyping. Anyways this Code Snippets plugin gives a nice warning if a line has invisibles. I better make sure I am using plain text. At least the php syntax was right!

For the next lines of code I need to grab the post id of the selected post in the generic select. Not sure how to do this?

    $post_id_selected = ??  /* need id of selected post....get_the_ID()?
    $tag_selected = $_POST['post_id'];  /* need slug of current post
    wp_set_object_terms( $post_id_selected, $tag_selected, $taxonomy, true );
#1268621

So the generic field option values are post slugs, correct? To get the value of the selected item in the callback, look for the generic field slug as a key in the $_POST superglobal. If the generic field slug is "my-generic-select" then you will find the selected value in $_POST['my-generic-select'];

To convert that post slug to a post ID you can use the WordPress API get_page_by_path: https://codex.wordpress.org/Function_Reference/get_page_by_path

You have access to the newly created post's ID in the cred_save_data callback's first parameter, in this example it's $post_id:

function set_term_from_generic_select($post_id, $form_data) {
  // $post_id is the ID of the post you just created in Forms
  ..

To get the post slug of the current post, use the WordPress API get_post().
https://developer.wordpress.org/reference/functions/get_post/

The get_post API returns a post object. The slug can be found in the post_name key.
https://stackoverflow.com/questions/33842251/how-to-get-post-slug-from-post-in-wordpress

Making sense so far?