- VisualStudio2022插件的安装及使用-编程手把手系列文章
- pprof-在现网场景怎么用
- C#实现的下拉多选框,下拉多选树,多级节点
- 【学习笔记】基础数据结构:猫树
效果图如下 。
。
。
目前这个预览菜单这个效果有点问题,但是不影响实际排序,有懂源码的朋友可以自行修改一下, 目录结构 menu -assets menu.css 。
menu.js 。
menu.php 。
源码如下 menu.php文件 。
<?php /** * Plugin Name: 菜单整理 * Description: 将 WooCommerce 产品分类添加到现有菜单中。 * Version: 1.2 * Author: 朵啦 * License: GPL2 */ // 防止直接访问文件 if (!defined('ABSPATH')) { exit; } // 注册插件设置页面 add_action('admin_menu', 'cmo_add_admin_menu'); function cmo_add_admin_menu() { add_menu_page( '分类菜单管理', // 页面标题 '分类菜单', // 菜单标题 'manage_options', // 权限 'cmo-settings', // 菜单 slug 'cmo_settings_page', // 回调函数 'dashicons-menu', // 图标 60 // 位置 ); } // 引入 JS 和 CSS 文件 add_action('admin_enqueue_scripts', 'cmo_enqueue_scripts'); function cmo_enqueue_scripts() { wp_enqueue_script('cmo-menu-js', plugin_dir_url(__FILE__) . 'assets/menu.js', ['jquery'], false, true); wp_enqueue_style('cmo-menu-css', plugin_dir_url(__FILE__) . 'assets/menu.css'); } // 使 ajaxurl 变量在前端 JavaScript 中可用 add_action('admin_enqueue_scripts', 'add_ajax_url'); function add_ajax_url() { wp_localize_script('cmo-menu-js', 'ajaxurl', admin_url('admin-ajax.php')); } // 设置页面的显示内容 function cmo_settings_page() { ?> <div class="wrap"> <h1>WooCommerce 分类菜单管理</h1> <form method="post" action="options.php"> <?php settings_fields('cmo_settings_group'); function cmo_section_text() { echo '<p>选择要添加到菜单的产品分类</p>'; } do_settings_sections('cmo-settings'); ?> </form> <h2>菜单操作</h2> <form method="post" action="" id="menu-action-form"> <label for="cmo_menu_selector">选择菜单:</label> <?php cmo_menu_selector(); ?> <button type="button" id="cmo_add_to_menu" class="button button-primary">添加分类到选定菜单</button> <button type="button" id="cmo_backup_menu" class="button">备份当前菜单</button> <button type="button" id="cmo_restore_menu" class="button">恢复备份菜单</button> </form> <div id="menu-preview"> <h3>菜单预览</h3> <div id="preview-content"></div> </div> </div> <?php } // 注册设置字段 add_action('admin_init', 'cmo_settings_init'); function cmo_settings_init() { register_setting('cmo_settings_group', 'cmo_selected_categories'); add_settings_section( 'cmo_main_section', '选择要添加到菜单的产品分类', 'cmo_section_text', 'cmo-settings' ); add_settings_field( 'cmo_categories_field', '产品分类', 'cmo_categories_field_callback', 'cmo-settings', 'cmo_main_section' ); } // 分类选择字段回调,递归展示分类 function cmo_categories_field_callback($parent = 0, $level = 0) { if ($parent == 0 || $level == 0) { // 只在最顶层展示全选按钮 echo '<input type="checkbox" id="select-all"> 全选<br><div style="display: flex; flex-wrap: wrap;">'; } $categories = get_terms([ 'taxonomy' => 'product_cat', 'hide_empty' => false, 'parent' => $parent // 通过 parent 参数递归获取子分类 ]); $selected_categories = get_option('cmo_selected_categories', []); if (!is_array($selected_categories)) { $selected_categories = []; } foreach ($categories as $category) { // 缩进效果,表示分类层级 $indent = str_repeat(' ', $level); echo '<div style="flex-basis: 100%; margin-left:' . ($level * 20) . 'px;">' . '<input type="checkbox" name="cmo_selected_categories[]" value="' . esc_attr($category->term_id) . '" ' . checked(in_array($category->term_id, $selected_categories), true, false) . '> ' . esc_html($category->name) . '</div>'; // 递归调用自己,展示子分类 cmo_categories_field_callback($category->term_id, $level + 1); } if ($parent == 0 && $level == 0) { // 结束顶层div echo '</div>'; } } // 生成分类菜单选择器 function cmo_menu_selector() { $menus = wp_get_nav_menus(); echo '<select name="cmo_selected_menu" id="cmo_menu_selector">'; foreach ($menus as $menu) { echo '<option value="' . esc_attr($menu->term_id) . '">' . esc_html($menu->name) . '</option>'; } echo '</select>'; } // 添加分类到菜单的功能 add_action('wp_ajax_cmo_add_to_menu', 'cmo_add_categories_to_menu'); function cmo_add_categories_to_menu() { if (!isset($_POST['menu_id'])) { wp_send_json_error('菜单ID未设置'); } $menu_id = intval($_POST['menu_id']); if (!isset($_POST['selected_categories']) || empty($_POST['selected_categories'])) { wp_send_json_error('未选择任何分类'); } $selected_categories = $_POST['selected_categories']; // 创建一个数组来保存分类和菜单项的 ID 关联 $category_menu_items = []; // 循环处理选中的分类 foreach ($selected_categories as $category_id) { $category = get_term($category_id, 'product_cat'); // 获取当前分类的父分类 ID $parent_id = $category->parent; // 如果父分类已存在菜单项,则将其设置为子菜单项 $parent_menu_item_id = isset($category_menu_items[$parent_id]) ? $category_menu_items[$parent_id] : 0; // 添加菜单项,并保存它的 ID $menu_item_id = wp_update_nav_menu_item($menu_id, 0, [ 'menu-item-title' => esc_html($category->name), 'menu-item-url' => get_term_link($category), 'menu-item-status' => 'publish', 'menu-item-parent-id' => $parent_menu_item_id, // 指定父菜单项 ]); // 将当前分类的菜单项 ID 保存到数组中,供子分类使用 $category_menu_items[$category_id] = $menu_item_id; } wp_send_json_success('分类已成功添加到菜单'); } // 备份当前菜单 add_action('wp_ajax_cmo_backup_menu', 'cmo_backup_menu'); function cmo_backup_menu() { if (!isset($_POST['menu_id'])) { wp_send_json_error('菜单ID未设置'); } $menu_id = intval($_POST['menu_id']); $menu_items = wp_get_nav_menu_items($menu_id); if ($menu_items) { update_option('cmo_menu_backup_' . $menu_id, $menu_items); wp_send_json_success('菜单已成功备份'); } wp_send_json_error('备份失败'); } // 恢复备份菜单 add_action('wp_ajax_cmo_restore_menu', 'cmo_restore_menu'); function cmo_restore_menu() { if (!isset($_POST['menu_id'])) { wp_send_json_error('菜单ID未设置'); } $menu_id = intval($_POST['menu_id']); $backup = get_option('cmo_menu_backup_' . $menu_id); if ($backup) { foreach ($backup as $item) { wp_update_nav_menu_item($menu_id, 0, [ 'menu-item-title' => esc_html($item->title), 'menu-item-url' => $item->url, 'menu-item-status' => 'publish', ]); } wp_send_json_success('菜单已成功恢复'); } wp_send_json_error('没有备份可恢复'); } // 预览菜单内容 add_action('wp_ajax_cmo_preview_menu', 'cmo_preview_menu'); function cmo_preview_menu() { if (!isset($_POST['menu_id'])) { wp_send_json_error('菜单ID未设置'); } $menu_id = intval($_POST['menu_id']); $menu_items = wp_get_nav_menu_items($menu_id); if (empty($menu_items)) { wp_send_json_error('该菜单没有内容'); } $html = '<ul class="menu-preview">'; foreach ($menu_items as $item) { // 根据菜单项的 parent 判断是否是子项 if ($item->menu_item_parent == 0) { $html .= '<li class="menu-item">' . esc_html($item->title); // 查找子项 $html .= get_menu_child_items($menu_items, $item->ID); $html .= '</li>'; } } $html .= '</ul>'; wp_send_json_success($html); } // 获取子菜单项的递归函数 function get_menu_child_items($menu_items, $parent_id) { $child_items = ''; foreach ($menu_items as $item) { if ($item->menu_item_parent == $parent_id) { if ($child_items == '') { $child_items .= '<ul class="submenu">'; } $child_items .= '<li class="menu-item">' . esc_html($item->title); $child_items .= get_menu_child_items($menu_items, $item->ID); $child_items .= '</li>'; } } if ($child_items != '') { $child_items .= '</ul>'; } return $child_items; } ?>
menu.css文件 。
/* 调整预览框的高度和宽度 */ #menu-preview { margin-top: 20px; border: 1px solid #ddd; padding: 10px; background-color: #f9f9f9; width: 100%; /* 让框的宽度适应容器 */ height: 400px; /* 设置高度为400px,具体可根据需要调整 */ overflow-y: auto; /* 让框的内容可以滚动 */ box-shadow: 0 4px 10px rgba(0, 0, 0, 0.1); /* 添加阴影效果 */ } /* 一级菜单样式 */ .menu-preview { display: flex; flex-direction: row; list-style: none; padding: 0; margin: 0; } .menu-item { position: relative; padding: 10px 20px; background-color: #f0f0f0; margin-right: 10px; cursor: default; border: 1px solid #ccc; /* 添加边框 */ border-radius: 5px; /* 圆角效果 */ font-weight: bold; /* 让文字加粗 */ transition: background-color 0.3s ease; /* 添加背景颜色的过渡效果 */ } /* 一级菜单悬浮效果 */ .menu-item:hover { background-color: #e0e0e0; border-color: #b0b0b0; /* 悬浮时改变边框颜色 */ } /* 子菜单样式 */ .submenu { display: none; position: absolute; top: 100%; left: 0; background-color: white; list-style: none; padding: 0; margin: 0; box-shadow: 0 8px 16px rgba(0, 0, 0, 0.1); z-index: 10; /* 确保子菜单在顶层显示 */ opacity: 0; /* 初始透明度 */ visibility: hidden; /* 初始不可见 */ transition: opacity 0.3s ease, visibility 0.3s ease; /* 过渡效果 */ } /* 子菜单项的样式 */ .submenu .menu-item { padding: 10px; margin-right: 0; white-space: nowrap; background-color: #ffffff; border: 1px solid #ddd; /* 给子菜单项添加边框 */ border-radius: 3px; } /* 子菜单项的悬浮效果 */ .submenu .menu-item:hover { background-color: #f0f0f0; } /* 一级菜单悬浮时显示子菜单 */ .menu-item:hover .submenu { display: block; opacity: 1; /* 显示时渐变透明度 */ visibility: visible; /* 显示可见 */ z-index: 999; } /* 让一级菜单项和子菜单保持距离 */ .menu-item:hover .submenu { margin-top: 5px; } /* 调整子菜单的位置 */ .submenu { min-width: 200px; /* 给子菜单设置最小宽度 */ z-index: 1000; } /* 鼠标移开子菜单后延迟消失 */ .menu-item { transition: background-color 0.3s ease; } /* 子菜单在鼠标移开后延迟消失 */ .menu-item:hover .submenu { transition: opacity 0.3s ease, visibility 0.3s ease; } .menu-item .submenu { transition-delay: 1.5s; /* 添加延迟消失效果 */ } /* 阻止点击行为,确保只是预览 */ .menu-preview a { pointer-events: none; color: #333; text-decoration: none; cursor: default; }
menu.js 。
document.addEventListener('DOMContentLoaded', function() { // 禁用菜单预览的点击事件 const previewLinks = document.querySelectorAll('.menu-preview .menu-item'); previewLinks.forEach(function(link) { link.addEventListener('click', function(event) { event.preventDefault(); // 禁用默认的点击行为 }); }); // 处理菜单悬停显示子菜单 const menuItems = document.querySelectorAll('.menu-item'); menuItems.forEach(function(menuItem) { let timer; // 定义延时计时器 menuItem.addEventListener('mouseenter', function() { clearTimeout(timer); // 清除离开时的计时器,确保子菜单正常显示 const submenu = this.querySelector('.submenu'); if (submenu) { submenu.style.display = 'block'; submenu.style.opacity = '1'; submenu.style.visibility = 'visible'; } }); menuItem.addEventListener('mouseleave', function() { const submenu = this.querySelector('.submenu'); if (submenu) { timer = setTimeout(function() { submenu.style.opacity = '0'; submenu.style.visibility = 'hidden'; }, 1500); // 鼠标离开 1.5 秒后隐藏子菜单 } }); }); // 全选功能 const selectAllCheckbox = document.getElementById('select-all'); if (selectAllCheckbox) { selectAllCheckbox.addEventListener('click', function () { const checkboxes = document.querySelectorAll('input[name="cmo_selected_categories[]"]'); checkboxes.forEach(checkbox => checkbox.checked = this.checked); console.log('全选按钮已点击'); }); } // 按钮点击事件 const addToMenuButton = document.getElementById('cmo_add_to_menu'); if (addToMenuButton) { addToMenuButton.addEventListener('click', function (event) { console.log('添加分类到选定菜单按钮已点击'); handleMenuAction('cmo_add_to_menu', '添加分类到选定菜单', event); }); } const backupMenuButton = document.getElementById('cmo_backup_menu'); if (backupMenuButton) { backupMenuButton.addEventListener('click', function (event) { handleMenuAction('cmo_backup_menu', '备份当前菜单', event); }); } const restoreMenuButton = document.getElementById('cmo_restore_menu'); if (restoreMenuButton) { restoreMenuButton.addEventListener('click', function (event) { handleMenuAction('cmo_restore_menu', '恢复备份菜单', event); }); } // 预览菜单 const menuSelector = document.getElementById('cmo_menu_selector'); if (menuSelector) { menuSelector.addEventListener('change', function () { const menuId = this.value; loadMenuPreview(menuId); }); } }); // 处理按钮点击的AJAX请求 function handleMenuAction(action, message, event) { const menuId = document.getElementById('cmo_menu_selector').value; console.log('处理菜单:', menuId); const button = event.target; button.disabled = true; button.innerHTML = '处理中...'; // 获取选中的分类 const selectedCategories = Array.from(document.querySelectorAll('input[name="cmo_selected_categories[]"]:checked')).map(input => input.value); if (selectedCategories.length === 0) { alert("未选择任何分类"); button.disabled = false; button.innerHTML = message; console.log('未选择分类'); return; } console.log('发送的分类:', selectedCategories); // 发送 AJAX 请求 jQuery.post(ajaxurl, { action: action, menu_id: menuId, selected_categories: selectedCategories // 传递选中的分类数据 }, function(response) { console.log('Response:', response); button.disabled = false; button.innerHTML = message; if (response.success) { alert(response.data); console.log('操作成功'); if (action === 'cmo_add_to_menu' || action === 'cmo_preview_menu') { loadMenuPreview(menuId); } } else { console.log('操作失败:', response.data); alert('操作失败: ' + response.data); } }); } // 加载菜单预览 function loadMenuPreview(menuId) { document.getElementById('preview-content').innerHTML = '加载中...'; jQuery.post(ajaxurl, { action: 'cmo_preview_menu', menu_id: menuId }, function (response) { if (response.success) { document.getElementById('preview-content').innerHTML = response.data; } else { document.getElementById('preview-content').innerHTML = '预览加载失败'; } }); }
。
最后此篇关于WordPress产品分类添加,自动排序插件的文章就讲到这里了,如果你想了解更多关于WordPress产品分类添加,自动排序插件的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我正在尝试对每个条目有多个值的关联数组进行排序。 例如 [0] => stdClass Object ( [type] => node [sid] => 158 [score] => 0.059600
我在 mysql 中有“日期”列以这种格式保存日期 2014 年 9 月 17 日(日-月-年) 我需要对它们进行升序排序,所以我使用了这个命令: SELECT * FROM table ORDER
我目前正在将 MySQL 存储过程重写为 MS SQL 存储过程,但遇到了问题。 在 MySQL 存储过程中,有一个游标,它根据最近的日期 (effdate) 选择一个值并将其放入变量 (thestt
我想要 gwt r.QuestionId- 排序。但是我得到未排序的 QuestionId 尽管我提到了 QuestionId ASC 的顺序。 SELECT r.QuestionId,
我有一个关于在 scandir 函数中排序的基本问题。到目前为止,我阅读了 POSIX readdir 的手册页,但没有找到有关订购保证的具体信息。 但是当我遍历大目录(无法更改,只读)时,我在多个系
基本上我必须从 SQL 数据库中构建项目列表,但是用户可以选择对 7 个过滤器的任意组合进行过滤,也可以选择要排序的列以及按方向排序。 正如您可以想象的那样,这会以大量不同的组合进行编码,并且数据集非
我有两张 table 。想象第一个是一个目录,包含很多文件(第二个表)。 第二个表(文件)包含修改日期。 现在,我想选择所有目录并按修改日期 ASC 对它们进行排序(因此,最新的修改最上面)。我不想显
我想先根据用户的状态然后根据用户名来排序我的 sql 请求。该状态由 user_type 列设置: 1=活跃,2=不活跃,3=创始人。 我会使用此请求来执行此操作,但它不起作用,因为我想在“活跃”成员
在 C++ 中,我必须实现一个“类似 Excel/Access”(引用)的查询生成器,以允许对数据集进行自定义排序。如果您在 Excel 中使用查询构建器或 SQL 中的“ORDER BY a, b,
我面临这样的挑战: 检索按字段 A 排序的文档 如果字段 B 存在/不为空 . 否则 按字段排序 C. 在 SQL 世界中,我会做两个查询并创建一个 UNION SELECT,但我不知道如何从 Mon
我想对源列表执行以下操作: map 列表 排序 折叠 排序 展开 列表 其中一些方法(例如map和toList)是可链接的,因为它们返回非空对象。但是,sort 方法返回 void,因为它对 List
我制作了一个用于分析 Windows 日志消息编号的脚本。 uniq -c 数字的输出很难预测,因为根据数字的大小会有不同的空白。此时,我手动删除了空白。 这是对消息进行排序和计数的命令: cat n
我有以下词典: mydict1 = {1: 11, 2: 4, 5: 1, 6: 1} mydict2 = {1: 1, 5: 1} 对于它们中的每一个,我想首先按值(降序)排序,然后按键(升序)排序
我刚刚开始使用泛型,目前在对多个字段进行排序时遇到问题。 案例: 我有一个 PeopleList 作为 TObjectList我希望能够通过一次选择一个排序字段,但尽可能保留以前的排序来制作类似 Ex
有没有办法在 sql 中组合 ORDER BY 和 IS NULL 以便我可以在列不为空时按列排序,但如果它为null,按另一列排序? 最佳答案 类似于: ORDER BY CASE WHEN
我有一个包含 2 列“id”和“name”的表。 id 是常规的自动增量索引,name 只是 varchar。 id name 1 john 2 mary 3 pop 4 mary 5 j
场景 网站页面有一个带有分页、过滤、排序功能的表格 View 。 表中的数据是从REST API服务器获取的,数据包含数百万条记录。 数据库 REST API 服务器 Web 服务器 浏览器 问
假设我有一本字典,其中的键(单词)和值(分数)如下: GOD 8 DONG 16 DOG 8 XI 21 我想创建一个字典键(单词)的 NSArray,首先按分数排序,然后按字
如何在 sphinx 上通过 sql 命令选择前 20 行按标题 WEIGHT 排序,接下来 20 行按标题 ASC 排序(总共 40 个结果),但不要给出重复的标题输出。 我尝试了这个 sql 命令
我有一个奇怪的问题,当从 SQLite 数据库中选择信息并根据日期排序时,返回的结果无效。 我的SQL语句是这样的: Select pk from usersDates order by dateti
我是一名优秀的程序员,十分优秀!