我有一个与所有帖子和页面关联的自定义字段。这是所有导航菜单的下拉列表。 这是我填充自定义字段下拉列表的方式:(字段名称为custom_menu ...)
function acf_load_menu_field_choices( $field ) {
// reset choices
$field['choices'] = array();
$menus = get_terms( 'nav_menu', array( 'hide_empty' => true ) );
$blank_list = json_encode(array( "name" => "Select Menu", "slug" => ""));
$blank_list = json_decode($blank_list);
array_unshift($menus, $blank_list);
foreach ( $menus as $val ) {
$value = $val->slug;
$label = $val->name;
$field['choices'][ $value ] = $label;
}
// return the field
return $field;
}
add_filter('acf/load_field/name=custom_menu', 'acf_load_menu_field_choices');
这是我在每个页面上使用的常见菜单位置:
function register_custom_menu() { //function to register new menu
register_nav_menu('custom-menu',__( 'Custom Menu' ));
}
add_action( 'init', 'register_custom_menu' );
然后,我根据每页上的自定义字段菜单,将菜单动态分配给位置custom-menu
。
这是加载页面时会触发的函数:
add_action("wp_ajax_load_custom_menu", "load_custom_menu");
add_action("wp_ajax_nopriv_load_custom_menu", "load_custom_menu");
function load_custom_menu(){
$post_id = $_POST['page_id'];
$page_custom_menu = get_field('custom_menu', $post_id);
if(empty($page_custom_menu) || $page_custom_menu == "primary") return;
$locations = get_theme_mod( 'nav_menu_locations' );
if(!empty($locations)) {
foreach($locations as $locationId => $menuValue) {
if($locationId == "custom-menu") $menu = get_term_by('slug', $page_custom_menu, 'nav_menu');
if(isset($menu)) { $locations[$locationId] = $menu->term_id; }
}
}
set_theme_mod('nav_menu_locations', $locations);
wp_nav_menu( array(
'theme_location' => 'custom-menu',
'menu_id' => 'primary-menu',
'menu_class' => 'main-nav underline-decoration l-to-r-line level-arrows-on outside-item-remove-margin',
'container' => false
)
);
wp_die();
}
此ajax函数在ready
事件上触发,并接收名为POST
的{{1}}值。此函数检查page_id
的给定page_id
的自定义字段值,并将该菜单分配给名为custom-menu
的{{1}}。
这是我的JavaScript,以备您浏览:
menu location
这就是我的代码的工作方式,到目前为止一切正常。
现在是问题所在 每当我从外观>菜单>删除菜单中删除导航菜单时,由于自定义字段值仍指向已删除的菜单,因此我的自定义菜单开始异常运行。 我要在这里做的是,我想在删除菜单时删除自定义字段。 首先,我要获取已删除菜单的信息,然后查找具有该信息的自定义字段值,最后,删除或重置该自定义字段。
答案 0 :(得分:2)
WordPress中的菜单仅为terms in a taxonomy。因此,您可以使用所有术语“挂钩”。
尤其是pre_delete_term钩子。
add_action( 'pre_delete_term', 'my_func' );
function my_func($term, $taxonomy){
// Check the taxonomy is really 'menu', then check term
}
答案 1 :(得分:1)
您正在寻找需要一个参数-wp_delete_nav_menu
的操作menu id
。到那时,您的导航菜单将被删除,因此您将无法处理它。
如果可以存储导航菜单ID而不是子弹,那将大大简化事情。
在acf_load_menu_field_choices
中替换:
foreach ( $menus as $val ) {
$value = $val->term_id;
$label = $val->name;
$field['choices'][ $value ] = $label;
}
在load_custom_menu
中:
$page_custom_menu = get_field('custom_menu', $post_id);
if(empty($page_custom_menu) || $page_custom_menu == /* Should be your primary menu ID */) return;
$locations = get_theme_mod( 'nav_menu_locations' );
if(!empty($locations)) {
foreach($locations as $locationId => $menuValue) {
if($locationId == "custom-menu") $menu = get_term_by('id', $page_custom_menu, 'nav_menu');
if(isset($menu)) { $locations[$locationId] = $menu->term_id; }
}
}
这些更改之后,您将需要在所有帖子\页面中重写custom_menu
。
此后,以下功能将在删除菜单时删除所有相关字段。仅在典型的ACF字段(字符串)上测试了它,而不是对它进行了测试,但也可以在您的代码上正常工作。
add_action('wp_delete_nav_menu', 'delete_all_acf_fields_with_menu', 10, 1);
function delete_all_acf_fields_with_menu($term_id) {
$args = array(
'post_type' => array('post', 'page'),
'posts_per_page' => -1,
'meta_key' => 'custom_menu',
'meta_value' => $term_id,
);
$posts = get_posts($args);
if( $posts ) {
foreach( $posts as $p ) {
delete_field('custom_menu', $p->ID);
}
}
}