Hi,
Thank you for waiting.
Reviewing and testing for the requirements on my website, I feel the closest possible working option would be to use a repeating field group for each skill with the translator profile post and also store a custom field value reference in that same translator profile post, which can be used for the search.
1. You'll add these post types:
a). Translator Profiles
The main post type for the translator profile posts
b). Languages
This will be used for storing all the languages, which can be used for the origin and destination part in the skills.
(e.g. English, German, Italian, etc)
c). Job Types
This will be used for storing all the types of parts in the skills.
(e.g. Translation, Sworn translation, Correction and revision, etc)
2. You'll add a new custom field group "Translator Profile Info" for the "Translator Profiles" post type. In this you'll add a repeating field group "Translator Profile Skill Info" ( slug "translator-skill"), which will have 3 select type fields:
a). Origin Language
b). Destination Language
c). Job Type
You don't need to include any options for these fields, as they will be populated using the "wpt_field_options" filter:
https://toolset.com/documentation/programmer-reference/types-api-filters/#wpt_field_options
Example:
add_filter( 'wpt_field_options', 'populate_skill_field_options', 10, 3);
function populate_skill_field_options( $options, $title, $type ){
switch( $title ){
case 'Origin Language':
case 'Destination Language':
$options = array();
$args = array(
'post_type' => 'language',
'posts_per_page' => -1,
'post_status' => 'publish',
);
$posts_array = get_posts( $args );
$options[] = array('#value' => '', '#title' => '---',);
foreach ($posts_array as $post) {
$options[] = array(
'#value' => $post->ID,
'#title' => $post->post_title,
);
}
break;
case 'Job Type':
$options = array();
$args = array(
'post_type' => 'job-type',
'posts_per_page' => -1,
'post_status' => 'publish',
);
$posts_array = get_posts( $args );
$options[] = array('#value' => '', '#title' => '---',);
foreach ($posts_array as $post) {
$options[] = array(
'#value' => $post->ID,
'#title' => $post->post_title,
);
}
break;
}
return $options;
}
Please note how this function fills in the options for these 3 select fields, from the respective post types.
d). Translator Skills
This can be a single-line type custom field (outside the repeating field group), which can have multiple instances. This will be used to save the value of each skill entry in the format:
{ID of Job Type post}-{ID of Origin Lang post}-{ID of Destination Lang post}
3. After that in the single "Translator Profiles" post page, you can include a new post form that adds entries in the repeating field group "Translator Profile Skill Info", attached to the current post.
This form will have the 3 select custom fields so that an individual skill record can be added.
To perform the extra processing of the saving this submitted skill entry as a direct custom field value in the "Translator Profiles" post's "Translator Skills" field, "cred_save_data" hook can be used:
https://toolset.com/documentation/programmer-reference/cred-api/#cred_save_data
add_action('cred_save_data','process_skill_add_repeating_form',15,2);
function process_skill_add_repeating_form($post_id, $form_data) {
if ($form_data['id']==123) {
$skill_value = $_POST['wpcf-job-type'].'-'.$_POST['wpcf-origin-language'].'-'.$_POST['wpcf-destination-language'];
add_post_meta( $post_id, 'translator-profile', $_POST['_cred_cred_prefix_cred_container_id'], true );
add_post_meta( $_POST['_cred_cred_prefix_cred_container_id'], 'wpcf-translator-skills', $skill_value, false );
}
}
Note: you'll replace "123" with the actual ID of your form. As a result, whenever a new skill entry would be added through the front-end form in the repeating field group, its corresponding direct custom field value would also be stored in the "Translator Skills" field.
4. Another challenge in this structure is to delete the corresponding direct custom field value stored in the "Translator Skills" field when a repeating field entry is deleted.
For that, you can additionally use the "before_delete_post" hook:
https://developer.wordpress.org/reference/hooks/before_delete_post/
Example:
add_action( 'before_delete_post', 'delete_translator_skill' );
function delete_translator_skill( $post_id ) {
// We check if specific type of post is being deleted
if ( get_post_type( $post_id ) !== 'translator-skill' ) {
return;
}
$translator_profile = get_post_meta($post_id, 'translator-profile', true);
$skill_job_type = get_post_meta($post_id, 'wpcf-job-type', true);
$skill_origin_language = get_post_meta($post_id, 'wpcf-origin-language', true);
$skill_destination_language = get_post_meta($post_id, 'wpcf-destination-language', true);
delete_post_meta( $translator_profile, 'wpcf-translator-skills', $skill_job_type.'-'.$skill_origin_language.'-'.$skill_destination_language );
}
Here is a duplicator package of my test website, where you can see these elements in action on the single translator profile pages:
hidden link
( ref: hidden link )
Note: if you feel this structure and approach can work for your project, we can next move on to using this custom field value in the view's search.
regards,
Waqar