You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为WordPress菜单设置添加自定义语言下拉字段

解决方案

核心问题修正

你之前使用的wp_nav_menu是前端渲染菜单的钩子,无法在后台菜单设置区域输出内容。正确的钩子是wp_nav_menu_options,它专门用于在菜单设置区域(“自动添加页面”“显示位置”下方)插入自定义字段。

同时,将菜单语言值存储为菜单的Post元数据而非独立Option,更符合WordPress数据结构规范,也便于管理。

完整修正代码

// 在菜单设置区域添加语言下拉框
add_action('wp_nav_menu_options', 'add_language_field_to_menu_settings');
function add_language_field_to_menu_settings() {
    // 获取当前选中的菜单ID
    $menu_id = isset($_GET['menu']) ? intval($_GET['menu']) : 0;
    if (!$menu_id) return;

    // 获取已保存的语言值
    $selected_language = get_post_meta($menu_id, '_menu_language', true);
    $available_languages = get_theme_available_languages();

    // 输出Nonce字段用于安全验证
    wp_nonce_field('save_menu_language_nonce', 'menu_language_nonce');

    // 输出字段(匹配WordPress默认表单样式)
    echo '<p class="form-field">';
    echo '<label for="menu_language">' . __('Menu Language', 'text-domain') . '</label>';
    echo '<select name="menu_language" id="menu_language" class="widefat">';
    echo '<option value="" ' . selected($selected_language, '', false) . '>' . __('No Language Selected', 'text-domain') . '</option>';
    foreach ($available_languages as $lang_code => $lang_name) {
        echo '<option value="' . esc_attr($lang_code) . '" ' . selected($selected_language, $lang_code, false) . '>' . esc_html($lang_name) . '</option>';
    }
    echo '</select>';
    echo '<span class="description">' . __('Select the language associated with this menu.', 'text-domain') . '</span>';
    echo '</p>';
}

// 保存菜单语言设置
add_action('wp_update_nav_menu', 'save_menu_language_settings');
function save_menu_language_settings($menu_id) {
    // 验证Nonce和权限
    if (!isset($_POST['menu_language_nonce']) || !wp_verify_nonce($_POST['menu_language_nonce'], 'save_menu_language_nonce')) {
        return;
    }
    if (!current_user_can('edit_nav_menu', $menu_id)) {
        return;
    }

    // 处理并保存语言值
    $menu_language = isset($_POST['menu_language']) ? sanitize_text_field($_POST['menu_language']) : '';
    update_post_meta($menu_id, '_menu_language', $menu_language);
}

// 获取菜单关联的语言值
function get_menu_language($menu_id) {
    return get_post_meta($menu_id, '_menu_language', true);
}

// 获取主题可用语言(优化版)
function get_theme_available_languages() {
    $languages = array();
    $language_dir = get_template_directory() . '/languages';

    if (is_dir($language_dir)) {
        $files = glob($language_dir . '/*.po');
        foreach ($files as $file) {
            $lang_code = basename($file, '.po');
            // 尝试从PO文件中获取语言名称(更可靠的方式)
            $lang_name = $lang_code;
            $handle = fopen($file, 'r');
            if ($handle) {
                while (($line = fgets($handle)) !== false) {
                    if (strpos($line, '"Language:') !== false) {
                        preg_match('/"Language: ([^\\\]+)\\\/', $line, $matches);
                        if (!empty($matches[1])) {
                            $lang_name = trim($matches[1]);
                            break;
                        }
                    }
                }
                fclose($handle);
            }
            $languages[$lang_code] = $lang_name;
        }
    }

    // 确保英文选项存在
    if (!isset($languages['en-US'])) {
        $languages['en-US'] = 'English (United States)';
    }

    return $languages;
}

关键修改说明

  1. 钩子替换:用wp_nav_menu_options替代wp_nav_menu,确保字段显示在后台菜单设置区域的正确位置。
  2. 数据存储优化:使用get_post_meta/update_post_meta将语言值存储为菜单的Post元数据,而非独立Option,符合WordPress数据规范。
  3. 样式匹配:用p.form-field包裹字段,和WordPress默认菜单设置字段的样式保持一致。
  4. 安全增强:添加current_user_can权限验证,确保只有有权限的用户才能修改设置。
  5. 语言名称提取优化:从PO文件的Language:行提取语言名称,比读取第一行更可靠。

使用方法

  1. 将上述代码添加到主题的functions.php文件中,或自定义插件中。
  2. 进入后台外观 > 菜单,选择目标菜单,即可在“菜单设置”区域看到语言下拉框。
  3. 在主题中调用get_menu_language($menu_id)获取菜单关联的语言值,例如:
    // 获取当前菜单ID(示例:主菜单)
    $main_menu_id = get_nav_menu_locations()['primary'];
    $menu_language = get_menu_language($main_menu_id);
    // 根据语言值执行逻辑,比如加载对应语言的样式或内容
    

内容的提问来源于stack exchange,提问作者Dejan Dozet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.22 22:55:14