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?
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.
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
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!
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.
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
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.
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
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/
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?
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.
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 );
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.
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 );
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?