admin管理员组文章数量:1122846
I have two custom taxonomies on the site - Countries and Cities.
The Country taxonomy contains over 200 terms, and the Cities taxonomy contains over 47,000 terms.
Naturally, editing content with reference to such a large taxonomy is very resource-intensive.
So the task arose to link these two taxonomies and load the list of cities only for the selected country on Post Edit (Add) screen.
Now Cities taxonomy terms have a meta field linked to Country.
I have two metaboxes (post_category_meta_box type) on the custom post type (ex. Event) editing page.
How can I implement the following features:
- by default for new content, do not display a list of cities, but replace it with the (zero) value - "First select a country"
- when selecting a Country (post_category_meta_box) - update the Cities metabox, indicating only the cities of the selected country
A similar task was discussed on wordpress, but I don’t know how it was implemented. Post Edit – Filter Terms on Meta-box 1 based on selected terms of Meta-box 2
I will be glad to any help. Note: content can be linked to different countries and several cities.
Here's what I did:
- added a script to the post editor window for selecting countries
`
/* Set linked process with country taxonomy */
function cities_add_admin_scripts( $hook ) {
global $post;
if ( $hook == 'post-new.php' || $hook == 'post.php' ) {
if ( in_array($post->post_type, ['hotel','event','sight','webcamera'])) {
wp_add_inline_script( "jquery",
"(function($){
function city_doing_ajax( countries ){
$.ajax({
url: ajaxurl,
method: 'post',
dataType: 'json',
data: {action: 'city_filter', countries: countries, nonce: '" . wp_create_nonce('myajax-nonce') . "'}
}).done(function(data){
console.log(data);
});
}
$(document).ready(function() {
/* set starting values */
var countries = $('#countrychecklist input[type=\"checkbox\"]:checked').map(function(){ return $(this).val();}).get();
console.log('countries Ids:', countries);
if(countries.length > 0){
city_doing_ajax(countries);
}
$('#countrychecklist input[type=\"checkbox\"]').change(function() {
countries = $('#countrychecklist input[type=\"checkbox\"]:checked').map(function(){ return $(this).val();}).get();
console.log('renew countries Ids:', countries);
city_doing_ajax(countries);
});
})})(jQuery);" );
}
}
}
` I do this twice. Immediately after loading the form, to have a list of already marked countries, and for each select (unselect) of the form
Next, I hang the handler on the Ajax request
`
add_action( 'wp_ajax_city_filter', array(
$this, 'city_ajax_action_callback'
) );
`
and the code of the Ajax processing function itself
`
function city_ajax_action_callback(){
$countries_ids = array_map( 'intval', $_POST['countries'] );
if(!empty( $countries_ids ) ) {
$country_abbr = get_terms([
'taxonomy' => 'country',
'hide_empty' => false,
'fields' => 'all', /* slug not exists as parameter*/
'include' => $countries_ids
]);
if( $country_abbr && ! is_wp_error( $country_abbr ) ){
$countr_codes = [];
foreach ($country_abbr as $term) $countr_codes[] = $term->slug;
**$this->country_codes** = $countr_codes;
add_action('parse_term_query', array($this, 'city_filter_term_query'));
} else {
remove_action('parse_term_query', array($this, 'city_filter_term_query'));
}
wp_send_json_success();
} else {
/* remove_action('parse_term_query', array($this, 'city_filter_term_query')); */
wp_send_json_error();
}
}
`
and the last function adds our filter at the stage of preparing the request to the table of terms
`
function city_filter_term_query( $wp_term_query ){
$taxonomy = $wp_term_query->query_vars['taxonomy'];
if( is_admin() && $taxonomy == 'city' && (! empty($this->country_codes))){
$meta_query = [
'relation' => 'AND',
];
$meta_query[] = [
'key' => 'country_code',
'value' => **$this->country_codes**,
'compare' => 'IN',
];
$wp_term_query->query_vars['meta_query'] = $meta_query;
error_log( print_r(['city_filter_term_query' => $wp_term_query], true ) );
}
}
`
I note that all this is implemented in the CityTaxonomy
class, where there is a field (highlighted in bold)
private $country_codes = [];
I have two custom taxonomies on the site - Countries and Cities.
The Country taxonomy contains over 200 terms, and the Cities taxonomy contains over 47,000 terms.
Naturally, editing content with reference to such a large taxonomy is very resource-intensive.
So the task arose to link these two taxonomies and load the list of cities only for the selected country on Post Edit (Add) screen.
Now Cities taxonomy terms have a meta field linked to Country.
I have two metaboxes (post_category_meta_box type) on the custom post type (ex. Event) editing page.
How can I implement the following features:
- by default for new content, do not display a list of cities, but replace it with the (zero) value - "First select a country"
- when selecting a Country (post_category_meta_box) - update the Cities metabox, indicating only the cities of the selected country
A similar task was discussed on wordpress.org, but I don’t know how it was implemented. Post Edit – Filter Terms on Meta-box 1 based on selected terms of Meta-box 2
I will be glad to any help. Note: content can be linked to different countries and several cities.
Here's what I did:
- added a script to the post editor window for selecting countries
`
/* Set linked process with country taxonomy */
function cities_add_admin_scripts( $hook ) {
global $post;
if ( $hook == 'post-new.php' || $hook == 'post.php' ) {
if ( in_array($post->post_type, ['hotel','event','sight','webcamera'])) {
wp_add_inline_script( "jquery",
"(function($){
function city_doing_ajax( countries ){
$.ajax({
url: ajaxurl,
method: 'post',
dataType: 'json',
data: {action: 'city_filter', countries: countries, nonce: '" . wp_create_nonce('myajax-nonce') . "'}
}).done(function(data){
console.log(data);
});
}
$(document).ready(function() {
/* set starting values */
var countries = $('#countrychecklist input[type=\"checkbox\"]:checked').map(function(){ return $(this).val();}).get();
console.log('countries Ids:', countries);
if(countries.length > 0){
city_doing_ajax(countries);
}
$('#countrychecklist input[type=\"checkbox\"]').change(function() {
countries = $('#countrychecklist input[type=\"checkbox\"]:checked').map(function(){ return $(this).val();}).get();
console.log('renew countries Ids:', countries);
city_doing_ajax(countries);
});
})})(jQuery);" );
}
}
}
` I do this twice. Immediately after loading the form, to have a list of already marked countries, and for each select (unselect) of the form
Next, I hang the handler on the Ajax request
`
add_action( 'wp_ajax_city_filter', array(
$this, 'city_ajax_action_callback'
) );
`
and the code of the Ajax processing function itself
`
function city_ajax_action_callback(){
$countries_ids = array_map( 'intval', $_POST['countries'] );
if(!empty( $countries_ids ) ) {
$country_abbr = get_terms([
'taxonomy' => 'country',
'hide_empty' => false,
'fields' => 'all', /* slug not exists as parameter*/
'include' => $countries_ids
]);
if( $country_abbr && ! is_wp_error( $country_abbr ) ){
$countr_codes = [];
foreach ($country_abbr as $term) $countr_codes[] = $term->slug;
**$this->country_codes** = $countr_codes;
add_action('parse_term_query', array($this, 'city_filter_term_query'));
} else {
remove_action('parse_term_query', array($this, 'city_filter_term_query'));
}
wp_send_json_success();
} else {
/* remove_action('parse_term_query', array($this, 'city_filter_term_query')); */
wp_send_json_error();
}
}
`
and the last function adds our filter at the stage of preparing the request to the table of terms
`
function city_filter_term_query( $wp_term_query ){
$taxonomy = $wp_term_query->query_vars['taxonomy'];
if( is_admin() && $taxonomy == 'city' && (! empty($this->country_codes))){
$meta_query = [
'relation' => 'AND',
];
$meta_query[] = [
'key' => 'country_code',
'value' => **$this->country_codes**,
'compare' => 'IN',
];
$wp_term_query->query_vars['meta_query'] = $meta_query;
error_log( print_r(['city_filter_term_query' => $wp_term_query], true ) );
}
}
`
I note that all this is implemented in the CityTaxonomy
class, where there is a field (highlighted in bold)
private $country_codes = [];
- Please edit the question to limit it to a specific problem with enough detail to identify an adequate answer. – Community Bot Commented Oct 3, 2024 at 3:51
1 Answer
Reset to default 0My approach would be:
- Hide city edition metabox, by setting
public
to false. - I would override how metabox for country should render by using
meta_box_cb
parameter. You should provide callback for the function that will do the render. - In this function, you first render the field for country, and then on choose you make an AJAX request to your backend to gather a list of the cities for the provided country.
本文标签:
版权声明:本文标题:categories - Two related taxonomies. how to filter terms in second taxonomy depending on selected term in first taxonomy on Post 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736282949a1926808.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论