简体   繁体   English

在WordPress中删除导航菜单时重置自定义字段

[英]reset custom field when navigation menu is deleted in WordPress

I have a custom field associated with all posts and pages. 我有一个与所有帖子和页面关联的自定义字段。 It's a dropdown of all the navigation menus. 这是所有导航菜单的下拉列表。 here is how I'm populating the custom field drop-down: (the field name is custom_menu...) 这是我填充自定义字段下拉列表的方式:(字段名称为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');

Here is a common menu location that I'm using on each page: 这是我在每个页面上使用的常见菜单位置:

function register_custom_menu() {  //function to register new menu
     register_nav_menu('custom-menu',__( 'Custom Menu' ));
}
add_action( 'init', 'register_custom_menu' );

And then I'm assigning a menu dynamically to the location custom-menu based on the custom field menu on each page. 然后根据每个页面上的自定义字段菜单,将菜单动态分配给位置custom-menu定义菜单。

and here is the function the fires on each page when it's loaded: 这是加载页面时会触发的函数:

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();
}

This ajax function fires on ready event and recieves a POST value called page_id . 此ajax函数在ready事件时触发,并接收名为page_idPOST值。 This function checks the custom field value of the given page_id for custom-menu and assign that menu to the menu location called custom-menu . 此函数检查给定page_idcustom-menu定义字段值的custom-menu并将该菜单分配给名为custom-menumenu location

Here's my JavaScript in case you need to have a look on it: 这是我的JavaScript,以防您需要看一下:

jQuery(document).ready( function($){
    let customMenu;
    let page_id = script_vars.postID;
    $.post(dtLocal.ajaxurl, { action: "load_custom_menu", page_id: page_id }, resp => customMenu = resp);
    $(window).scroll(() => {
        if(customMenu !== "0"){
            $("#phantom .main-nav").remove();
            $("#phantom .menu-box").html(customMenu);
        }
    })
})

This is how my code is working, And everything works fine up to this point. 这就是我的代码的工作方式,到目前为止一切正常。

Now here is the problem Whenever I delete a Navigation menu from Appearence>Menus>Delete Menu My custom Menu starts behaving unexpectedly because the custom field value is still pointing to the deleted Menu. 现在这是一个问题,每当我从外观>菜单>删除菜单中删除导航菜单时,由于自定义字段值仍指向已删除的菜单,因此我的自定义菜单开始出现异常情况 What I want to do here is, I want to Delete the Custom Field whenever a menu is deleted . 我要在这里做的是, 无论何时删除菜单我都想删除自定义字段 First I want to get the slug of a deleted menu and then find the custom field value with that slug and then finally, delete or reset that custom field. 首先,我想获取已删除菜单的信息,然后查找具有该信息的自定义字段值,最后,删除或重置该自定义字段。

Menus in WordPress are just terms in a taxonomy . WordPress中的菜单只是分类法中的术语 So you can use all of the term hooks. 因此,您可以使用所有术语“挂钩”。

In particular the pre_delete_term hook. 特别是pre_delete_term挂钩。

add_action( 'pre_delete_term', 'my_func' );
function my_func($term, $taxonomy){

  // Check the taxonomy is really 'menu', then check term
}

You are looking for action wp_delete_nav_menu that will take one argument - menu id . 您正在寻找wp_delete_nav_menu动作,该动作将wp_delete_nav_menu一个参数- menu id The problem that at that point your nav menu will be deleted, so you won't be able to take it slug. 到那时,您的导航菜单将被删除,因此您将无法处理它。

If it is possible that you can store nav menu ID instead of slug, that would simplify things greatly. 如果可以存储导航菜单ID而不是存储段ID,那将大大简化事情。

In acf_load_menu_field_choices replace: acf_load_menu_field_choices替换:

foreach ( $menus as $val ) {
    $value = $val->term_id;
    $label = $val->name;
    $field['choices'][ $value ] = $label;
}

And in load_custom_menu : 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; }
    }
}

After those changes you will need to rewrite custom_menu in all posts\\pages. 完成这些更改后,您将需要在所有帖子\\页面中重写custom_menu

After that, following function will remove all related fields when you delete menu. 之后,当您删除菜单时,以下功能将删除所有相关字段。 It has been tested only on typical ACF field (string) instead of custom, but should work just fine with your code as well. 它仅在典型的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);
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM