You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2093 lines
79 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

<?php
/**
* 主题设置和基础功能配置
* 包含主题支持、导航菜单、图像尺寸等基础设置
*/
// 防止直接访问
if (!defined('ABSPATH')) {
exit;
}
/**
* 主题基础设置和功能支持
* 启用WordPress主题的各种功能支持
*/
function nenghui_theme_setup() {
// 启用文章特色图像(缩略图)支持
add_theme_support('post-thumbnails');
// 启用文章和页面的特色图像
add_theme_support('post-thumbnails', array('post', 'page'));
// 设置特色图像的默认尺寸
set_post_thumbnail_size(800, 600, true);
// 添加自定义图像尺寸
add_image_size('nenghui-large', 1200, 800, true);
add_image_size('nenghui-medium', 600, 400, true);
add_image_size('nenghui-small', 300, 200, true);
// 添加产品封面图尺寸
add_image_size('product-cover-large', 1200, 800, true);
add_image_size('product-cover-medium', 600, 400, true);
add_image_size('product-cover-small', 300, 200, true);
// 启用HTML5支持
add_theme_support('html5', array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption'
));
// 启用自动feed链接
add_theme_support('automatic-feed-links');
// 启用标题标签支持
add_theme_support('title-tag');
}
add_action('after_setup_theme', 'nenghui_theme_setup');
/**
* 注册导航菜单
* 注册主题使用的导航菜单位置
*/
function register_theme_menus() {
register_nav_menus(array(
'primary-menu' => '主导航菜单'
));
}
add_action('init', 'register_theme_menus');
/**
* 自定义网站底部版权信息和加载时间
* 使用方法:
* 1. 此函数会自动在后台底部显示
* 2. 在前台footer.php中显示需添加以下代码:
* <?php echo footerText(); ?>
*/
function footerText() {
$year = date('Y');
return '<p style="text-align: center; color: #666; font-size: 14px; margin-right: 10px;">' . $year . ' © Shang hai Nenghui Energy | 版权所有 | 优化后加载耗时:' . timer_stop(0, 3) . '秒</p>';
}
// 在后台底部显示
add_action('admin_footer_text', 'footerText', 9999);
// 在前台底部显示
add_action('wp_footer', 'footerText', 9999);
/**
* 启用图片懒加载机制
* 为图片添加懒加载属性以提升页面性能
*/
add_filter('wp_lazy_loading_enabled', '__return_true');
/**
* 为内容中的图片添加懒加载属性
* @param string $content 文章内容
* @return string 处理后的内容
*/
function add_lazy_loading_to_images($content) {
if (is_feed() || is_preview()) {
return $content;
}
$content = preg_replace('/<img([^>]*)(?<!loading=)>/i', '<img$1 loading="lazy">', $content);
return $content;
}
add_filter('the_content', 'add_lazy_loading_to_images');
add_filter('post_thumbnail_html', 'add_lazy_loading_to_images');
/**
* 禁用评论功能
* 完全禁用WordPress的评论系统以避免comments.php弃用警告
*/
function disable_comments_functionality() {
// 移除评论支持
remove_post_type_support('post', 'comments');
remove_post_type_support('page', 'comments');
// 移除评论相关的菜单项
remove_menu_page('edit-comments.php');
// 移除评论相关的管理栏项目
remove_action('admin_bar_menu', 'wp_admin_bar_comments_menu', 60);
// 禁用评论feed
remove_action('wp_head', 'feed_links_extra', 3);
// 重定向评论页面
if (is_admin() && isset($_GET['page']) && $_GET['page'] === 'edit-comments.php') {
wp_redirect(admin_url());
exit;
}
}
add_action('init', 'disable_comments_functionality');
add_action('admin_init', 'disable_comments_functionality');
/**
* 关闭所有现有文章和页面的评论
*/
function close_existing_comments() {
// 关闭新文章的评论
update_option('default_comment_status', 'closed');
// 关闭新页面的评论
update_option('default_ping_status', 'closed');
}
add_action('admin_init', 'close_existing_comments');
/**
* 移除评论相关的元框
*/
function remove_comment_metaboxes() {
remove_meta_box('commentsdiv', 'post', 'normal');
remove_meta_box('commentstatusdiv', 'post', 'normal');
remove_meta_box('trackbacksdiv', 'post', 'normal');
remove_meta_box('commentsdiv', 'page', 'normal');
remove_meta_box('commentstatusdiv', 'page', 'normal');
remove_meta_box('trackbacksdiv', 'page', 'normal');
}
add_action('admin_menu', 'remove_comment_metaboxes');
/**
* 隐藏评论相关的设置选项
*/
function hide_comment_settings() {
echo '<style>
.form-table tr:has(th[scope="row"] label[for="default_comment_status"]),
.form-table tr:has(th[scope="row"] label[for="default_ping_status"]),
.form-table tr:has(th[scope="row"] label[for="comment_moderation"]),
.form-table tr:has(th[scope="row"] label[for="comments_notify"]),
.form-table tr:has(th[scope="row"] label[for="moderation_notify"]),
.form-table tr:has(th[scope="row"] label[for="comment_max_links"]),
.form-table tr:has(th[scope="row"] label[for="comment_whitelist"]),
.form-table tr:has(th[scope="row"] label[for="comment_registration"]),
.form-table tr:has(th[scope="row"] label[for="close_comments_for_old_posts"]),
.form-table tr:has(th[scope="row"] label[for="close_comments_days_old"]),
.form-table tr:has(th[scope="row"] label[for="thread_comments"]),
.form-table tr:has(th[scope="row"] label[for="thread_comments_depth"]),
.form-table tr:has(th[scope="row"] label[for="page_comments"]),
.form-table tr:has(th[scope="row"] label[for="comments_per_page"]),
.form-table tr:has(th[scope="row"] label[for="default_comments_page"]),
.form-table tr:has(th[scope="row"] label[for="comment_order"]),
.form-table tr:has(th[scope="row"] label[for="require_name_email"]),
.form-table tr:has(th[scope="row"] label[for="show_avatars"]) {
display: none !important;
}
</style>';
}
add_action('admin_head-options-discussion.php', 'hide_comment_settings');
/**
* 移除评论相关的REST API端点
*/
function disable_comments_rest_api($endpoints) {
// 确保 $endpoints 是数组且不为空
if (!is_array($endpoints) || empty($endpoints)) {
return is_array($endpoints) ? $endpoints : array();
}
// 安全地移除评论相关的端点
if (isset($endpoints['/wp/v2/comments'])) {
unset($endpoints['/wp/v2/comments']);
}
if (isset($endpoints['/wp/v2/comments/(?P<id>[\d]+)'])) {
unset($endpoints['/wp/v2/comments/(?P<id>[\d]+)']);
}
return $endpoints;
}
add_filter('rest_endpoints', 'disable_comments_rest_api');
/**
* 移除评论相关的小工具
*/
function remove_comment_widgets() {
unregister_widget('WP_Widget_Recent_Comments');
}
add_action('widgets_init', 'remove_comment_widgets');
/**
* 注册下载中心自定义文章类型
*/
function register_download_center_post_type() {
$labels = array(
'name' => '下载中心',
'singular_name' => '下载项目',
'menu_name' => '下载中心',
'name_admin_bar' => '下载项目',
'archives' => '下载归档',
'attributes' => '下载属性',
'parent_item_colon' => '父级下载项目:',
'all_items' => '所有下载',
'add_new_item' => '添加新下载',
'add_new' => '添加新下载',
'new_item' => '新下载项目',
'edit_item' => '编辑下载',
'update_item' => '更新下载',
'view_item' => '查看下载',
'view_items' => '查看下载',
'search_items' => '搜索下载',
'not_found' => '未找到下载项目',
'not_found_in_trash' => '回收站中未找到下载项目',
'featured_image' => '特色图像',
'set_featured_image' => '设置特色图像',
'remove_featured_image' => '移除特色图像',
'use_featured_image' => '使用特色图像',
'insert_into_item' => '插入到下载项目',
'uploaded_to_this_item' => '上传到此下载项目',
'items_list' => '下载列表',
'items_list_navigation' => '下载列表导航',
'filter_items_list' => '筛选下载列表',
);
$args = array(
'label' => '下载中心',
'description' => '管理下载中心的文件和资源',
'labels' => $labels,
'supports' => array('title', 'editor', 'thumbnail', 'custom-fields'),
'taxonomies' => array('download_category'),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 20,
'menu_icon' => 'dashicons-download',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true,
);
register_post_type('download_center', $args);
}
add_action('init', 'register_download_center_post_type', 0);
/**
* 注册下载分类法
*/
function register_download_category_taxonomy() {
$labels = array(
'name' => '下载分类',
'singular_name' => '下载分类',
'menu_name' => '下载分类',
'all_items' => '所有分类',
'parent_item' => '父级分类',
'parent_item_colon' => '父级分类:',
'new_item_name' => '新分类名称',
'add_new_item' => '添加新分类',
'edit_item' => '编辑分类',
'update_item' => '更新分类',
'view_item' => '查看分类',
'separate_items_with_commas' => '用逗号分隔分类',
'add_or_remove_items' => '添加或移除分类',
'choose_from_most_used' => '从常用分类中选择',
'popular_items' => '热门分类',
'search_items' => '搜索分类',
'not_found' => '未找到分类',
'no_terms' => '无分类',
'items_list' => '分类列表',
'items_list_navigation' => '分类列表导航',
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'show_in_rest' => true,
);
register_taxonomy('download_category', array('download_center'), $args);
}
add_action('init', 'register_download_category_taxonomy', 0);
/**
* 创建默认下载分类
*/
function create_default_download_categories() {
// 检查是否已经创建过默认分类
if (get_option('nenghui_download_categories_created')) {
return;
}
// 创建 Company profile 分类
if (!term_exists('Company profile', 'download_category')) {
wp_insert_term(
'Company profile',
'download_category',
array(
'description' => '公司简介相关下载文件',
'slug' => 'company-profile',
)
);
}
// 创建 Product series 分类
if (!term_exists('Product series', 'download_category')) {
wp_insert_term(
'Product series',
'download_category',
array(
'description' => '产品系列相关下载文件',
'slug' => 'product-series',
)
);
}
// 标记已创建默认分类
update_option('nenghui_download_categories_created', true);
}
add_action('init', 'create_default_download_categories');
/**
* 为下载中心添加自定义字段
*/
function add_download_center_meta_boxes() {
add_meta_box(
'download_file_info',
'下载文件信息',
'download_file_info_callback',
'download_center',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_download_center_meta_boxes');
/**
* 为下载中心编辑页面加载媒体库脚本
*/
function enqueue_download_center_admin_scripts($hook) {
global $post;
// 在下载中心和产品的编辑页面加载
if ($hook == 'post-new.php' || $hook == 'post.php') {
if ('download_center' === $post->post_type || 'products' === $post->post_type) {
// 加载媒体库脚本
wp_enqueue_media();
}
}
}
add_action('admin_enqueue_scripts', 'enqueue_download_center_admin_scripts');
/**
* 下载文件信息元框回调函数
*/
function download_file_info_callback($post) {
// 添加nonce字段用于安全验证
wp_nonce_field('download_file_info_nonce', 'download_file_info_nonce');
// 获取现有值
$download_url = get_post_meta($post->ID, '_download_url', true);
$file_size = get_post_meta($post->ID, '_file_size', true);
$file_type = get_post_meta($post->ID, '_file_type', true);
echo '<table class="form-table">';
echo '<tr>';
echo '<th><label for="download_url">下载链接</label></th>';
echo '<td>';
echo '<input type="url" id="download_url" name="download_url" value="' . esc_attr($download_url) . '" class="regular-text" placeholder="https://example.com/file.pdf" style="margin-right: 10px;" />';
echo '<button type="button" class="button" id="select_file_button">选择文件</button>';
echo '<br><small class="description">可以直接输入链接,或点击"选择文件"从媒体库选择</small>';
echo '</td>';
echo '</tr>';
echo '<tr>';
echo '<th><label for="file_size">文件大小</label></th>';
echo '<td><input type="text" id="file_size" name="file_size" value="' . esc_attr($file_size) . '" class="regular-text" placeholder="例如: 2.5MB" /></td>';
echo '</tr>';
echo '<tr>';
echo '<th><label for="file_type">文件类型</label></th>';
echo '<td><input type="text" id="file_type" name="file_type" value="' . esc_attr($file_type) . '" class="regular-text" placeholder="例如: PDF" /></td>';
echo '</tr>';
echo '</table>';
echo '<p class="description">请填写下载文件的相关信息。如果不填写下载链接,将使用特色图像作为下载文件。</p>';
// 添加JavaScript代码用于媒体库选择
echo '<script>
jQuery(document).ready(function($) {
var mediaUploader;
$("#select_file_button").click(function(e) {
e.preventDefault();
// 如果媒体上传器已存在,重新打开
if (mediaUploader) {
mediaUploader.open();
return;
}
// 创建新的媒体上传器
mediaUploader = wp.media({
title: "选择下载文件",
button: {
text: "选择此文件"
},
multiple: false
});
// 当文件被选择时
mediaUploader.on("select", function() {
var attachment = mediaUploader.state().get("selection").first().toJSON();
// 设置下载链接
$("#download_url").val(attachment.url);
// 自动填充文件大小(如果有的话)
if (attachment.filesizeHumanReadable) {
$("#file_size").val(attachment.filesizeHumanReadable);
}
// 自动填充文件类型
if (attachment.subtype) {
$("#file_type").val(attachment.subtype.toUpperCase());
} else if (attachment.mime) {
var mimeType = attachment.mime.split("/")[1];
$("#file_type").val(mimeType.toUpperCase());
}
});
// 打开媒体上传器
mediaUploader.open();
});
});
</script>';
}
/**
* 保存下载文件信息
*/
function save_download_file_info($post_id) {
// 验证nonce
if (!isset($_POST['download_file_info_nonce']) || !wp_verify_nonce($_POST['download_file_info_nonce'], 'download_file_info_nonce')) {
return;
}
// 检查用户权限
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 检查是否为自动保存
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
// 保存字段
if (isset($_POST['download_url'])) {
update_post_meta($post_id, '_download_url', sanitize_url($_POST['download_url']));
}
if (isset($_POST['file_size'])) {
update_post_meta($post_id, '_file_size', sanitize_text_field($_POST['file_size']));
}
if (isset($_POST['file_type'])) {
update_post_meta($post_id, '_file_type', sanitize_text_field($_POST['file_type']));
}
}
add_action('save_post', 'save_download_file_info');
/**
* 注册案例展示自定义文章类型
*/
function register_cases_post_type() {
$labels = array(
'name' => '案例展示',
'singular_name' => '案例',
'menu_name' => '案例展示',
'name_admin_bar' => '案例',
'archives' => '案例归档',
'attributes' => '案例属性',
'parent_item_colon' => '父级案例:',
'all_items' => '所有案例',
'add_new_item' => '添加新案例',
'add_new' => '添加新案例',
'new_item' => '新案例',
'edit_item' => '编辑案例',
'update_item' => '更新案例',
'view_item' => '查看案例',
'view_items' => '查看案例',
'search_items' => '搜索案例',
'not_found' => '未找到案例',
'not_found_in_trash' => '回收站中未找到案例',
'featured_image' => '案例特色图像',
'set_featured_image' => '设置案例特色图像',
'remove_featured_image' => '移除案例特色图像',
'use_featured_image' => '使用案例特色图像',
'insert_into_item' => '插入到案例',
'uploaded_to_this_item' => '上传到此案例',
'items_list' => '案例列表',
'items_list_navigation' => '案例列表导航',
'filter_items_list' => '筛选案例列表',
);
$args = array(
'label' => '案例展示',
'description' => '案例展示文章类型',
'labels' => $labels,
'supports' => array('title', 'editor', 'thumbnail', 'excerpt'),
'taxonomies' => array('case_category'),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 6,
'menu_icon' => 'dashicons-portfolio',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true,
'rewrite' => array('slug' => 'cases'),
);
register_post_type('cases', $args);
}
add_action('init', 'register_cases_post_type', 0);
/**
* 注册案例分类法
*/
function register_case_category_taxonomy() {
$labels = array(
'name' => '案例分类',
'singular_name' => '案例分类',
'menu_name' => '案例分类',
'all_items' => '所有分类',
'parent_item' => '父级分类',
'parent_item_colon' => '父级分类:',
'new_item_name' => '新分类名称',
'add_new_item' => '添加新分类',
'edit_item' => '编辑分类',
'update_item' => '更新分类',
'view_item' => '查看分类',
'separate_items_with_commas' => '用逗号分隔分类',
'add_or_remove_items' => '添加或移除分类',
'choose_from_most_used' => '从最常用的分类中选择',
'popular_items' => '热门分类',
'search_items' => '搜索分类',
'not_found' => '未找到分类',
'no_terms' => '没有分类',
'items_list' => '分类列表',
'items_list_navigation' => '分类列表导航',
);
$args = array(
'labels' => $labels,
'hierarchical' => true,
'public' => true,
'show_ui' => true,
'show_admin_column' => true,
'show_in_nav_menus' => true,
'show_tagcloud' => true,
'show_in_rest' => true,
'rewrite' => array('slug' => 'case-category'),
);
register_taxonomy('case_category', array('cases'), $args);
}
add_action('init', 'register_case_category_taxonomy', 0);
/**
* 创建默认案例分类
*/
function create_default_case_categories() {
// 检查是否已经创建过默认分类
if (get_option('nenghui_case_categories_created')) {
return;
}
// 创建 Power Station 分类
if (!term_exists('Power Station', 'case_category')) {
wp_insert_term(
'Power Station',
'case_category',
array(
'description' => '电站项目案例',
'slug' => 'power-station',
)
);
}
// 创建 PV Project 分类
if (!term_exists('PV Project', 'case_category')) {
wp_insert_term(
'PV Project',
'case_category',
array(
'description' => '光伏项目案例',
'slug' => 'pv-project',
)
);
}
// 创建 Agricultural Solar 分类
if (!term_exists('Agricultural Solar', 'case_category')) {
wp_insert_term(
'Agricultural Solar',
'case_category',
array(
'description' => '农业太阳能项目案例',
'slug' => 'agricultural-solar',
)
);
}
// 标记已创建默认分类
update_option('nenghui_case_categories_created', true);
}
add_action('init', 'create_default_case_categories');
/**
* 注册产品自定义文章类型
*/
function register_products_post_type() {
$labels = array(
'name' => '产品管理',
'singular_name' => '产品',
'menu_name' => '产品管理',
'name_admin_bar' => '产品',
'archives' => '产品归档',
'attributes' => '产品属性',
'parent_item_colon' => '父级产品:',
'all_items' => '所有产品',
'add_new_item' => '添加新产品',
'add_new' => '添加新产品',
'new_item' => '新产品',
'edit_item' => '编辑产品',
'update_item' => '更新产品',
'view_item' => '查看产品',
'view_items' => '查看产品',
'search_items' => '搜索产品',
'not_found' => '未找到产品',
'not_found_in_trash' => '回收站中未找到产品',
'featured_image' => '产品特色图像',
'set_featured_image' => '设置产品特色图像',
'remove_featured_image' => '移除产品特色图像',
'use_featured_image' => '使用产品特色图像',
'insert_into_item' => '插入到产品',
'uploaded_to_this_item' => '上传到此产品',
'items_list' => '产品列表',
'items_list_navigation' => '产品列表导航',
'filter_items_list' => '筛选产品列表',
);
$args = array(
'label' => '产品管理',
'description' => '产品展示和管理',
'labels' => $labels,
'supports' => array('title', 'thumbnail', 'custom-fields'),
'hierarchical' => false,
'public' => true,
'show_ui' => true,
'show_in_menu' => true,
'menu_position' => 5,
'menu_icon' => 'dashicons-products',
'show_in_admin_bar' => true,
'show_in_nav_menus' => true,
'can_export' => true,
'has_archive' => true,
'exclude_from_search' => false,
'publicly_queryable' => true,
'capability_type' => 'post',
'show_in_rest' => true,
'rewrite' => array('slug' => 'products'),
);
register_post_type('products', $args);
}
add_action('init', 'register_products_post_type', 0);
/**
* 添加产品Banner图片meta box
*/
function add_products_banner_meta_box() {
add_meta_box(
'product_banner_meta_box',
'产品Banner图片',
'product_banner_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_banner_meta_box');
/**
* 添加产品封面图meta box
*/
function add_product_cover_meta_box() {
add_meta_box(
'product_cover_meta_box',
'产品封面图',
'product_cover_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_product_cover_meta_box');
/**
* 添加产品特性meta box
*/
function add_products_features_meta_box() {
add_meta_box(
'product_features_meta_box',
'产品特性设置',
'product_features_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_features_meta_box');
/**
* 添加使用场景meta box
*/
function add_products_usage_scenario_meta_box() {
add_meta_box(
'product_usage_scenario_meta_box',
'使用场景设置',
'product_usage_scenario_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_usage_scenario_meta_box');
/**
* 添加技术规格meta box
*/
function add_products_technical_specs_meta_box() {
add_meta_box(
'product_technical_specs_meta_box',
'技术规格设置',
'product_technical_specs_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_technical_specs_meta_box');
/**
* 添加产品PDF下载meta box
*/
function add_products_pdf_downloads_meta_box() {
add_meta_box(
'product_pdf_downloads_meta_box',
'PDF下载设置',
'product_pdf_downloads_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_pdf_downloads_meta_box');
/**
* 添加产品描述meta box
*/
function add_products_description_meta_box() {
add_meta_box(
'product_description_meta_box',
'产品描述',
'product_description_meta_box_callback',
'products',
'normal',
'high'
);
}
add_action('add_meta_boxes', 'add_products_description_meta_box');
/**
* 产品Banner图片meta box回调函数
*/
function product_banner_meta_box_callback($post) {
wp_nonce_field('save_product_banner', 'product_banner_nonce');
$banner_url = get_post_meta($post->ID, '_product_banner_url', true);
?>
<table class="form-table">
<tr>
<th><label for="product_banner_url">Banner图片URL</label></th>
<td>
<input type="text" id="product_banner_url" name="product_banner_url" value="<?php echo esc_attr($banner_url); ?>" style="width: 70%;" />
<input type="button" id="upload_banner_button" class="button" value="上传图片" />
<br><small>建议尺寸1920x600像素</small>
<?php if ($banner_url): ?>
<div style="margin-top: 10px;">
<img src="<?php echo esc_url($banner_url); ?>" style="max-width: 300px; height: auto;" />
</div>
<?php endif; ?>
</td>
</tr>
</table>
<script>
jQuery(document).ready(function($) {
$('#upload_banner_button').click(function(e) {
e.preventDefault();
var custom_uploader = wp.media({
title: '选择Banner图片',
button: {
text: '使用此图片'
},
multiple: false
});
custom_uploader.on('select', function() {
var attachment = custom_uploader.state().get('selection').first().toJSON();
$('#product_banner_url').val(attachment.url);
});
custom_uploader.open();
});
});
</script>
<?php
}
/**
* 保存产品Banner图片
*/
function save_product_banner($post_id) {
if (!isset($_POST['product_banner_nonce']) || !wp_verify_nonce($_POST['product_banner_nonce'], 'save_product_banner')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['product_banner_url'])) {
update_post_meta($post_id, '_product_banner_url', sanitize_text_field($_POST['product_banner_url']));
}
}
add_action('save_post', 'save_product_banner');
/**
* 产品封面图meta box回调函数
*/
function product_cover_meta_box_callback($post) {
wp_nonce_field('save_product_cover', 'product_cover_nonce');
$cover_id = get_post_thumbnail_id($post->ID);
$cover_url = $cover_id ? wp_get_attachment_image_url($cover_id, 'medium') : '';
?>
<table class="form-table">
<tr>
<th><label for="product_cover_id">产品封面图</label></th>
<td>
<input type="text" id="product_cover_id" name="product_cover_id" value="<?php echo esc_attr($cover_id); ?>" />
<input type="button" id="upload_cover_button" class="button" value="上传封面图" />
<br><small>建议尺寸1200x800像素</small>
<?php if ($cover_url): ?>
<div style="margin-top: 10px;">
<img src="<?php echo esc_url($cover_url); ?>" style="max-width: 300px; height: auto;" />
</div>
<?php endif; ?>
</td>
</tr>
</table>
<script>
jQuery(document).ready(function($) {
$('#upload_cover_button').click(function(e) {
e.preventDefault();
var coverUploader = wp.media({
title: '选择产品封面图',
button: {
text: '使用此图片'
},
multiple: false
});
coverUploader.on('select', function() {
var attachment = coverUploader.state().get('selection').first().toJSON();
$('#product_cover_id').val(attachment.id);
var previewHtml = '<div style="margin-top: 10px;"><img src="' + attachment.url + '" style="max-width: 300px; height: auto;" /></div>';
var existingPreview = $('#product_cover_id').parent().find('div');
if (existingPreview.length > 0) {
existingPreview.replaceWith(previewHtml);
} else {
$('#product_cover_id').parent().append(previewHtml);
}
});
coverUploader.open();
});
});
</script>
<?php
}
/**
* 保存产品封面图
*/
function save_product_cover($post_id) {
if (!isset($_POST['product_cover_nonce']) || !wp_verify_nonce($_POST['product_cover_nonce'], 'save_product_cover')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['product_cover_id']) && !empty($_POST['product_cover_id'])) {
$cover_id = intval($_POST['product_cover_id']);
set_post_thumbnail($post_id, $cover_id);
}
}
add_action('save_post', 'save_product_cover');
/**
* 产品描述meta box回调函数
*/
function product_description_meta_box_callback($post) {
wp_nonce_field('save_product_description', 'product_description_nonce');
$product_description = get_post_meta($post->ID, '_product_description', true);
?>
<div style="margin: 15px 0;">
<label for="product_description" style="font-weight: 600; margin-bottom: 10px; display: block;">产品描述</label>
<?php
// 富文本编辑器设置
$editor_settings = array(
'textarea_name' => 'product_description',
'textarea_rows' => 8,
'media_buttons' => true,
'teeny' => false,
'dfw' => false,
'tinymce' => array(
'resize' => false,
'wp_autoresize_on' => true,
'add_unload_trigger' => false,
'toolbar1' => 'bold,italic,underline,strikethrough,|,bullist,numlist,blockquote,|,link,unlink,|,spellchecker,fullscreen,wp_adv',
'toolbar2' => 'formatselect,forecolor,backcolor,|,pastetext,removeformat,charmap,|,outdent,indent,|,undo,redo'
),
'quicktags' => array(
'buttons' => 'strong,em,ul,ol,li,link,close'
)
);
// 输出富文本编辑器
wp_editor($product_description, 'product_description', $editor_settings);
?>
<p class="description" style="margin-top: 10px;">此描述将显示在产品页面的标题下方,用于简要介绍产品特点和用途。支持富文本格式。</p>
</div>
<?php
}
/**
* 保存产品描述
*/
function save_product_description($post_id) {
if (!isset($_POST['product_description_nonce']) || !wp_verify_nonce($_POST['product_description_nonce'], 'save_product_description')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['product_description'])) {
// 使用wp_kses_post来保留安全的HTML标签
update_post_meta($post_id, '_product_description', wp_kses_post($_POST['product_description']));
}
}
add_action('save_post', 'save_product_description');
/**
* 产品特性meta box回调函数
*/
function product_features_meta_box_callback($post) {
wp_nonce_field('save_product_features', 'product_features_nonce');
// 获取产品特性显示开关和特性数据
$show_features = get_post_meta($post->ID, '_show_product_features', true);
if ($show_features === '') {
$show_features = '1'; // 默认显示
}
$features = get_post_meta($post->ID, '_product_features', true);
if (!is_array($features)) {
$features = array();
}
// 默认特性数据(与前端硬编码内容保持一致)
$default_features = array(
array(
'title' => 'COMPACT<br>DESIGN',
'description' => 'Light footprint, easy frame<br>installation and field installation.',
'icon' => 'product-icon-1.webp',
'alt' => 'Compact Design'
),
array(
'title' => 'HIGH<br>INTEGRATION',
'description' => '20kWh+ energy in one cabinet<br>with DC/AC power conversion<br>& thermal cooling.',
'icon' => 'product-icon-2.webp',
'alt' => 'High Integration'
),
array(
'title' => 'EFFICIENT<br>COOLING',
'description' => 'Optimal air-duct design optimizes<br>airflow for improved cooling with low<br>energy consumption.',
'icon' => 'product-icon-3.webp',
'alt' => 'Efficient Cooling'
),
array(
'title' => 'LONG<br>CYCLE LIFE',
'description' => 'Over 6,000 times cycle life, excellent<br>performance of battery system.',
'icon' => 'product-icon-4.webp',
'alt' => 'Long Cycle Life'
),
array(
'title' => 'FLEXIBLE<br>EXPANSION',
'description' => 'Modular design, simplified panel<br>for expansion.',
'icon' => 'product-icon-5.webp',
'alt' => 'Flexible Expansion'
),
array(
'title' => 'ULTIMATE<br>SAFETY',
'description' => 'Comprehensive safety protection<br>with NOVEC1230 thermal prevent<br>heat diffusion and spreading.',
'icon' => 'product-icon-6.webp',
'alt' => 'Ultimate Safety'
)
);
// 如果没有保存的数据,使用默认数据
if (empty($features)) {
$features = $default_features;
}
?>
<div id="product-features-container">
<p><strong>产品特性板块设置:</strong></p>
<div style="margin-bottom: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px;">
<label for="show_product_features">
<input type="checkbox" id="show_product_features" name="show_product_features" value="1" <?php checked($show_features, '1'); ?> />
<strong>显示产品特性板块</strong>
</label>
<p><small>勾选此选项将在前端显示产品特性卡片,取消勾选将隐藏整个板块。</small></p>
</div>
<div id="features-management">
<div style="margin-bottom: 20px; display: flex; justify-content: space-between; align-items: center;">
<h3 style="margin: 0;">产品特性卡片管理</h3>
<button type="button" id="add-feature-btn" class="button button-primary">添加新特性</button>
</div>
<div id="features-list">
<?php foreach ($features as $index => $feature): ?>
<div class="feature-item" data-index="<?php echo $index; ?>">
<div class="feature-header">
<h4>特性 <?php echo ($index + 1); ?></h4>
<div class="feature-actions">
<button type="button" class="button move-up" title="上移">↑</button>
<button type="button" class="button move-down" title="下移">↓</button>
<button type="button" class="button button-secondary remove-feature" title="删除">删除</button>
</div>
</div>
<table class="form-table">
<tr>
<th><label>标题</label></th>
<td>
<input type="text" name="product_features[<?php echo $index; ?>][title]"
value="<?php echo esc_attr($feature['title']); ?>" style="width: 100%;" />
<small>可以使用 &lt;br&gt; 标签换行</small>
</td>
</tr>
<tr>
<th><label>描述</label></th>
<td>
<textarea name="product_features[<?php echo $index; ?>][description]"
rows="3" style="width: 100%;"><?php echo esc_textarea($feature['description']); ?></textarea>
<small>可以使用 &lt;br&gt; 标签换行</small>
</td>
</tr>
<tr>
<th><label>图标</label></th>
<td>
<div style="display: flex; gap: 10px; align-items: center;">
<input type="text" name="product_features[<?php echo $index; ?>][icon]"
value="<?php echo esc_attr($feature['icon']); ?>" style="width: 70%;" class="feature-icon-input" />
<button type="button" class="button upload-icon-btn">上传图标</button>
</div>
<small>图标文件名或完整URL</small>
<?php if (!empty($feature['icon'])): ?>
<div class="icon-preview" style="margin-top: 10px;">
<?php
$icon_src = $feature['icon'];
if (filter_var($icon_src, FILTER_VALIDATE_URL)) {
$icon_url = $icon_src;
} else {
$icon_url = get_template_directory_uri() . '/assets/images/' . $icon_src;
}
?>
<img src="<?php echo esc_url($icon_url); ?>" style="max-width: 60px; height: auto;" />
</div>
<?php endif; ?>
</td>
</tr>
<tr>
<th><label>Alt属性</label></th>
<td>
<input type="text" name="product_features[<?php echo $index; ?>][alt]"
value="<?php echo esc_attr(isset($feature['alt']) ? $feature['alt'] : ''); ?>" style="width: 100%;" />
<small>图片的Alt属性用于无障碍访问和SEO</small>
</td>
</tr>
</table>
</div>
<?php endforeach; ?>
</div>
</div>
<p><small><strong>注意:</strong>修改后需要点击"更新"按钮保存设置。</small></p>
</div>
<style>
#features-management {
border: 1px solid #ddd;
border-radius: 4px;
padding: 20px;
background: #fff;
}
.feature-item {
border: 1px solid #ddd;
border-radius: 4px;
margin-bottom: 20px;
background: #f9f9f9;
padding: 15px;
}
.feature-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #ddd;
}
.feature-header h4 {
margin: 0;
color: #23282d;
font-size: 16px;
}
.feature-actions {
display: flex;
gap: 5px;
}
.feature-actions .button {
padding: 4px 8px;
font-size: 12px;
line-height: 1;
}
.feature-item .form-table th {
width: 120px;
padding: 8px 0;
vertical-align: top;
}
.feature-item .form-table td {
padding: 8px 0;
}
.icon-preview {
display: inline-block;
padding: 5px;
border: 1px solid #ddd;
border-radius: 4px;
background: #fff;
}
#add-feature-btn {
font-size: 14px;
padding: 8px 16px;
}
.sortable-placeholder {
border: 2px dashed #0073aa;
background: #f0f8ff;
margin-bottom: 20px;
height: 100px;
border-radius: 4px;
}
</style>
<script>
jQuery(document).ready(function($) {
var featureIndex = <?php echo count($features); ?>;
// 添加新特性
$('#add-feature-btn').on('click', function() {
var newFeatureHtml = `
<div class="feature-item" data-index="${featureIndex}">
<div class="feature-header">
<h4>特性 ${featureIndex + 1}</h4>
<div class="feature-actions">
<button type="button" class="button move-up" title="上移">↑</button>
<button type="button" class="button move-down" title="下移">↓</button>
<button type="button" class="button button-secondary remove-feature" title="删除">删除</button>
</div>
</div>
<table class="form-table">
<tr>
<th><label>标题</label></th>
<td>
<input type="text" name="product_features[${featureIndex}][title]"
value="" style="width: 100%;" />
<small>可以使用 &lt;br&gt; 标签换行</small>
</td>
</tr>
<tr>
<th><label>描述</label></th>
<td>
<textarea name="product_features[${featureIndex}][description]"
rows="3" style="width: 100%;"></textarea>
<small>可以使用 &lt;br&gt; 标签换行</small>
</td>
</tr>
<tr>
<th><label>图标</label></th>
<td>
<div style="display: flex; gap: 10px; align-items: center;">
<input type="text" name="product_features[${featureIndex}][icon]"
value="" style="width: 70%;" class="feature-icon-input" />
<button type="button" class="button upload-icon-btn">上传图标</button>
</div>
<small>图标文件名或完整URL</small>
<div class="icon-preview" style="margin-top: 10px; display: none;">
<img src="" style="max-width: 60px; height: auto;" />
</div>
</td>
</tr>
<tr>
<th><label>Alt属性</label></th>
<td>
<input type="text" name="product_features[${featureIndex}][alt]"
value="" style="width: 100%;" />
<small>图片的Alt属性用于无障碍访问和SEO</small>
</td>
</tr>
</table>
</div>
`;
$('#features-list').append(newFeatureHtml);
featureIndex++;
updateFeatureNumbers();
});
// 删除特性
$(document).on('click', '.remove-feature', function() {
if (confirm('确定要删除这个特性吗?')) {
$(this).closest('.feature-item').remove();
updateFeatureNumbers();
}
});
// 上移特性
$(document).on('click', '.move-up', function() {
var $item = $(this).closest('.feature-item');
var $prev = $item.prev('.feature-item');
if ($prev.length) {
$item.insertBefore($prev);
updateFeatureNumbers();
}
});
// 下移特性
$(document).on('click', '.move-down', function() {
var $item = $(this).closest('.feature-item');
var $next = $item.next('.feature-item');
if ($next.length) {
$item.insertAfter($next);
updateFeatureNumbers();
}
});
// 上传图标
$(document).on('click', '.upload-icon-btn', function() {
var $button = $(this);
var $input = $button.siblings('.feature-icon-input');
var $preview = $button.closest('td').find('.icon-preview');
var mediaUploader = wp.media({
title: '选择产品特性图标',
button: {
text: '使用此图标'
},
multiple: false,
library: {
type: 'image'
}
});
mediaUploader.on('select', function() {
var attachment = mediaUploader.state().get('selection').first().toJSON();
$input.val(attachment.url);
// 更新预览
$preview.find('img').attr('src', attachment.url);
$preview.show();
});
mediaUploader.open();
});
// 更新特性编号和name属性
function updateFeatureNumbers() {
$('#features-list .feature-item').each(function(index) {
$(this).attr('data-index', index);
$(this).find('.feature-header h4').text('特性 ' + (index + 1));
// 更新所有input和textarea的name属性
$(this).find('input, textarea').each(function() {
var name = $(this).attr('name');
if (name) {
var newName = name.replace(/\[\d+\]/, '[' + index + ']');
$(this).attr('name', newName);
}
});
});
}
// 图标输入框变化时更新预览
$(document).on('input', '.feature-icon-input', function() {
var $input = $(this);
var $preview = $input.closest('td').find('.icon-preview');
var iconValue = $input.val();
if (iconValue) {
var iconUrl;
if (iconValue.indexOf('http') === 0) {
iconUrl = iconValue;
} else {
iconUrl = '<?php echo get_template_directory_uri(); ?>/assets/images/' + iconValue;
}
$preview.find('img').attr('src', iconUrl);
$preview.show();
} else {
$preview.hide();
}
});
});
</script>
<?php
}
/**
* 保存产品特性数据
*/
function save_product_features($post_id) {
if (!isset($_POST['product_features_nonce']) || !wp_verify_nonce($_POST['product_features_nonce'], 'save_product_features')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
if (isset($_POST['show_product_features'])) {
update_post_meta($post_id, '_show_product_features', '1');
} else {
update_post_meta($post_id, '_show_product_features', '0');
}
if (isset($_POST['product_features']) && is_array($_POST['product_features'])) {
$features = array();
foreach ($_POST['product_features'] as $feature) {
$features[] = array(
'title' => sanitize_text_field($feature['title']),
'description' => sanitize_textarea_field($feature['description']),
'icon' => sanitize_text_field($feature['icon']),
'alt' => sanitize_text_field($feature['alt'])
);
}
update_post_meta($post_id, '_product_features', $features);
}
}
add_action('save_post', 'save_product_features');
/**
* 使用场景meta box回调函数
*/
function product_usage_scenario_meta_box_callback($post) {
wp_nonce_field('save_product_usage_scenario', 'product_usage_scenario_nonce');
// 获取使用场景显示开关和数据
$show_usage_scenario = get_post_meta($post->ID, '_show_usage_scenario', true);
if ($show_usage_scenario === '') {
$show_usage_scenario = '1'; // 默认显示
}
$usage_scenario_data = get_post_meta($post->ID, '_usage_scenario_data', true);
if (!is_array($usage_scenario_data)) {
$usage_scenario_data = array();
}
// 默认使用场景数据
$default_data = array(
'title' => 'USAGE SCENARIO',
'description' => 'Off-grid PV, energy storage, diesel generation, and charging post',
'image' => 'Usage scenario.webp',
'bottom_text' => 'Nenghui all-in-one liquid-cooled ESS cabinet adopts advanced cabinet-level liquid cooling and temperature balancing strategy. The cell temperature difference is less than 3°C, which further improves the consistency of cell temperature and extends the battery life. The modular design makes the parallel solution more flexible and has a higher energy density, which significantly improves the economy, safety and construction convenience of ESS projects.'
);
// 如果没有保存的数据,使用默认数据
if (empty($usage_scenario_data)) {
$usage_scenario_data = $default_data;
}
?>
<div id="usage-scenario-container">
<p><strong>使用场景板块设置:</strong></p>
<div style="margin-bottom: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px;">
<label for="show_usage_scenario">
<input type="checkbox" id="show_usage_scenario" name="show_usage_scenario" value="1" <?php checked($show_usage_scenario, '1'); ?> />
<strong>显示使用场景板块</strong>
</label>
<p><small>勾选此选项将在前端显示使用场景板块,取消勾选将隐藏整个板块。</small></p>
</div>
<table class="form-table">
<tr>
<th><label for="usage_scenario_title">标题</label></th>
<td>
<input type="text" id="usage_scenario_title" name="usage_scenario_data[title]"
value="<?php echo esc_attr($usage_scenario_data['title']); ?>" style="width: 100%;" />
<small>使用场景板块的主标题</small>
</td>
</tr>
<tr>
<th><label for="usage_scenario_description">描述</label></th>
<td>
<textarea id="usage_scenario_description" name="usage_scenario_data[description]"
rows="3" style="width: 100%;"><?php echo esc_textarea($usage_scenario_data['description']); ?></textarea>
<small>使用场景的简短描述</small>
</td>
</tr>
<tr>
<th><label for="usage_scenario_image">图片文件名</label></th>
<td>
<input type="text" id="usage_scenario_image" name="usage_scenario_data[image]"
value="<?php echo esc_attr($usage_scenario_data['image']); ?>" style="width: 70%;" />
<input type="button" id="upload_scenario_image_button" class="button" value="上传图片" />
<br><small>图片URL或文件名Usage scenario.webp如果是文件名文件应放在 /assets/images/ 目录下</small>
<?php if (!empty($usage_scenario_data['image'])): ?>
<div style="margin-top: 10px;">
<?php
$preview_image_src = $usage_scenario_data['image'];
// 如果是完整URL直接使用否则拼接主题目录路径
if (filter_var($preview_image_src, FILTER_VALIDATE_URL)) {
$preview_image_url = $preview_image_src;
} else {
$preview_image_url = get_template_directory_uri() . '/assets/images/' . $preview_image_src;
}
?>
<img src="<?php echo esc_url($preview_image_url); ?>" style="max-width: 300px; height: auto;" />
</div>
<?php endif; ?>
</td>
</tr>
<tr>
<th><label for="usage_scenario_bottom_text">底部文字</label></th>
<td>
<textarea id="usage_scenario_bottom_text" name="usage_scenario_data[bottom_text]"
rows="5" style="width: 100%;"><?php echo esc_textarea($usage_scenario_data['bottom_text']); ?></textarea>
<small>使用场景图片下方的详细说明文字</small>
</td>
</tr>
</table>
<p><small><strong>注意:</strong>修改后需要点击"更新"按钮保存设置。图片文件需要手动上传到主题的 assets/images 目录。</small></p>
</div>
<style>
#usage-scenario-container .form-table th {
width: 120px;
padding: 8px 0;
}
#usage-scenario-container .form-table td {
padding: 8px 0;
}
</style>
<script>
jQuery(document).ready(function($) {
$('#upload_scenario_image_button').click(function(e) {
e.preventDefault();
var mediaUploader = wp.media({
title: '选择使用场景图片',
button: {
text: '使用此图片'
},
multiple: false
});
mediaUploader.on('select', function() {
var attachment = mediaUploader.state().get('selection').first().toJSON();
// 直接使用完整的URL而不是文件名
$('#usage_scenario_image').val(attachment.url);
});
mediaUploader.open();
});
});
</script>
<?php
}
/**
* 保存使用场景meta box数据
*/
function save_product_usage_scenario($post_id) {
if (!isset($_POST['product_usage_scenario_nonce']) || !wp_verify_nonce($_POST['product_usage_scenario_nonce'], 'save_product_usage_scenario')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存显示开关
if (isset($_POST['show_usage_scenario'])) {
update_post_meta($post_id, '_show_usage_scenario', '1');
} else {
update_post_meta($post_id, '_show_usage_scenario', '0');
}
// 保存使用场景数据
if (isset($_POST['usage_scenario_data']) && is_array($_POST['usage_scenario_data'])) {
$usage_scenario_data = array();
$usage_scenario_data['title'] = sanitize_text_field($_POST['usage_scenario_data']['title']);
$usage_scenario_data['description'] = sanitize_textarea_field($_POST['usage_scenario_data']['description']);
$usage_scenario_data['image'] = sanitize_text_field($_POST['usage_scenario_data']['image']);
$usage_scenario_data['bottom_text'] = sanitize_textarea_field($_POST['usage_scenario_data']['bottom_text']);
update_post_meta($post_id, '_usage_scenario_data', $usage_scenario_data);
}
}
add_action('save_post', 'save_product_usage_scenario');
/**
* 技术规格meta box回调函数
*/
function product_technical_specs_meta_box_callback($post) {
wp_nonce_field('save_product_technical_specs', 'product_technical_specs_nonce');
// 获取技术规格显示开关和数据
$show_technical_specs = get_post_meta($post->ID, '_show_technical_specs', true);
if ($show_technical_specs === '') {
$show_technical_specs = '1'; // 默认显示
}
$technical_specs_data = get_post_meta($post->ID, '_technical_specs_data', true);
if (!is_array($technical_specs_data)) {
$technical_specs_data = array();
}
// 默认技术规格数据
$default_specs = array(
array(
'title' => 'DC Side',
'content' => '<table><tr><td>Cell Type</td><td>LFP280Ah</td></tr><tr><td>PACK</td><td>46.592kWh/IP25S</td></tr><tr><td>Battery System</td><td>232.96kWh/IP260S</td></tr><tr><td>Rated Voltage</td><td>832Vdc</td></tr><tr><td>Voltage Range</td><td>728-936Vdc</td></tr><tr><td>Pack Ingress Rating</td><td>IP65</td></tr></table>',
'expanded' => true
),
array(
'title' => 'AC Side',
'content' => '<table style="width: 100%; border-collapse: collapse;"><tr><td style="border: 1px solid #ddd; padding: 8px;">Rated Power</td><td style="border: 1px solid #ddd; padding: 8px;">100kW</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">Max. Power</td><td style="border: 1px solid #ddd; padding: 8px;">110kW</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">THDi</td><td style="border: 1px solid #ddd; padding: 8px;">≤3%</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">DC Ratio</td><td style="border: 1px solid #ddd; padding: 8px;">≤0.5%lon</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">Nominal Voltage</td><td style="border: 1px solid #ddd; padding: 8px;">400Vac/3P+N+PE</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">Power Factor</td><td style="border: 1px solid #ddd; padding: 8px;">-1lagging~1leading</td></tr><tr><td style="border: 1px solid #ddd; padding: 8px;">Nominal Frequency</td><td style="border: 1px solid #ddd; padding: 8px;">50Hz/60Hz</td></tr></table>',
'expanded' => false
)
);
// 如果没有保存的数据,使用默认数据
if (empty($technical_specs_data)) {
$technical_specs_data = $default_specs;
}
?>
<div id="technical-specs-container">
<p><strong>技术规格板块设置:</strong></p>
<div style="margin-bottom: 20px; padding: 15px; background: #f0f0f0; border-radius: 4px;">
<label for="show_technical_specs">
<input type="checkbox" id="show_technical_specs" name="show_technical_specs" value="1" <?php checked($show_technical_specs, '1'); ?> />
<strong>显示技术规格板块</strong>
</label>
<p><small>勾选此选项将在前端显示技术规格折叠面板,取消勾选将隐藏整个板块。</small></p>
</div>
<div id="specs-panels-container">
<p><strong>技术规格面板:</strong></p>
<div id="specs-panels-list">
<?php foreach ($technical_specs_data as $index => $spec): ?>
<div class="spec-panel" data-index="<?php echo $index; ?>">
<div class="panel-header">
<h4>面板 <?php echo ($index + 1); ?></h4>
<button type="button" class="button remove-panel">删除面板</button>
</div>
<table class="form-table">
<tr>
<th><label>面板标题</label></th>
<td>
<input type="text" name="technical_specs_data[<?php echo $index; ?>][title]"
value="<?php echo esc_attr($spec['title']); ?>" style="width: 100%;" />
</td>
</tr>
<tr>
<th><label>默认展开</label></th>
<td>
<input type="checkbox" name="technical_specs_data[<?php echo $index; ?>][expanded]"
value="1" <?php checked(!empty($spec['expanded']), true); ?> />
<small>勾选此项,该面板将默认展开显示</small>
</td>
</tr>
<tr>
<th><label>面板内容</label></th>
<td>
<?php
$editor_id = 'technical_specs_content_' . $index;
$settings = array(
'textarea_name' => 'technical_specs_data[' . $index . '][content]',
'media_buttons' => true,
'textarea_rows' => 10,
'teeny' => false,
'tinymce' => array(
'toolbar1' => 'bold,italic,underline,strikethrough,|,bullist,numlist,|,link,unlink,|,undo,redo',
'toolbar2' => '',
'plugins' => 'link,lists'
)
);
wp_editor($spec['content'], $editor_id, $settings);
?>
<small>可以使用富文本编辑器编辑内容,支持文本格式化、列表和链接</small>
</td>
</tr>
</table>
</div>
<?php endforeach; ?>
</div>
<div style="margin-top: 20px;">
<button type="button" id="add-spec-panel" class="button button-primary">添加新面板</button>
</div>
</div>
<p><small><strong>注意:</strong>修改后需要点击"更新"按钮保存设置。第一个面板默认展开,其他面板默认折叠。</small></p>
</div>
<style>
#technical-specs-container .spec-panel {
border: 1px solid #ddd;
margin-bottom: 20px;
padding: 15px;
background: #fff;
border-radius: 4px;
}
#technical-specs-container .panel-header {
display: flex;
justify-content: space-between;
align-items: center;
margin-bottom: 15px;
padding-bottom: 10px;
border-bottom: 1px solid #eee;
}
#technical-specs-container .panel-header h4 {
margin: 0;
color: #333;
}
#technical-specs-container .form-table th {
width: 120px;
padding: 8px 0;
}
#technical-specs-container .form-table td {
padding: 8px 0;
}
</style>
<script>
jQuery(document).ready(function($) {
var panelIndex = <?php echo count($technical_specs_data); ?>;
// 添加新面板
$('#add-spec-panel').click(function() {
var editorId = 'technical_specs_content_' + panelIndex;
var newPanel = $('<div class="spec-panel" data-index="' + panelIndex + '">' +
'<div class="panel-header">' +
'<h4>面板 ' + (panelIndex + 1) + '</h4>' +
'<button type="button" class="button remove-panel">删除面板</button>' +
'</div>' +
'<table class="form-table">' +
'<tr>' +
'<th><label>面板标题</label></th>' +
'<td><input type="text" name="technical_specs_data[' + panelIndex + '][title]" value="" style="width: 100%;" /></td>' +
'</tr>' +
'<tr>' +
'<th><label>默认展开</label></th>' +
'<td><input type="checkbox" name="technical_specs_data[' + panelIndex + '][expanded]" value="1" /><small>勾选此项,该面板将默认展开显示</small></td>' +
'</tr>' +
'<tr>' +
'<th><label>面板内容</label></th>' +
'<td><div id="' + editorId + '_container"></div><small>可以使用富文本编辑器编辑内容,支持文本格式化、列表和链接</small></td>' +
'</tr>' +
'</table>' +
'</div>');
$('#specs-panels-list').append(newPanel);
// 初始化富文本编辑器
var editorSettings = {
tinymce: {
wpautop: true,
plugins: 'charmap colorpicker hr lists paste tabfocus textcolor fullscreen wordpress wpautoresize wpeditimage wpemoji wpgallery wplink wptextpattern',
toolbar1: 'bold,italic,underline,strikethrough,|,bullist,numlist,|,link,unlink,|,wp_adv',
toolbar2: 'formatselect,forecolor,|,pastetext,removeformat,|,charmap,|,outdent,indent,|,undo,redo,|,fullscreen'
},
quicktags: true,
mediaButtons: true
};
// 创建textarea元素
var textarea = $('<textarea name="technical_specs_data[' + panelIndex + '][content]" id="' + editorId + '" rows="10" style="width: 100%;"></textarea>');
$('#' + editorId + '_container').append(textarea);
// 初始化TinyMCE编辑器
if (typeof tinymce !== 'undefined') {
tinymce.init({
selector: '#' + editorId,
height: 300,
menubar: false,
plugins: 'link lists textcolor colorpicker',
toolbar: 'bold italic underline | bullist numlist | link unlink | forecolor backcolor | removeformat',
setup: function(editor) {
editor.on('change', function() {
editor.save();
});
}
});
}
panelIndex++;
});
// 删除面板
$(document).on('click', '.remove-panel', function() {
if (confirm('确定要删除这个面板吗?')) {
var panel = $(this).closest('.spec-panel');
var textarea = panel.find('textarea');
// 清理TinyMCE编辑器实例
if (textarea.length > 0 && typeof tinymce !== 'undefined') {
var editorId = textarea.attr('id');
if (editorId && tinymce.get(editorId)) {
tinymce.get(editorId).remove();
}
}
panel.remove();
}
});
});
</script>
<?php
}
/**
* 保存技术规格meta box数据
*/
function save_product_technical_specs($post_id) {
if (!isset($_POST['product_technical_specs_nonce']) || !wp_verify_nonce($_POST['product_technical_specs_nonce'], 'save_product_technical_specs')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存显示开关
if (isset($_POST['show_technical_specs'])) {
update_post_meta($post_id, '_show_technical_specs', '1');
} else {
update_post_meta($post_id, '_show_technical_specs', '0');
}
// 保存技术规格数据
if (isset($_POST['technical_specs_data']) && is_array($_POST['technical_specs_data'])) {
$technical_specs_data = array();
foreach ($_POST['technical_specs_data'] as $index => $spec) {
if (!empty($spec['title'])) {
$technical_specs_data[] = array(
'title' => sanitize_text_field($spec['title']),
'content' => wp_kses_post($spec['content']),
'expanded' => !empty($spec['expanded'])
);
}
}
update_post_meta($post_id, '_technical_specs_data', $technical_specs_data);
}
}
add_action('save_post', 'save_product_technical_specs');
/**
* 产品PDF下载meta box回调函数
*/
function product_pdf_downloads_meta_box_callback($post) {
wp_nonce_field('save_product_pdf_downloads', 'product_pdf_downloads_nonce');
// 获取显示开关
$show_pdf_downloads = get_post_meta($post->ID, '_show_pdf_downloads', true);
if ($show_pdf_downloads === '') {
$show_pdf_downloads = '1'; // 默认显示
}
// 获取PDF下载数据
$pdf_downloads_data = get_post_meta($post->ID, '_pdf_downloads_data', true);
if (empty($pdf_downloads_data)) {
$pdf_downloads_data = array(
array(
'title' => 'Nenghui\'s innovative 40',
'file_url' => '',
'file_size' => '',
'description' => ''
)
);
}
?>
<table class="form-table">
<tr>
<th><label>显示PDF下载板块</label></th>
<td>
<input type="checkbox" name="show_pdf_downloads" value="1" <?php checked($show_pdf_downloads, '1'); ?> />
<small>勾选此项将在产品页面显示PDF下载板块</small>
</td>
</tr>
</table>
<div id="pdf-downloads-list">
<h4>PDF文件列表</h4>
<?php foreach ($pdf_downloads_data as $index => $pdf): ?>
<div class="pdf-item" data-index="<?php echo $index; ?>">
<div class="pdf-header">
<h4>PDF文件 <?php echo ($index + 1); ?></h4>
<button type="button" class="button remove-pdf">删除文件</button>
</div>
<table class="form-table">
<tr>
<th><label>文件标题</label></th>
<td><input type="text" name="pdf_downloads_data[<?php echo $index; ?>][title]" value="<?php echo esc_attr($pdf['title']); ?>" style="width: 100%;" /></td>
</tr>
<tr>
<th><label>PDF文件</label></th>
<td>
<input type="url" name="pdf_downloads_data[<?php echo $index; ?>][file_url]" value="<?php echo esc_attr($pdf['file_url']); ?>" class="regular-text pdf-url-input" placeholder="PDF文件URL" style="margin-right: 10px;" />
<button type="button" class="button upload-pdf-button">上传PDF</button>
<small style="display: block; margin-top: 5px;">仅支持PDF格式文件</small>
</td>
</tr>
<tr>
<th><label>文件大小</label></th>
<td><input type="text" name="pdf_downloads_data[<?php echo $index; ?>][file_size]" value="<?php echo esc_attr($pdf['file_size']); ?>" class="regular-text" placeholder="例如: 2.5MB" /></td>
</tr>
<tr>
<th><label>文件描述</label></th>
<td><textarea name="pdf_downloads_data[<?php echo $index; ?>][description]" rows="3" style="width: 100%;"><?php echo esc_textarea($pdf['description']); ?></textarea></td>
</tr>
</table>
</div>
<?php endforeach; ?>
</div>
<p>
<button type="button" id="add-pdf-item" class="button button-secondary">添加PDF文件</button>
</p>
<script>
jQuery(document).ready(function($) {
var pdfIndex = <?php echo count($pdf_downloads_data); ?>;
// 添加新PDF文件
$('#add-pdf-item').click(function() {
var newPdf = $('<div class="pdf-item" data-index="' + pdfIndex + '">' +
'<div class="pdf-header">' +
'<h4>PDF文件 ' + (pdfIndex + 1) + '</h4>' +
'<button type="button" class="button remove-pdf">删除文件</button>' +
'</div>' +
'<table class="form-table">' +
'<tr>' +
'<th><label>文件标题</label></th>' +
'<td><input type="text" name="pdf_downloads_data[' + pdfIndex + '][title]" value="" style="width: 100%;" /></td>' +
'</tr>' +
'<tr>' +
'<th><label>PDF文件</label></th>' +
'<td>' +
'<input type="url" name="pdf_downloads_data[' + pdfIndex + '][file_url]" value="" class="regular-text pdf-url-input" placeholder="PDF文件URL" style="margin-right: 10px;" />' +
'<button type="button" class="button upload-pdf-button">上传PDF</button>' +
'<small style="display: block; margin-top: 5px;">仅支持PDF格式文件</small>' +
'</td>' +
'</tr>' +
'<tr>' +
'<th><label>文件大小</label></th>' +
'<td><input type="text" name="pdf_downloads_data[' + pdfIndex + '][file_size]" value="" class="regular-text" placeholder="例如: 2.5MB" /></td>' +
'</tr>' +
'<tr>' +
'<th><label>文件描述</label></th>' +
'<td><textarea name="pdf_downloads_data[' + pdfIndex + '][description]" rows="3" style="width: 100%;"></textarea></td>' +
'</tr>' +
'</table>' +
'</div>');
$('#pdf-downloads-list').append(newPdf);
pdfIndex++;
});
// 删除PDF文件
$(document).on('click', '.remove-pdf', function() {
if (confirm('确定要删除这个PDF文件吗')) {
$(this).closest('.pdf-item').remove();
}
});
// 上传PDF文件
$(document).on('click', '.upload-pdf-button', function() {
var button = $(this);
var urlInput = button.siblings('.pdf-url-input');
var mediaUploader = wp.media({
title: '选择PDF文件',
button: {
text: '选择文件'
},
library: {
type: 'application/pdf'
},
multiple: false
});
mediaUploader.on('select', function() {
var attachment = mediaUploader.state().get('selection').first().toJSON();
if (attachment.subtype === 'pdf') {
urlInput.val(attachment.url);
// 自动填充文件大小
var sizeInput = button.closest('.pdf-item').find('input[name*="[file_size]"]');
if (attachment.filesizeHumanReadable) {
sizeInput.val(attachment.filesizeHumanReadable);
}
} else {
alert('请选择PDF格式的文件');
}
});
mediaUploader.open();
});
});
</script>
<?php
}
/**
* 保存产品PDF下载meta box数据
*/
function save_product_pdf_downloads($post_id) {
if (!isset($_POST['product_pdf_downloads_nonce']) || !wp_verify_nonce($_POST['product_pdf_downloads_nonce'], 'save_product_pdf_downloads')) {
return;
}
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return;
}
if (!current_user_can('edit_post', $post_id)) {
return;
}
// 保存显示开关
if (isset($_POST['show_pdf_downloads'])) {
update_post_meta($post_id, '_show_pdf_downloads', '1');
} else {
update_post_meta($post_id, '_show_pdf_downloads', '0');
}
// 保存PDF下载数据
if (isset($_POST['pdf_downloads_data']) && is_array($_POST['pdf_downloads_data'])) {
$pdf_downloads_data = array();
foreach ($_POST['pdf_downloads_data'] as $index => $pdf) {
if (!empty($pdf['title']) || !empty($pdf['file_url'])) {
$pdf_downloads_data[] = array(
'title' => sanitize_text_field($pdf['title']),
'file_url' => esc_url_raw($pdf['file_url']),
'file_size' => sanitize_text_field($pdf['file_size']),
'description' => sanitize_textarea_field($pdf['description'])
);
}
}
update_post_meta($post_id, '_pdf_downloads_data', $pdf_downloads_data);
}
}
add_action('save_post', 'save_product_pdf_downloads');
?>