🎯 何时使用本技能
- 新建或维护依赖 zibll 子比主题的独立插件(非修改主题核心文件)
- 需要 CSF 后台选项或 CSF 小工具,且必须兼容主题加载顺序
- 开发 zibll 附加插件、子比扩展、CSF 后台、侧栏小工具或与 zibaut 并列的插件
⚠️ 核心约束(必读)
💡 重要提示:违反以下约束将导致插件无法正常工作或产生致命错误。
- 主题后于插件加载:任意
CSF::、CSF_Widget及依赖主题提供的函数,必须挂在zib_require_end内;不得在插件文件顶层直接调用(否则会因主题未加载而报错)。 - 插件主文件名必须与插件文件夹名完全一致(例如文件夹
zibll-additional-demo01→ 入口zibll-additional-demo01.php)。 - 所有函数、选项 key、widget key、脚本 handle 使用唯一前缀,避免与主题或其他插件冲突。
- CSF 的 options 储存 KEY(
$options_key)必须全局唯一,不可与其它插件或主题重复。 - CSF 框架路径:主题的 CSF 框架主体代码位于
inc/codestar-framework/目录下,inc/csf-framework/仅包含小工具表单相关的ZCSF类。插件开发应使用CSF::createOptions()和CSF::createWidget(),这两个方法都在codestar-framework中定义。
主题加载顺序说明
主题在 inc/inc.php 中按以下顺序加载核心文件:
inc/dependent→ 依赖检测与工具函数inc/codestar-framework/codestar-framework→ CSF 框架主体inc/widgets/widget-class→ 小工具类封装inc/csf-framework/classes/zib-csf.class→ ZCSF 小工具表单类do_action('zib_require_end')→ 插件应挂载此钩子注册 CSF
理解加载顺序有助于避免”类未定义”错误。
🚀 快速开始
1. 创建插件目录结构
在同名 zibll-additional-demo01.php 顶部使用 WordPress 标准插件头注释,按需修改名称、版本、作者、URI、Requires PHP 等。
新建插件目录,例如 zibll-additional-demo01/
<!--?php
/**
* Plugin Name: 子比附加示例插件
* Plugin URI: https://1z345.cn/
* Description: 专为子比主题开发的附加示例插件
* Version: 1.0.0
* Author: 小武
* Author URI: https://1z345.cn/
* Requires at least: 7.0
* Requires PHP: 8.1
*/
if (!defined('ABSPATH')) {
exit;
}-->2. 主题依赖检测
在入口文件早期执行(在引入使用主题的代码之前):
- 若
get_stylesheet() != 'zibll':仅add_action('admin_notices', ...)提示依赖 zibll,然后return终止后续加载,避免前台/后台致命错误。
3. 注册激活钩子
使用 register_activation_hook() 处理启用时任务(建表、初始化选项等)。
4. 分文件组织代码
根据插件复杂度选择合适的组织结构:
- 简单插件:逻辑可集中在入口文件
- 复杂插件:按功能模块分子目录
your-plugin/
├── your-plugin.php # 入口(依赖检测 + require_once)
├── inc/
│ ├── options.php # CSF 后台选项(挂 zib_require_end)
│ ├── widget.php # CSF 小工具(挂 zib_require_end)
│ └── ajax.php # AJAX 处理器
└── assets/
├── css/
│ └── frontend.css # 前台样式
└── js/
└── frontend.js # 前台脚本5. CSF 后台选项配置
⚠️ 关键:必须将注册函数挂在
zib_require_end钩子内!
- 使用:
add_action('zib_require_end', 'yourprefix_admin_csf_options'); - 函数内先检查:
if (!is_admin()) return; - 使用唯一
$options_key调用CSF::createOptions($options_key, array(...)) - 再用
CSF::createSection/ fields 定义字段;字段id仅限小写字母、数字、下划线 - 复杂字段类型可参考主题内示例:
wp-content/themes/zibll/inc/options/admin-options.php
完整模板:
function yourprefix_admin_csf_options()
{
if (!is_admin()) {
return;
}
$options_key = 'yourplugin_options';
CSF::createOptions($options_key, array(
'menu_title' => __('你的插件设置', 'your-textdomain'),
'menu_slug' => $options_key,
'framework_title' => __('插件名称', 'your-textdomain'),
'show_in_customizer' => false,
'theme' => 'light',
));
CSF::createSection($options_key, array(
'id' => 'basic',
'title' => __('基础设置', 'your-textdomain'),
'icon' => 'fa fa-fw fa-cog',
'fields' => array(
array(
'id' => 'enabled',
'type' => 'switcher',
'title' => __('启用功能', 'your-textdomain'),
'default' => true,
),
array(
'id' => 'text_field',
'type' => 'text',
'title' => __('文本输入', 'your-textdomain'),
'default' => '',
),
),
));add_action(‘zib_require_end’, ‘yourprefix_admin_csf_options’);
### CSF 选项保存钩子机制
CSF 框架在保存选项时会触发以下钩子(以 `$options_key = 'arc_options'` 为例):
| 钩子名称 | 类型 | 用途 | 示例 |
|---------|------|------|------|
| `csf_{$unique}_save` | filter | 保存前验证/修改数据 | `add_filter('csf_arc_options_save', ...)` |
| `csf_{$unique}_saved` | action | 保存后执行操作(如清缓存) | `add_action('csf_arc_options_saved', ...)` |
**完整示例:**
```php
// 保存前验证
add_filter('csf_arc_options_save', function($data) {
// 验证逻辑
if (empty($data['required_field'])) {
add_settings_error('arc_options', 'required_missing', __('必填字段不能为空', 'textdomain'));
}
return $data;
});
// 保存后清除缓存
add_action('csf_arc_options_saved', function() {
wp_cache_delete('arc_plugin_options', 'arc_plugin');
});⚠️ 常见错误:不要猜测钩子名称如 csf_validate_arc_options 或 csf_save_options_arc_options,正确格式始终是 csf_{$unique}_save 和 csf_{$unique}_saved。
6. 读取主题选项
使用主题提供的 _pz() 函数读取后台设置(带静态缓存,性能极佳):
- 实现
yourprefix_get_option($key, $default = false):内部static $options,首次get_option($options_key),返回$options[$key] ?? $default。 $options_key与 CSF 注册处必须一致。
function yourprefix_get_option($key, $default = false)
{
static $options = null;
if ($options === null) {
$options = get_option('yourplugin_options');
}
return isset($options[$key]) ? $options[$key] : $default;
}7. 创建 CSF 小工具
⚠️ 同样必须挂在
zib_require_end钩子内!⚠️ 重要说明:
Zib_CFSwidget已完全废弃(源码注释明确说明”此对象已经没有使用,为了兼容旧版插件保留”),内部直接委托给CSF::createWidget()→CSF_Widget。
- 新插件必须使用:
CSF::createWidget($widget_key, array(...))- 旧代码兼容:
Zib_CFSwidget::create($widget_key, array(...))仍可工作,但不推荐使用
- 注册:
add_action('zib_require_end', 'yourprefix_widget_create'); CSF::createWidget($widget_key, array(...))或Zib_CFSwidget::create($widget_key, array(...)):$widget_key自定且唯一。- 前端输出函数名必须等于
create的第一个参数$widget_key。 - 输出模板:使用
CSF_Widget::show_class($instance)做显示控制;内容直接echoHTML 即可;文本输出使用esc_html/ 合适转义。
完整模板:
// 注册小工具(必须在 zib_require_end 内)
function yourprefix_widget_create()
{
CSF::createWidget('yourprefix_demo_widget', array(
'title' => __('你的小工具', 'your-textdomain'),
'classname' => 'yourprefix-demo-widget',
'description' => __('小工具描述', 'your-textdomain'),
'width' => '350px',
'fields' => array(
array(
'id' => 'title',
'type' => 'text',
'title' => __('标题', 'your-textdomain'),
'default' => __('默认标题', 'your-textdomain'),
),
array(
'id' => 'show_bg',
'type' => 'switcher',
'title' => __('显示背景', 'your-textdomain'),
'default' => true,
),
),
));
}
add_action('zib_require_end', 'yourprefix_widget_create');
// 前端输出(函数名 = widget_key)
function yourprefix_demo_widget($args, $instance)
{
$show_bg = !empty($instance['show_bg']);
$title = $instance['title'] ?? '';
echo '<div class="clearfix">';
if ($show_bg) {
echo '<div class="zib-widget nobottom notop">';
}
if ($title) {
echo '<h4 class="widget-title">' . esc_html($title) . '</h4>';
}
echo '<div class="muted-box padding-10">你的内容</div>';
if ($show_bg) {
echo '</div>';
}
echo '</div>';
}
// 可选:显示条件过滤
function yourprefix_demo_widget_is_show($show_class, $args, $instance)
{
if (empty($instance['title'])) {
return false;
}
return $show_class;
}8. 引入前端资源
前台样式与脚本
- 典型目录:
assets/css/、assets/js/。 - 前台:
add_action('wp_enqueue_scripts', ...)→wp_enqueue_style/wp_enqueue_script(plugin_dir_url(__FILE__),版本号与插件一致)。 - 后台:
add_action('admin_enqueue_scripts', ...)。 - 脚本依赖按需声明(如
array('jquery'));主题在 zib-theme.php:1044-1082 中重新注册了jquery(主题目录js/libs/jquery.min.js),插件与主题并存时勿假设 WP 默认 jQuery CDN 路径。 - CSS 加载顺序建议:声明依赖
array('main')确保在主题 main.css 之后加载。
function yourprefix_enqueue_assets()
{
$url = plugin_dir_url(__FILE__);
$ver = YOURPLUGIN_VERSION;
wp_enqueue_style('yourprefix-frontend', $url . 'assets/css/frontend.css', array('main'), $ver);
wp_enqueue_script('yourprefix-frontend', $url . 'assets/js/frontend.js', array('jquery'), $ver, true);
wp_localize_script('yourprefix-frontend', 'yourprefix_var', array(
'ajax_url' => admin_url('admin-ajax.php'),
'nonce' => wp_create_nonce('yourprefix_nonce'),
));
}
add_action('wp_enqueue_scripts', 'yourprefix_enqueue_assets');🔐 AJAX 安全标准
所有 AJAX 请求必须遵循以下安全规范:
所有插件自增的 AJAX 接口都应遵循以下安全模式:
// 注册(公开接口才加 nopriv)
add_action('wp_ajax_yourprefix_action', 'yourprefix_ajax_handler');
// add_action('wp_ajax_nopriv_yourprefix_action', 'yourprefix_ajax_handler'); // 仅需公开时取消注释
function yourprefix_ajax_handler()
{
// 1. Nonce 验证
check_ajax_referer('yourprefix_nonce', 'nonce');
// 2. 权限检查
if (!current_user_can('read')) {
wp_send_json_error(__('权限不足', 'your-textdomain'), 403);
}
// 3. 获取并清理参数
$data = isset($_POST['data']) ? sanitize_text_field(wp_unslash($_POST['data'])) : '';
// 4. 业务逻辑
// ...
// 5. 返回
wp_send_json_success(array('result' => $data));
}关键注意点:
- 非公开接口(需要登录)不要注册
wp_ajax_nopriv_*钩子。 - 公开接口(如查询类)必须同时注册
wp_ajax_*和wp_ajax_nopriv_*,并在回调内做权限分级。 - nonce 应通过
wp_localize_script注入到 JS 变量中,前端 AJAX 时携带。 - 主题内置的
zib_ajax()会自动处理 nonce(通过form-data属性或window.captcha),插件自定义接口应自行管理 nonce。
📚 主题 API 速查表
inc/ 目录常用函数
以下为在已启用 zibll 前提下可用的常用入口;升级主题后请以源码为准,并可在 inc 与 zibpay 下用 grep 自行补充。
主题选项
_pz($name, $default = false, $subname = '')— 读取get_option('zibll_options'),带静态缓存;嵌套配置用$subname。定义见inc/dependent.php:112。_spz($name, $value)— 写回zibll_options中单键(覆盖式合并需谨慎,优先用 CSF/后台改主题设置)。定义见inc/dependent.php:131。
用户系统(inc/functions/user/)
| 函数 | 文件 | 用途 |
|---|---|---|
zib_get_user_center_link($class, $text) | user.php | 用户中心页 <a> HTML |
zib_get_user_center_url($type, $tab) | user.php | 用户中心 URL($type: order/message/settings 等) |
zib_get_user_id($id_or_email) | zib-theme.php:539 | 从 ID/email/对象获取用户 ID |
zib_get_data_avatar($user_id, $size) | zib-theme.php | 获取头像 HTML(含懒加载) |
zib_get_user_meta($user_id, $key, $single) | dependent.php | 读取用户 meta |
zib_user_is_ban($user_id) | user-ban.php | 是否被封禁 |
zib_get_user_ban_info($user_id) | user-ban.php | 封禁详情 |
zib_get_user_ban_info_modal($user_id) | user-ban.php | 封禁信息弹窗 HTML |
zib_get_user_ban_appeal_modal($user_id) | user-ban.php | 申诉弹窗 HTML |
zib_user_checkin($user_id) | user-checkin.php | 执行签到 |
zib_user_is_checkined($user_id) | user-checkin.php | 今日是否已签到 |
zib_get_user_checkin_btn(...) | user-checkin.php | 签到按钮 HTML |
zib_get_user_checkin_details_modal($user_id) | user-checkin.php | 签到详情弹窗 |
zib_add_user_medal($user_id, $medal_name, $remarks) | user_medal.php | 添加勋章 |
zib_get_user_medal_info_modal($user_id) | user.php (modal) | 勋章信息弹窗 |
zib_get_user_auth_apply_modal(...) | user-auth.php | 认证申请弹窗 |
zib_get_user_auth_info_modal(...) | user-auth.php | 认证信息弹窗 |
zib_get_user_card_box($user_id) | user.php (card) | 用户悬浮卡片 |
zib_get_user_badges($user_id) | functions.php:482 | 用户徽标 HTML |
zib_get_user_follow(...) | zib-theme.php:2187 | 关注按钮 |
zib_get_user_favorite_count($author_id) | zib-theme.py:1318 | 收藏计数 |
用户中心扩展点(filter):
zib_user_can($capability)— 统一能力判断zib_user_center_page_sidebar_button_1_args/_2_args— 用户中心侧栏按钮配置(数组,可追加按钮)zib_user_center_page_sidebar— 用户中心侧栏内容user_show_name— 显示名user_name_badge/user_avatar_badge/user_count_badges— 名称/头像/数量徽标user_medal_args— 勋章参数user_center_account_setup— 账户设置区user_sidebar_statistics_args— 侧栏统计
URL 与工具
zib_get_current_url()— 当前页面完整 URL。inc/functions/functions.php。zib_get_admin_ajax_url($action = false, $query_arg = array())— 拼装admin-ajax.php链接。zib_get_lazy_attr($size, $is_other = false)— 图片懒加载属性。inc/functions/zib-tool.php。zib_get_time_ago($timestamp)/zib_get_time_remaining($end)/zib_get_time_spend($start, $end)— 时间文案。zib_is_show_sidebar()— 是否显示侧栏(结果可走zib_is_show_sidebarfilter)。zib_get_theme_mode()— 亮/暗等(可走zib_theme_modefilter)。
UI 组件(PHP 输出 HTML)
模态框(Modal)
zib_modal($args) — 构建 Bootstrap 3 模态框。inc/functions/functions.php:992。
zib_modal(array(
'id' => 'my-modal-id',
'class' => 'modal-sm',
'colorful_header' => true,
'header_class' => 'jb-blue',
'header_icon' => '<i class="fa fa-info-circle"></i>',
'title' => '标题',
'content' => '内容 HTML',
'buttons_align' => 'right',
'buttons' => array(
array(
'text' => '确定',
'class' => 'but c-green',
'data' => array('dismiss' => 'modal'),
),
),
'buttons_class' => 'but radius',
));其他模态相关函数:
| 函数 | 用途 |
|---|---|
zib_get_blank_modal($args) | 空白模态容器(仅 header + body 容器) |
zib_get_blank_modal_link($text, $config) | 触发空白模态的 <a> 链接 |
zib_get_refresh_modal_link($text, $config) | 刷新内容模态链接 |
zib_get_add_modal_link($text, $config) | 追加内容模态链接 |
zib_get_modal_colorful_header($class, $icon, $content, $close_btn) | 彩色头部 HTML 片段 |
zib_get_report_modal($post_id) | 举报弹窗 |
zib_get_rewards_modal($post_id) | 打赏弹窗 |
zib_get_user_auth_apply_modal($user_id) | 认证申请弹窗 |
zib_get_user_ban_appeal_modal($user_id) | 封禁申诉弹窗 |
zib_get_user_checkin_details_modal($user_id) | 签到详情弹窗 |
zib_get_user_medal_info_modal($user_id) | 勋章详情弹窗 |
Tab 导航
zib_get_ajax_tab($tabs, $active, $args)— AJAX Tab 切换组件。返回包含.ajax-tab容器的 HTML。zib_get_main_tab_nav($tabs, $active)— 主导航 Tab(用于搜索/作者等页)。zib_get_search_main_tab_nav(...)/zib_get_search_tab_nav_filter(...)— 搜索页 Tab。
提示 / 公告
zib_notice($args, $echo = true) — 公告轮播条(swiper)。functions.php:882。
zib_notice(array(
'class' => 'c-blue',
'interval' => 5000,
'notice' => array(
array('title' => '公告1', 'icon' => 'fa fa-bullhorn', 'href' => 'https://...'),
array('title' => '公告2', 'icon' => 'fa fa-info-circle'),
),
));zib_system_notice()— 页脚自动弹出系统通知模态(由主题选项控制,插件一般不需直接调用)。
链接生成器
| 函数 | 用途 |
|---|---|
zib_get_post_edit_link($post_id) | 编辑文章链接 |
zib_get_report_link($post_id, $class, $text) | 举报链接 |
zib_get_refresh_modal_link($text, $config) | 刷新模态触发链接 |
zib_get_msg_all_readed_link($class, $text) | 全部已读链接 |
zib_get_user_auth_*_link(...) | 用户认证相关链接 |
zib_get_user_ban_*_link(...) | 用户封禁相关链接 |
zib_get_url_link($url, $text, $class) | 通用外链 |
卡片组件
zib_icon_card($args)— 图标卡片(图标+标题+描述+链接)。zib_get_user_card_box($user_id)— 用户悬浮卡片。zib_get_user_card_lists($user_id)/zib_get_user_card_post($user_id)— 卡片内的列表/文章。
移动底栏
- filter
footer_tabbar— 底部导航栏按钮配置 zib_get_footer_tabbar_btn($args)— 单个底栏按钮zib_get_single_footer_tabbar()— 文章页底栏
ZibPay(zibpay/functions/)
| 函数 | 用途 |
|---|---|
zibpay_is_paid($post_id, $user_id = 0) | 是否已具备文章付费权益 |
zibpay_get_post_paid_data_by_user($post_id, $user_id) | 付费状态细节(按用户) |
zibpay_get_post_paid_data_by_order_num($order_num) | 付费状态细节(按订单号) |
zibpay_get_order_title($order) | 订单标题文案 |
zibpay_get_order_status_name($status) | 订单状态名 |
zibpay_get_pay_type_name($type) | 支付方式名 |
zibpay_get_payment_methods() | 可用支付方式列表 |
zibpay_get_initiate_pay_input($order) | 发起支付按钮 HTML |
zibpay_get_admin_shop_url() | 后台商城 URL |
zibpay_get_admin_shop_order_url() | 后台订单 URL |
发现更多: 在主题内执行 grep -rn "^function zib_" inc/ zibpay/ 或按文件名浏览(如 zib-single.php、zib-header.php)。
常用动作钩子 do_action
核心 / 生命周期
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_require_end | inc/inc.php:126 — 主题加载链结束 | 无 |
zibll_update_notices | 主题更新后提示 | $theme_version |
zibll_new_install_notices | 主题新安装提示 | $theme_version |
单篇 / 内容
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_single_before | 单篇模板开头 | 无 |
zib_single_after | 单篇模板结尾 | 无 |
zib_single_box_content_before | 单篇内容盒之前 | 无 |
zib_single_box_content_after | 单篇内容盒之后 | 无 |
zib_posts_content_before | 正文区域之前 | $post |
zib_posts_content_after | 正文区域之后 | $post |
zib_article_content_after | 正文输出之后 | $post |
zib_pre_insert_post | BBS 等发帖写入数据库前 | $insert_args / $post_args |
zib_frontend_set_save | 前台编辑保存 | $object_data, $type |
zib_bbs_posts_content_after | 论坛帖正文之后 | $post |
作者 / 用户中心
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_author_main_content | 作者页主内容区 | 无 |
zib_use_invit_code | 邀请码使用成功 | $user_id, $invit_code_obj |
user_checkined | 签到成功后 | (由签到动作触发) |
user_add_medal | 添加勋章后 | (由勋章动作触发) |
user_remove_medal | 移除勋章后 | (由勋章动作触发) |
updata_user_ban | 更新封禁状态后 | (由封禁动作触发) |
私信 / 消息
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_add_message | 发送私信前 | $values |
zib_update_message | 更新私信 | $values |
zib_message_readed | 已读私信 | $id, $_user_id |
zib_message_all_readed | 全部已读 | $where, $user_id |
zib_message_set_status | 设置消息状态 | $id, $values |
zib_message_set_status_batch | 批量设状态 | $where, $values |
商城 / 订单
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_shop_init | 商城初始化 | 无 |
zibpay_download_before | 付费下载前 | $post_id, $down_id, $paid, $file_url, $file_local |
order_created | 订单创建后 | 订单对象 |
payment_order_success | 支付成功后 | 订单对象 |
order_closed | 订单关闭后 | 订单 ID |
order_refunded | 订单退款后 | 订单 ID |
save_order_meta | 保存订单 meta | $order_id, $key, $value |
add_order_meta | 新增订单 meta | 同上 |
update_order_meta | 更新订单 meta | 同上 |
delete_order_meta | 删除订单 meta | 同上 |
delete_order | 删除订单 | 订单 ID |
pay_transfer | 余额转账 | 转账数据 |
user_apply_withdraw | 申请提现 | 提现数据 |
withdraw_process | 提现处理 | 处理数据 |
withdraw_process_newmsg | 提现新消息 | 消息数据 |
BBS / 社区
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
bbs_favorite_posts | 收藏帖子 | 相关数据 |
bbs_follow_plate | 关注版块 | 版块数据 |
bbs_home_tab_content_top | 论坛首页 Tab 顶部 | 无 |
bbs_home_tab_content_bottom | 论坛首页 Tab 底部 | 无 |
bbs_posts_essence_set | 设精华 | 帖子数据 |
bbs_posts_topping_set | 置顶 | 帖子数据 |
bbs_single_footer | 帖子底部 | 帖子数据 |
posts_is_hot | 设热门 | 帖子数据 |
posts_plate_move | 移动版块 | 帖子数据 |
plate_is_hot | 版块热门 | 版块数据 |
answer_adopted | 采纳答案 | 回答数据 |
comment_is_hot | 评论热门 | 评论数据 |
shop_favorite_product | 收藏商品 | 商品数据 |
shop_product_page_content_after | 商品页内容后 | 商品数据 |
author_points_income | 积分收入 | 积分数据 |
小工具
| 钩子 | 位置/用途 | 参数 |
|---|---|---|
zib_cfswidget_echo_before | 侧栏模块输出前包裹 | $args |
zib_cfswidget_echo_after | 侧栏模块输出后包裹 | $args |
常用过滤钩子 apply_filters
主题全局
| 钩子 | 用途 |
|---|---|
zib_temp_dir | 临时目录(与常量 ZIB_TEMP_DIR 一致) |
zib_is_show_sidebar | 是否显示侧栏 |
zib_theme_mode | 主题色模式(light/dark 等) |
zib_theme_mode_button_positions | 模式切换按钮位置 |
zib_add_bodyclass | 追加 body class |
zib_get_excerpt | 摘要文本 |
zib_widget_title | 小工具标题 |
zib_float_right | 右下角浮动按钮 HTML |
zib_nav_radius_button | 导航区域圆形按钮 |
zib_user_can | 统一能力判断 $capability |
zib_oauth_login_url | OAuth 登录 URL |
zib_js_i18n_strings | 前台 JS i18n 字符串 |
zib_admin_js_i18n_strings | 后台 JS i18n 字符串 |
footer_tabbar | 移动底栏按钮配置 |
用户中心
| 钩子 | 用途 |
|---|---|
zib_user_center_page_sidebar | 用户中心侧栏内容 |
zib_user_center_page_sidebar_button_1_args | 侧栏按钮组 1 配置 |
zib_user_center_page_sidebar_button_2_args | 侧栏按钮组 2 配置 |
user_show_name | 显示名 |
user_name_badge | 名称徽标 |
user_avatar_badge | 头像徽标 |
user_count_badges | 数量徽标 |
user_medal_args | 勋章参数 |
user_center_account_setup | 账户设置区 |
user_sidebar_statistics_args | 侧栏统计参数 |
user_page_header_desc | 用户页头部描述 |
user_checkin_detail_maximum | 签到详情最大值 |
前台发布 / 表单
| 钩子 | 用途 |
|---|---|
zib_frontend_set_input_array | 前台发布表单字段数组 |
zib_frontend_set_input_html | 前台发布表单字段 HTML |
zib_add_message_values | 发私信前数据处理 |
ZibPay 付费
| 钩子 | 用途 |
|---|---|
zibpay_is_show_paybutton | 是否展示付费按钮 |
zibpay_posts_pay_box | 文章付费区域 HTML |
zibpay_posts_paid_box | 已购区域 HTML |
zibpay_payment_methods | 支付方式列表 |
zibpay_order_title | 订单标题 |
zibpay_initiate_paysdk | 发起支付 SDK |
zibpay_initiate_{$sdk} | 发起指定 SDK 支付 |
zibpay_is_allow_balance_pay | 是否允许余额支付 |
zibpay_is_allow_card_pass_pay | 是否允许卡密支付 |
zibpay_card_pass_payment_desc | 卡密支付描述 |
pay_download_paid_data | 下载数据权限 |
zibpay_download_file_local | 本地下载路径 |
pre_order_create_data | 创建订单前置数据 |
initiate_order_data_type_{$type} | 指定类型订单数据 |
not_repeat_create_order_type | 不重复创建的订单类型 |
pay_order_price_is_allow_0 | 允许 0 元订单 |
hidecontent_is_show | 隐藏内容是否显示 |
hidecontent_payshow_hide_content | 付费隐藏内容 |
tourists_pay_is_allow | 游客是否可购买 |
tourists_pay_cookie_days | 游客购买 cookie 天数 |
zib_add_pay_meta_box_args | 文章编辑付费框参数 |
zib_add_pay_meta_box_meta | 文章编辑付费框 meta |
订单 UI
| 钩子 | 用途 |
|---|---|
user_order_list_card | 订单列表卡片 HTML |
user_order_details_modal | 订单详情弹窗 |
user_page_order_tabs | 订单页 Tab |
user_order_card_btns | 订单卡片按钮 |
user_order_details_footer_left | 详情底部左侧 |
user_order_details_footer_right | 详情底部右侧 |
BBS / 社区
| 钩子 | 用途 |
|---|---|
bbs_home_tab_options | 论坛首页 Tab 选项 |
bbs_home_tab_content_plate_before | 首页版块前 |
bbs_home_tab_content_plate_after | 首页版块后 |
bbs_plate_tab_options | 版块 Tab 选项 |
bbs_plate_order_options | 版块排序选项 |
bbs_posts_order_options | 帖子排序选项 |
bbs_single_fixed_btns | 帖子固定按钮 |
bbs_user_score_deduct_max | 扣分上限 |
bbs_user_score_extra_max | 加分上限 |
bbs_is_hot_plate | 热门版块判断 |
bbs_is_hot_posts | 热门帖子判断 |
作者 / 评论
| 钩子 | 用途 |
|---|---|
author_header_drop_lists | 作者头部下拉菜单 |
author_header_identity | 作者身份标识 |
author_header_more_btn | 作者头部更多按钮 |
author_main_tabs_array | 作者主页 Tab 数组 |
author_main_tab_{$key} | 指定 Tab 内容 |
author_favorite_types | 收藏类型 |
author_favorite_lists_{$type} | 指类型收藏列表 |
author_tab_favorite_count | 收藏计数 |
comments_action_lists | 评论操作列表 |
comments_user_name_badge | 评论用户名徽标 |
comment_header | 评论头部 |
comment_footer_info | 评论底部信息 |
comment_topping_enabled | 是否允许评论置顶 |
comment_edit_enabled | 是否允许编辑评论 |
mag_ctnter_main_tabs_array | 用户中心主 Tab |
user_ctnter_main_tabs_array | 同上(别名) |
search_main_tabs_array | 搜索主 Tab |
search_types | 搜索类型 |
search_orderby_array | 搜索排序 |
search_facets_datas | 搜索筛选数据 |
new_add_btns_options | 发布按钮选项 |
new_add_btns_{$key} | 指定发布按钮 |
frontend_set_switch | 前台编辑开关 |
is_close_signin | 关闭登录 |
is_close_signup | 关闭注册 |
is_can_roles | 允许角色 |
hascaps_roles_lists | 能力角色列表 |
integral_add_options | 积分增加选项 |
page_max_width | 页面最大宽度 |
single_show_breadcrumbs | 显示面包屑 |
shop_auto_delivery_content | 自动发货内容 |
is_shop_cart_page | 是否购物车页 |
widget_form_callback | 小工具表单回调 |
widget_import_templates | 小工具导入模板 |
widget_is_show_{$key} | 小工具是否显示 |
message_cats | 消息分类 |
💻 前端开发规范
复用主题 main.js 全局 API
主题前台脚本链:_load_scripts(zib-theme.php:1044)注册 jquery、bootstrap、loader.js(js/loader.js,内部 tbquire 再异步加载 main.js)。main.js 体量大,集成懒加载(lazySizes)、轮播、播放器、大量委托事件等。附加插件应优先调用已有全局函数,避免重复实现。
window._win(PHP 注入 + JS 补全)
对象首段由主题在页脚内联脚本赋值:zib-footer.php:65-110 中 window._win = { ... }。
完整字段清单:
| 字段 | 类型 | 说明 |
|---|---|---|
views | string | 当前文章 ID(仅单篇有值,否则空) |
www | string | 站点 URL (home_url()) |
uri | string | 主题目录 URL |
ver | string | 主题版本号 |
imgbox | string | 是否启图片灯箱 ("true"/"false") |
imgbox_type | string | 灯箱类型 ("group"/"single") |
imgbox_thumbs | string | 是否显示缩略图 |
imgbox_zoom | string | 是否显示放大 |
imgbox_full | string | 是否全屏 |
imgbox_play | string | 是否播放 |
imgbox_down | string | 是否下载 |
sign_type | string | 登录方式 |
signin_url | string | 登录 URL |
signup_url | string | 注册 URL |
ajax_url | string | admin-ajax.php URL |
ajaxpager | string | 分页方式 |
ajax_trigger | string | “加载更多” 文案 |
ajax_nomore | string | “没有更多了” 文案 |
qj_loading | string | “加载中…” 文案 |
highlight_kg | string | 代码高亮开关 |
highlight_hh | string | 高亮行高 |
highlight_btn | string | 高亮按钮 |
highlight_zt | string | 高亮主题 |
upload_img_size | string | 上传图片大小限制 |
upload_video_size | string | 上传视频大小限制 |
upload_file_size | string | 上传文件大小限制 |
upload_ext | string | 允许上传的扩展名 |
user_upload_nonce | string | 上传 nonce |
post_action_nonce | string | 点赞/收藏等 action nonce |
is_split_upload | string | 分片上传开关 |
split_minimum_size | string | 分片最小尺寸 |
comment_upload_img | string | 评论上传图片开关 |
translate_config | string | 翻译配置 JSON |
i18n | object | 前台 i18n 字符串对象 |
main.js 加载后补充的字段:
_win.bd→ jQuerybody对象_win.window→ jQuerywindow对象_win.is_signin→body是否含logged-inclass
编写插件 JS 时若仅读配置,可在 jQuery(function($){ ... }) 内使用 _win.ajax_url;若依赖 _win.bd,须在主题主逻辑跑了之后(通常同一 document ready 即可)。
AJAX 与提示(优先复用)
| API | 作用 | 要点 |
|---|---|---|
zib_ajax(_this, data, success, noty, no_loading) | 走 admin-ajax.php 的通用提交 | _this 为触发按钮 jQuery 对象;未传 data 时会从父级 form serializeObject(),或用 form-action / form-data 属性补 action;自动附加验证码 window.captcha(若有);成功触发 zib_ajax.success 自定义事件 |
$el.zib_ajax(data, success, noty, no_loading) | 同上 | $.fn.zib_ajax 封装 |
notyf(str, ys, time, id) | 右下角类 Toast | ys:success / danger / warning / load 等;error 会被映射为 danger;window.debounce_notyf 为防抖包装 |
refresh_modal(_config) | 动态 Bootstrap 模态 | 支持 content / remote URL、class、height、mobile_from_bottom、touch_close、new 等;与 [ajax-action] 等主题交互一致 |
debounce(fn, delay, immediate) / throttle(fn, delay) | 防抖 / 节流 | 全局函数,滚动、resize 场景与主题一致 |
$.fn.serializeObject | 表单 → 扁平对象 | 与主题 AJAX 表单惯例一致 |
lcs.get / lcs.set / lcs.remove | 本地存储 | 优先 localStorage,否则回退 jQuery.cookie(main.js 内置 cookie 辅助) |
zib_is_url / is_mail | 简单校验 | 表单或跳转前可复用 |
主题独立入口(非 admin-ajax): action_ajax 等会向 _win.uri + '/action/action.php' POST,并带 _wpnonce: _win.post_action_nonce。插件自增交互应优先用 admin-ajax.php + zib_ajax 模式;若必须与主题 action 目录协议一致,再对齐其 nonce 与字段。
tbquire 异步模块清单
tbquire(['模块名'], callback) 为 loader.js 提供的异步模块加载。以下为主题已注册的模块:
| 模块名 | 用途 |
|---|---|
swiper | Swiper 轮播 |
dplayer | DPlayer 视频播放器 |
captcha | 验证码 |
pay | 支付流程 |
imgbox | 图片灯箱 |
clipboard | 剪贴板复制 |
qrcode | 二维码生成 |
waterfall | 瀑布流布局 |
enlighterjs | 代码高亮 |
comment | 评论功能 |
message | 私信功能 |
sign-register | 登录注册 |
author | 作者页 |
mini-upload | 迷你上传 |
input-expand | 输入框展开 |
page-edit | 页面编辑 |
page-navs | 页面导航 |
page-template | 页面模板 |
poster-share | 海报分享 |
section-navs | 段落导航 |
svg-icon | SVG 图标 |
tilt | 3D 倾斜效果 |
grade | 评分组件 |
weixin-share | 微信分享 |
translate | 翻译 |
插件若仅需极少量逻辑,不必自行再引一套 AMD;必要时在回调内写扩展。
tbquire 异步加载注意事项
tbquire 是主题定制的 RequireJS 实现,所有模块均为异步加载。使用时需注意:
// ❌ 错误:直接使用未加载的模块
tbquire(['swiper'], function() {
// Swiper 已加载
});
// 此处 Swiper 尚未加载,不能使用 new Swiper()
// ✅ 正确:在回调内使用
tbquire(['swiper'], function() {
new Swiper('.my-swiper', { /* config */ });
});
// ✅ 正确:检查全局对象是否存在
if (typeof Swiper !== 'undefined') {
new Swiper('.my-swiper', { /* config */ });
}常见模块的全局对象名:
swiper→window.Swiperdplayer→window.DPlayerclipboard→window.ClipboardJSqrcode→ jQuery 插件$.fn.qrcodegrade→ jQuery 插件$.fn.grade
插件脚本加载顺序建议:
// 依赖主题 main.js(内部会异步加载 loader.js + main.min.js)
wp_enqueue_script('your-plugin', $url, array('jquery'), $ver, true);
// JS 内安全调用主题 API
jQuery(function($) {
// _win 已在页脚注入,可直接使用
console.log(_win.ajax_url);
// zib_ajax 需等待 main.js 加载完成
if (typeof zib_ajax === 'function') {
// 可以安全调用
} else {
// 延迟重试或监听 DOM 事件
$(document).on('zib_main_loaded', function() {
// main.js 加载完成后的逻辑
});
}
});常用 DOM 约定(委托在 body 上)
主题在 _win.bd 上绑定了大量 click/submit:例如 [data-close]、[data-toggle-class]、[ajax-action](admin-ajax + data-nonce)、.wp-ajax-submit / [zibajax="submit"]、[ajax-submit] 触发表单代点提交等。插件 HTML 若沿用这些属性/类名,可无侵入复用主题行为;自定义接口应用独立类名 + 自己的 nonce。
插件脚本挂载建议
wp_enqueue_script(..., ['jquery'], ..., true),在回调内使用typeof zib_ajax === 'function'守卫后再调用(因main.js由 loader 异步拉起,极端情况下 ready 极早时可能尚未定义,可短延迟重试或监听首次交互)。- 不要复制粘贴
main.js整段;只依赖文档化全局 API 与_win。 - 需要独立 UI 时,优先使用主题已加载的 Bootstrap 3 modal/tab 类与既有 notyf 样式,保证视觉一致。
主题内置 JS 工具函数
主题在 main.js 中提供了多个实用工具函数,插件可直接调用:
| 函数 | 用途 | 示例 |
|---|---|---|
zib_get_url_param(name) | 获取 URL 参数 | zib_get_url_param('page') |
zib_parse_url(url) | 解析 URL 对象 | zib_parse_url(window.location.href) |
zib_format_number(num) | 格式化数字(如 1000 → 1k) | zib_format_number(1234) |
zib_format_time(timestamp) | 格式化时间戳为相对时间 | zib_format_time(Date.now()) |
zib_scroll_to(el, offset) | 平滑滚动到指定元素 | zib_scroll_to('#target', 50) |
zib_is_mobile() | 判断是否移动端 | if (zib_is_mobile()) { ... } |
zib_debounce(fn, delay) | 防抖函数 | zib_debounce(myFunc, 300) |
zib_throttle(fn, delay) | 节流函数 | zib_throttle(myFunc, 100) |
使用示例:
// 获取 URL 参数
var page = zib_get_url_param('page');
// 格式化数字
var count = zib_format_number(12345); // 返回 "12.3k"
// 平滑滚动
zib_scroll_to('.target-section', 60);🎨 前台样式开发
复用 main.css 工具类与 CSS 变量
主题前台样式入口为 wp-content/themes/zibll/css/main.min.css(源文件 main.css,14736 行,由 _cssloader 注册)。附加插件输出 HTML(小工具、短代码、模态片段)时优先使用主题已有 class,避免硬编码色值,以自动适配亮色 / body.dark-theme。
body 上的 CSS 变量(完整清单)
根变量(:root):
| 变量 | 含义 | 默认值(亮色) |
|---|---|---|
--mian-max-width | 最大内容宽(源码拼写 mian) | 1200px |
--posts-card-scale | 文章卡片缩放比例 | 70% |
--posts-list-scale | 列表缩放比例 | 70% |
--single-cover-scale | 单篇封面高度 | 35% |
--theme-color | 品牌主色 | #f04494 |
--focus-color | 聚焦色 | var(--theme-color) |
--focus-shadow-color | 聚焦阴影色 | rgba(253,83,161,0.4) |
--focus-color-opacity05 | 聚焦色 5% 透明度 | – |
--focus-color-opacity1 | 聚焦色 10% 透明度 | – |
--focus-color-opacity3 | 聚焦色 30% 透明度 | – |
--key-color | 标题级文字 | #333 |
--main-color | 正文主色 | #4e5358 |
--main-shadow | 卡片阴影 | rgba(116,116,116,0.08) |
--muted-color | 次要文字 | #777 |
--muted-2-color | 次要文字 2 | #999 |
--muted-3-color | 次要文字 3 | #b1b1b1 |
--muted-4-color | 次要文字 4 | #d2d2d2 |
--body-bg-color | 页面背景 | #f5f6f7 |
--main-bg-color | 卡片/面板背景 | #fff |
--muted-bg-color | 弱背景 | #eee |
--main-border-color | 主边框 | rgba(50,50,50,0.06) |
--muted-border-color | 弱分隔线 | rgba(0,0,0,0.03) |
--main-radius | 默认圆角 | 8px |
--mini-radius | 小圆角 | calc(var(--main-radius)/1.4) |
--blur-bg | 毛玻璃背景 | rgba(255,255,255,0.8) |
--float-btn-bg | 浮动按钮背景 | rgba(200,200,200,0.4) |
--header-bg | 顶栏背景 | var(--blur-bg) |
--header-color | 顶栏文字色 | var(--main-color) |
--footer-bg | 页脚背景 | var(--main-bg-color) |
--footer-color | 页脚文字色 | var(--muted-2-color) |
暗色覆盖(body.dark-theme): 上述多数变量被覆盖为深色调(--key-color: #f8fafc、--body-bg-color: #292a2d、--main-bg-color: #323335 等)。
暗色模式适配标准写法:
.my-custom-element {
background: var(--main-bg-color);
color: var(--main-color);
border: 1px solid var(--main-border-color);
border-radius: var(--main-radius);
}
/* 不要这样写:
body.dark-theme .my-custom-element { background: #323335; }
直接用 CSS 变量即可自动适配 */暗色模式适配完整示例
/* ✅ 推荐:使用 CSS 变量自动适配 */
.my-card {
background: var(--main-bg-color);
color: var(--main-color);
border: 1px solid var(--main-border-color);
box-shadow: 0 2px 8px var(--main-shadow);
}
.my-card:hover {
background: var(--muted-bg-color);
}
.my-button {
background: var(--theme-color);
color: #fff;
}
/* ❌ 避免:硬编码色值 */
.my-card {
background: #fff; /* 暗色模式下不会变化 */
color: #333;
}
/* ❌ 避免:手动写暗色覆盖(除非必要) */
body.dark-theme .my-card {
background: #323335; /* 与主题变量不同步,易出错 */
}常用场景对照表:
| 场景 | 推荐变量 | 亮色默认值 | 暗色默认值 |
|---|---|---|---|
| 卡片背景 | --main-bg-color | #fff | #323335 |
| 页面背景 | --body-bg-color | #f5f6f7 | #292a2d |
| 主文字色 | --main-color | #4e5358 | #c9ccd0 |
| 标题文字 | --key-color | #333 | #f8fafc |
| 次要文字 | --muted-color | #777 | #999 |
| 边框颜色 | --main-border-color | rgba(50,50,50,0.06) | rgba(255,255,255,0.06) |
| 阴影 | --main-shadow | rgba(116,116,116,0.08) | rgba(0,0,0,0.3) |
文字色 / 强调
- 语义文字色:
.key-color、.focus-color、.muted-color、.muted-2-color、.muted-3-color(依次减弱)。 - 固定调色(含配套
--this-bg背景):.c-theme(跟主色)、.c-gray、.c-white、.c-red/.c-red-2、.c-yellow/.c-yellow-2、.c-blue/.c-blue-2、.c-cyan、.c-green/.c-green-2、.c-purple/.c-purple-2。 - 渐变字:
.cg-theme、.cg-red、.cg-gray等(background-clip: text)。 - 字阶:
.px12、.em12~.em4x、.smail、.font-bold/.font-normal。
背景 / 卡片 / 阴影
.main-bg—background: var(--main-bg-color)。.main-shadow— 轻阴影(可与卡片组合)。.box-bg— 主背景 + 阴影(主题盒子)。.zib-widget— 侧栏模块标准卡片:main-bg、内边距 15px、圆角--main-radius、阴影;附加插件小工具内块可直接套用以统一侧栏。.zib-widget-sm— 小工具无阴影版。.muted-box— 弱灰底圆角块;.muted-box.active时高亮。.noshadow— 去阴影。.blur-bg— 毛玻璃(backdrop-filter+var(--blur-bg))。.blur-5/.blur-10— 元素模糊滤镜。
Flex 与布局
- 容器:
.flex/.inflex(inline-flex)。 - 方向 / 换行:
.flex.xx/.inflex.xx(纵向)、.flex.hh(换行)。 - 对齐:
.flex.ac(交叉轴居中)、.flex.ab(底对齐)、.flex.abl(基线)、.flex.at(顶对齐)、.flex.jc(主轴+交叉轴居中)、.flex.jsb(两端)、.flex.jse、.flex.jsa。 - 间距:
.flex.gap3/.gap6/.gap10/.gap20。 - 子项:
.grow1、.shrink0、.flex0、.flex1、.flex-auto、.flex-auto-h、.ellipsis-box(单行截断辅助)。 - 其它:
.container/.widget-container+.relative;.block/.inline-block;.relative、.relative-h(隐藏溢出);.absolute/.fixed(铺满父级,用于遮罩类);.abs-left、.abs-right、.abs-center(垂直居中锚点)。
间距与圆角
- 外边距:
.mt3.mt6.mt10.mt15.mt20、.mtn6.mtn10;.mb6.mb10.mb15.mb20.mb30.mb40;.mr3.mr6.mr10.mr20.mrn10;.ml3.ml6.ml10.ml20.mln3。 - 内边距:
.padding-6、.padding-h6/.padding-w6、.padding-10、.padding-h10/.padding-h15、.padding-w10/.padding-w15、.p-b6、.padding-lg。 - 圆角:
.radius4、.radius8(使用var(--main-radius))、.radius(大圆角按钮感)。
其它常用
.opacity3/.opacity5/.opacity8;.pointer—cursor: pointer。.border-bottom— 底边线用var(--main-border-color)。.placeholder— 骨架屏占位动画;子类.img.t1.k1等控制尺寸。.obs-animate+.in-view+.ani-slideup等 — 滚动入场动画。- 渐变底(标签/按钮风,用于背景):
.jb-red、.jb-pink、.jb-yellow、.jb-blue、.jb-green、.jb-purple、.jb-cyan、.jb-vip1、.jb-orange等(与订单类型共用)。 - 固定调色文字(用于 color 属性):
.c-red、.c-blue、.c-green、.c-yellow、.c-purple、.c-cyan、.c-gray、.c-white、.c-theme。
主题内置 SVG 图标
主题 CSF 后台和前台均支持 zibsvg-* 系列 SVG 图标(约 50 个),可作为 CSF 字段 icon 选项或前台 <i> 直接使用:
zibsvg-like、zibsvg-view、zibsvg-comment、zibsvg-quick-reply、zibsvg-time、zibsvg-search、zibsvg-money、zibsvg-right、zibsvg-left、zibsvg-reply、zibsvg-circle、zibsvg-close、zibsvg-minus、zibsvg-add、zibsvg-check-circle、zibsvg-handbag、zibsvg-shopping-cart、zibsvg-img-lists、zibsvg-wallet、zibsvg-gift、zibsvg-transit、zibsvg-return、zibsvg-add-ring、zibsvg-post、zibsvg-posts、zibsvg-huo、zibsvg-favorite、zibsvg-manual-service、zibsvg-menu、zibsvg-d-qq、zibsvg-d-weibo、zibsvg-d-wechat、zibsvg-d-email、zibsvg-user、zibsvg-theme、zibsvg-signout、zibsvg-set、zibsvg-signup、zibsvg-user_rp、zibsvg-pan_baidu、zibsvg-lanzou、zibsvg-onedrive、zibsvg-tianyi、zibsvg-menu_2、zibsvg-alipay、zibsvg-baidu、zibsvg-dingtalk、zibsvg-xunlei、zibsvg-123pan、zibsvg-alipan、zibsvg-quark、zibsvg-360yunpan、zibsvg-huawei、zibsvg-xiaomi、zibsvg-gitee
前台用法:<i class="zibsvg-like"></i>
CSF 字段 icon:直接填 zibsvg-like 即可。
插件自定义 CSS 时:能用 var(--*) 与上述 class 则不用新写颜色;若必须新增类,命名加插件前缀,避免覆盖 .zib-widget 等主题全局类。
🚀 高级功能
REST API 扩展(可选)
主题在 inc/functions/rest-api/ 下提供了 REST API 端点,插件可扩展:
// 注册自定义 REST API 端点
add_action('rest_api_init', function() {
register_rest_route('zibll/v1', '/your-endpoint', array(
'methods' => 'GET',
'callback' => 'yourprefix_rest_handler',
'permission_callback' => function() {
return current_user_can('read');
},
));
});
function yourprefix_rest_handler($request) {
// 处理逻辑
return rest_ensure_response(array('data' => 'value'));
}注意:REST API 不依赖 zib_require_end,可在插件初始化时直接注册。
主题 REST API 端点清单
主题在 inc/functions/rest-api/ 下注册了以下常用端点:
| 端点 | 方法 | 用途 | 权限要求 |
|---|---|---|---|
/zibll/v1/user/profile | GET | 获取当前用户资料 | 登录用户 |
/zibll/v1/user/checkin | POST | 用户签到 | 登录用户 |
/zibll/v1/user/balance | GET | 获取用户余额 | 登录用户 |
/zibll/v1/posts/list | GET | 获取文章列表 | 公开 |
/zibll/v1/posts/detail | GET | 获取文章详情 | 公开 |
/zibll/v1/bbs/posts | GET/POST | 论坛帖子列表/发布 | 登录用户(POST) |
/zibll/v1/bbs/categories | GET | 论坛分类列表 | 公开 |
/zibll/v1/shop/products | GET | 商品列表 | 公开 |
/zibll/v1/shop/product | GET | 商品详情 | 公开 |
/zibll/v1/comments | GET/POST | 评论列表/发布 | 登录用户(POST) |
调用示例:
// 获取用户资料
fetch('/wp-json/zibll/v1/user/profile')
.then(res => res.json())
.then(data => console.log(data));
// 用户签到
fetch('/wp-json/zibll/v1/user/checkin', {
method: 'POST',
headers: { 'X-WP-Nonce': _win.nonce }
})
.then(res => res.json());主题模板扩展点
页面模板钩子系统
主题使用自定义的模板加载系统,提供以下扩展点:
用户中心页面
// 在用户中心模板加载前执行
add_action('locate_template_user_center', function() {
// 可在此处进行权限检查或数据准备
});
// 用户中心头部
add_action('user_center_page_header', function() {
echo '<div class="custom-header">自定义头部</div>';
});
// 用户中心内容区
add_action('user_center_page_content', function() {
echo '<div class="custom-content">自定义内容</div>';
});
// 用户中心底部
add_action('user_center_page_footer', function() {
echo '<div class="custom-footer">自定义底部</div>';
});消息中心页面
add_action('locate_template_msg_center', function() {});
add_action('msg_center_page_header', function() {});
add_action('msg_center_page_content', function() {});
add_action('msg_center_page_footer', function() {});BBS论坛页面
// 论坛帖子页顶部/底部
add_action('bbs_posts_page_content_top', function() {
echo '<div class="bbs-custom-top">论坛自定义顶部</div>';
});
add_action('bbs_posts_page_content_bottom', function() {
echo '<div class="bbs-custom-bottom">论坛自定义底部</div>';
});
// BBS其他页面
add_action('bbs_posts_edit_page_header', function() {});
add_action('bbs_posts_edit_page_content', function() {});商城商品页
// 商品页内容之后
add_action('shop_product_page_content_after', function() {
echo '<div class="shop-custom">商品页自定义内容</div>';
});
// 购物车页
add_action('shop_cart_page_content', function() {});插件开发建议:
- 优先使用
do_action钩子而非修改模板文件 - 可通过
locate_template_*钩子完全替换模板 - 参考主题
inc/functions/*/page/目录下的模板结构 - 确保钩子优先级合适,避免与其他插件冲突
主题自定义文章类型
主题注册了多个自定义文章类型(Custom Post Type),插件开发时可能需要与之交互:
| 文章类型 | 标识符 | 用途 | 支持功能 |
|---|---|---|---|
| 商品 | product | 商城商品 | 价格、库存、SKU、分类 |
| 论坛帖子 | bbs_posts | BBS帖子 | 分类、精华、置顶 |
| 订单 | order | 订单记录 | 状态、金额、商品列表 |
| 消息 | message | 私信消息 | 发送者、接收者、状态 |
| 资源 | resource | 下载资源 | 下载次数、积分消耗 |
| 活动 | activity | 活动管理 | 时间、地点、报名 |
查询示例:
// 查询商品列表
$products = new WP_Query(array(
'post_type' => 'product',
'post_status' => 'publish',
'posts_per_page' => 10,
));
// 查询论坛帖子
$posts = new WP_Query(array(
'post_type' => 'bbs_posts',
'meta_key' => 'is_essence',
'meta_value' => 1,
));主题短代码完整清单
主题提供了6个核心短代码,插件开发时应避免名称冲突:
| 短代码 | 参数示例 | 用途 |
|---|---|---|
评论后可见 指定文章ID 展示单篇文章卡片 分类、数量等 文章列表 商品ID 商品展示卡片
// 登录可见
// 密码保护
// 积分可见
// VIP可见
插件注册短代码
function yourprefix_shortcode_demo($atts, $content = null)
{
$atts = shortcode_atts(array(
'title' => '默认标题',
), $atts);
// 注意:短代码必须 return,不能 echo
return '<div class="zib-widget"><h4>' . esc_html($atts['title']) . '</h4></div>';
}
add_shortcode('yourprefix_demo', 'yourprefix_shortcode_demo');插件开发注意:
- 短代码必须在
init钩子后注册 - 使用
do_shortcode()可在PHP中处理短代码 - 避免与主题短代码名称冲突
- 所有输出使用
esc_html()/wp_kses_post()转义
function yourprefix_shortcode_demo($atts, $content = null)
{
$atts = shortcode_atts(array(
'title' => '默认标题',
), $atts);
// 注意:短代码必须 return,不能 echo
return '<div class="zib-widget"><h4>' . esc_html($atts['title']) . '</h4></div>';
}
add_shortcode('yourprefix_demo', 'yourprefix_shortcode_demo');JavaScript国际化(i18n)系统
主题通过 window._win.i18n 对象提供前端文案翻译,包含200+常用字符串。
访问方式
// main.js 中提供的辅助函数
function zib__(key) {
var map = window._win && window._win.i18n;
return map && Object.prototype.hasOwnProperty.call(map, key) ? map[key] : key;
}
// 使用示例
notyf(zib__('processing'), 'load');
console.log(zib__('confirm_delete'));常用i18n键名
| 键名 | 中文 | 用途 |
|---|---|---|
processing | 正在处理请稍后… | AJAX加载中 |
please_wait | 请稍候 | 通用等待提示 |
done | 处理完成 | 操作成功 |
ajax_error | 操作失败 %1$s %2$s | AJAX错误 |
confirm | 确认 | 确认对话框 |
close | 关闭 | 关闭按钮 |
loading | 加载中… | 加载状态 |
uploading | 上传中 | 文件上传 |
comment_reply | 回复 | 评论回复 |
message_all_loaded | 已加载全部 | 消息加载 |
countdown_day | 天 | 倒计时 |
like_thanks | 已赞!感谢您的支持 | 点赞反馈 |
search_loading | 正在搜索,请稍候… | 搜索状态 |
插件扩展i18n
// 在插件中添加自定义i18n字符串
add_filter('zib_js_i18n_strings', function($strings) {
$strings['my_plugin_confirm'] = __('我的插件确认提示', 'my-plugin');
$strings['my_plugin_success'] = __('操作成功', 'my-plugin');
$strings['my_plugin_error'] = __('操作失败', 'my-plugin');
return $strings;
});注意:
- i18n字符串在页脚通过
wp_json_encode()输出 - 支持
JSON_UNESCAPED_UNICODE确保中文正常显示 - 插件应使用自己的textdomain避免冲突
- 完整字符串列表见
inc/functions/zib-js-i18n.php(708行)
主题数据库操作类
主题提供了 zib_db 数据库查询构建器,简化复杂查询:
基本用法
// 简单查询
$db = new zib_db();
$results = $db->table('posts')
->where(['post_status' => 'publish'])
->limit(10)
->get();
// 复杂条件查询
$results = $db->table('posts', 'p')
->join('postmeta', 'pm', 'p.ID = pm.post_id')
->where([
'p.post_status' => 'publish',
'pm.meta_key' => '_thumbnail_id'
])
->select('p.ID, p.post_title, pm.meta_value')
->orderBy('p.post_date', 'DESC')
->limit(10)
->get();
// 插入数据
$db->table('custom_table')->insert([
'name' => 'test',
'value' => 123
]);
// 更新数据
$db->table('custom_table')
->where(['id' => 1])
->update(['value' => 456]);
// 删除数据
$db->table('custom_table')
->where(['id' => 1])
->delete();支持的方法
| 方法 | 说明 | 示例 |
|---|---|---|
table($name, $alias) | 设置表名 | ->table('posts', 'p') |
where($conditions) | WHERE条件 | ->where(['status' => 1]) |
whereIn($field, $values) | IN查询 | ->whereIn('id', [1,2,3]) |
whereBetween($field, $range) | BETWEEN查询 | ->whereBetween('date', ['2024-01-01', '2024-12-31']) |
join($table, $alias, $on) | JOIN连接 | ->join('meta', 'm', 'p.id = m.post_id') |
select($fields) | 选择字段 | ->select('id, name, value') |
orderBy($field, $dir) | 排序 | ->orderBy('date', 'DESC') |
limit($num) | 限制数量 | ->limit(10) |
offset($num) | 偏移量 | ->offset(20) |
group($field) | 分组 | ->group('category') |
having($condition) | HAVING条件 | ->having('COUNT(*) > 5') |
distinct() | 去重 | ->distinct() |
get() | 执行查询 | $results = $db->get() |
insert($data) | 插入数据 | ->insert(['name' => 'test']) |
update($data) | 更新数据 | ->update(['value' => 123]) |
delete() | 删除数据 | ->delete() |
聚合查询方法
| 方法 | 说明 | 示例 |
|---|---|---|
count($field) | 统计数量 | ->count('id') |
sum($field) | 求和 | ->sum('price') |
avg($field) | 平均值 | ->avg('score') |
min($field) | 最小值 | ->min('date') |
max($field) | 最大值 | ->max('date') |
聚合查询示例:
// 获取用户总数
$total = $db->table('users')->count('ID');
// 计算订单总金额
$revenue = $db->table('orders')
->where(['status' => 'completed'])
->sum('amount');
// 获取平均评分
$avg_score = $db->table('posts')->avg('rating');插件开发建议:
- 对于简单查询,仍推荐使用原生
$wpdb - 复杂多表JOIN查询可使用
zib_db构建器 - 注意表前缀自动处理(
$wpdb->prefix) - 所有输入会自动转义,防止SQL注入
- 参考
inc/class/db-class.php(1455行)
主题文件操作类
主题提供 ZibFile 类封装常用文件操作:
常用方法
// 检查文件是否存在(区分大小写)
if (ZibFile::file_exists_case($filename)) {
// 文件存在
}
// 检查路径是否可读/可写
if (ZibFile::path_readable($path)) { }
if (ZibFile::path_writeable($path)) { }
// 获取文件信息
$info = ZibFile::getFileInfo('/path/to/file.jpg');
// 返回: ['name', 'size', 'type', 'mtime', ...]
// 创建目录(递归)
ZibFile::mkdirs('/path/to/new/dir');
// 删除目录(递归)
ZibFile::rmdirs('/path/to/dir');
// 复制文件/目录
ZibFile::copy('/source', '/dest');
// 移动文件/目录
ZibFile::move('/source', '/dest');
// 获取文件扩展名
$ext = ZibFile::getExtension('photo.jpg'); // 返回 'jpg'
// 格式化文件大小
$size = ZibFile::formatSize(1024 * 1024); // 返回 '1 MB'
// 安全写入文件
ZibFile::writeFile('/path/to/file.txt', $content);
// 读取文件内容
$content = ZibFile::readFile('/path/to/file.txt');插件开发建议:
- 优先使用
ZibFile而非原生PHP文件函数 - 自动处理权限检查和错误处理
- 支持中文文件名和特殊字符
- 所有路径操作都经过安全检查
- 参考
inc/class/file-class.php(1588行)
主题工具类
短信验证码类 ZibSMS
支持阿里云、腾讯云、短信宝等多个服务商:
// 发送短信验证码
$result = ZibSMS::send('13800138000', '123456', 'ali');
// 返回: ['error' => 0, 'msg' => '发送成功'] 或 ['error' => 1, 'msg' => '错误信息']
// 验证手机号格式
if (ZibSMS::is_phonenumber('13800138000')) {
// 格式正确
}支持的短信服务商:
ali- 阿里云短信tencent- 腾讯云短信smsbao- 短信宝fcykj- 飞鱼云科技
二维码生成类 QRcode
基于 PHP QR Code 库:
// 生成二维码图片
QRcode::png('https://example.com', $outfile = false, $level = QR_ECLEVEL_L, $size = 4);
// 生成二维码SVG
QRcode::svg('https://example.com', $outfile = false);
// 参数说明:
// - $text: 二维码内容
// - $outfile: 输出文件路径,false则直接输出
// - $level: 纠错级别(L/M/Q/H)
// - $size: 像素大小邮件发送函数
主题提供统一的邮件发送接口:
// 发送邮件(封装wp_mail)
zib_send_mail($to, $subject, $message, $headers = array());
// 发送HTML邮件
zib_send_html_mail($to, $subject, $html_content);插件开发建议:
- 短信功能需先在主题后台配置API密钥
- 二维码生成无需额外依赖
- 邮件发送遵循WordPress标准,可被SMTP插件拦截
- 参考
inc/class/sms-class.php和inc/class/qrcode.class.php
主题侧边栏系统
主题提供了极其丰富的侧边栏(Widget Area)注册系统,支持在不同页面位置显示小工具。
主侧边栏区域
主题在 inc/widgets/widget-index.php 中注册了以下主要侧边栏:
全局侧边栏
| ID | 名称 | 说明 |
|---|---|---|
all_top_fluid | 所有页面-顶部全宽度 | 首页、分类页、标签页等顶部 |
all_bottom_fluid | 所有页面-底部全宽度 | 首页、分类页、标签页等底部 |
all_sidebar_top | 所有页面-侧边栏-顶部 | 侧边栏顶部位置 |
all_sidebar_bottom | 所有页面-侧边栏-底部 | 侧边栏底部位置 |
all_footer | 底部脚区内部 | 页脚区域内部 |
mobile_nav_fluid | 移动端-弹出菜单底部 | 移动端菜单下方 |
按页面类型划分的侧边栏
支持的页面类型:
home- 首页single- 文章页cat- 分类页tag- 标签页search- 搜索页author- 作者页user- 用户中心msg- 消息中心
每个页面类型支持的位置:
top_fluid- 顶部全宽度top_content- 主内容上面bottom_content- 主内容下面bottom_fluid- 底部全宽度sidebar- 侧边栏
示例ID:
home_top_fluid- 首页顶部全宽度single_sidebar- 文章页侧边栏cat_bottom_content- 分类页主内容下面user_top_content- 用户中心内容区上面
特殊页面侧边栏
// 前台投稿页面
'newposts_sidebar_top' // 前台投稿-侧边栏顶部
'newposts_sidebar_bottom' // 前台投稿-侧边栏底部
// 动态页面侧边栏(根据页面设置生成)
'page_top_fluid_123' // [页面:XXX]-顶部全宽度
'page_sidebar_123' // [页面:XXX]-侧边栏BBS论坛侧边栏
论坛模块在 inc/functions/bbs/widgets/widgets.php 中注册额外侧边栏:
// 论坛相关侧边栏ID示例
'bbs_plate_sidebar' // 版块侧边栏
'bbs_posts_sidebar' // 帖子页侧边栏商城侧边栏
商城模块在 inc/functions/shop/widgets/widgets.php 中注册:
// 商城相关侧边栏ID示例
'shop_product_sidebar' // 商品页侧边栏
'shop_cart_sidebar' // 购物车侧边栏插件开发建议
1. 使用现有侧边栏
// 在你的插件中,可以直接向已有侧边栏添加小工具
add_action('widgets_init', function() {
// 注册自定义小工具到特定侧边栏
register_widget('YourPrefix_Custom_Widget');
});2.检查侧边栏是否存在
if (is_active_sidebar('home_top_fluid')) {
dynamic_sidebar('home_top_fluid');
}3.创建自定义侧边栏
add_action('widgets_init', function() {
register_sidebar(array(
'name' => __('我的插件侧边栏', 'my-plugin'),
'id' => 'my_plugin_sidebar',
'description' => __('我的插件专用侧边栏', 'my-plugin'),
'before_widget' => '<div class="zib-widget %2$s">',
'after_widget' => '</div>',
'before_title' => '<h3>',
'after_title' => '</h3>',
));
});4. 注意事项
- 命名规范: 侧边栏ID使用小写字母和下划线
- 前缀: 自定义侧边栏建议加插件前缀避免冲突
- CSS类: 主题自动为widget添加
.zib-widget类 - 预览模式: 主题在自定义预览时会添加编辑按钮
- fluid区域: ID包含
fluid的侧边栏会自动包裹在.fluid-widget-wrap中
参考文件:
inc/widgets/widget-index.php- 主侧边栏注册 (439行)inc/functions/bbs/widgets/widgets.php- BBS侧边栏inc/functions/shop/widgets/widgets.php- 商城侧边栏footer.php- 页脚侧边栏调用示例
主题选项获取函数 _pz()
主题提供统一的选项获取函数 _pz(),用于读取主题后台设置。
基本用法
// 简单获取选项值
$value = _pz('option_name');
// 带默认值
$value = _pz('option_name', 'default_value');
// 获取嵌套数组的子项
$subvalue = _pz('parent_option', false, 'child_key');参数说明
/**
* @param string $name 选项的名称
* @param mixed $default 如果未找到选项,则返回的默认值
* @param string $subname (可选)如果选项是嵌套数组,则为选项的子名称
* @return mixed 选项的值,如果未找到则返回默认值
*/
function _pz($name, $default = false, $subname = '')常用选项示例
// 检查功能是否启用
if (_pz('pay_balance_s')) {
// 余额功能已启用
}
// 获取配置值(带默认值)
$cache_ttl = _pz('cache_time', 3600);
// 获取嵌套配置
$wechat_config = _pz('oauth_weixin', false, 'appid');性能优化
_pz() 函数内部使用 静态变量缓存,首次调用后会将所有选项缓存在内存中,后续调用直接从缓存读取,无需重复查询数据库:
function _pz($name, $default = false, $subname = '')
{
static $options = null;
if ($options === null) {
$options = get_option('zibll_options'); // 只执行一次
}
if (isset($options[$name])) {
if ($subname) {
return isset($options[$name][$subname]) ? $options[$name][$subname] : $default;
} else {
return $options[$name];
}
}
return $default;
}单独设置选项
如需单独修改某个选项,可使用 _spz() 函数:
// 更新单个选项
_spz('option_name', 'new_value');插件开发建议
- ✅ 优先使用
_pz()而非直接get_option('zibll_options') - ✅ 利用缓存机制,多次调用无性能损失
- ✅ 始终提供默认值,确保代码健壮性
- ❌ 避免直接修改
$options数组 - ⚠️ 注意选项名称,参考主题
inc/options/admin-options.php(660KB)
参考文件:
inc/dependent.php:112-_pz()函数定义inc/dependent.php:131-_spz()函数定义inc/options/admin-options.php- 所有可用选项清单
主题缓存系统
主题广泛使用 WordPress Cache API 进行性能优化,插件开发时应遵循相同的缓存策略。
缓存API使用
// 获取缓存
$cache = wp_cache_get($key, $group, $force);
// 设置缓存
wp_cache_set($key, $data, $group, $expire);
// 删除缓存
wp_cache_delete($key, $group);
// 刷新所有缓存
wp_cache_flush();主题缓存实践
1. 用户头像缓存
// 获取头像(带缓存)
function zib_get_data_avatar($user_id = '', $size = '', $alt = '')
{
$cache = wp_cache_get($user_id, 'user_avatar', true);
if (false === $cache) {
$avatar = zib_get_avatar(null, $user_id, $args);
wp_cache_set($user_id, $avatar, 'user_avatar');
} else {
$avatar = $cache;
}
return $avatar;
}
// 更新头像时清除缓存
add_action('user_save_custom_avatar', function ($user_id) {
wp_cache_delete($user_id, 'user_avatar');
zib_get_data_avatar($user_id);
}, 10);2.统计数据缓存
// 获取用户评论数(带缓存)
function get_user_comment_count($user_id, $comments_status = 'approve', $cut = true)
{
$cache_num = wp_cache_get($user_id, 'user_comment_' . $comments_status . '_count', true);
if (false === $cache_num) {
$args = array(
'user_id' => $user_id,
'status' => $comments_status,
'count' => true,
'post_type' => ['post'],
);
$count = get_comments($args);
wp_cache_set($user_id, $count, 'user_comment_' . $comments_status . '_count');
} else {
$count = $cache_num;
}
return $cut ? _cut_count($count) : (int) $count;
}
// 评论状态变化时清除缓存
add_action('transition_comment_status', 'zib_comment_del_cache_status', 10, 3);
add_action('comment_post', 'zib_comment_del_cache', 10);3.Transient缓存(长期缓存)
// SVG图标精灵缓存(24小时)
function zib_output_svg_sprite() {
$cache_key = 'zib_svg_sprite_v1';
$svg_sprite = get_transient($cache_key);
if ($svg_sprite === false) {
// 生成SVG内容...
set_transient($cache_key, $svg_sprite, 24 * HOUR_IN_SECONDS);
}
echo $svg_sprite;
}插件缓存最佳实践
推荐模式
function myplugin_get_expensive_data($id)
{
$cache_key = 'myplugin_data_' . $id;
$cache_group = 'myplugin';
// 尝试从缓存获取
$data = wp_cache_get($cache_key, $cache_group);
if (false === $data) {
// 缓存未命中,执行耗时操作
$data = expensive_database_query($id);
// 存入缓存(有效期1小时)
wp_cache_set($cache_key, $data, $cache_group, 3600);
}
return $data;
}
// 数据更新时清除缓存
add_action('myplugin_data_updated', function($id) {
wp_cache_delete('myplugin_data_' . $id, 'myplugin');
});主题缓存辅助函数
主题在 func.php 中提供了便捷的缓存函数,封装了 wp_cache_* 系列函数并添加了自动重建机制:
// 获取缓存(带自动重建机制)
zib_cache_get($key, $group, $callback, $expire = 0);
// 设置缓存
zib_cache_set($key, $value, $group, $expire = 0);
// 删除缓存
zib_cache_delete($key, $group);
// 清除整个缓存组
zib_cache_flush_group($group);使用示例:
// 获取或创建缓存(不存在时自动执行回调)
$result = zib_cache_get('my_plugin_data', 'my_plugin', function() {
return expensive_query();
}, 3600);
// 设置缓存(有效期1小时)
zib_cache_set('my_plugin_result', $data, 'my_plugin', 3600);
// 删除指定缓存
zib_cache_delete('my_plugin_data', 'my_plugin');
// 清除整个缓存组
zib_cache_flush_group('my_plugin');缓存组建议
| 缓存组 | 用途 | 过期时间 |
|---|---|---|
myplugin | 插件通用缓存 | 按需设置 |
user_avatar | 用户头像 | 永久(更新时清除) |
page_url | 模板页面URL | 永久 |
zib_cache_group | 主题通用缓存 | 按需设置 |
注意事项
- ✅ 使用有意义的缓存键名,避免冲突
- ✅ 设置合理的过期时间,平衡性能和数据新鲜度
- ✅ 在数据更新时及时清除缓存
- ✅ 使用缓存组隔离不同模块的数据
- ⚠️ Redis/Object Cache环境下,
wp_cache_*函数会使用Redis - ⚠️ Transients适合长期缓存,存储在
wp_options表中
参考文件:
func.php:725-760- 主题缓存辅助函数inc/functions/zib-theme.php:579-605- 头像缓存示例inc/functions/zib-comments-list.php:686-709- 评论统计缓存inc/functions/bbs/inc/moderator.php:48-91- BBS版主缓存
Meilisearch 全文搜索引擎
主题集成了 Meilisearch 高性能搜索引擎(需单独部署Meilisearch服务):
基本用法
use Zib\Meilisearch\Client;
// 创建客户端
$client = new Client('http://localhost:7700', 'masterKey');
// 获取索引
$index = $client->index('posts');
// 添加文档
$index->addDocuments([
['id' => 1, 'title' => '文章标题', 'content' => '文章内容'],
]);
// 搜索
$results = $index->search('关键词', [
'limit' => 20,
'filter' => 'post_status = publish',
]);
// 删除文档
$index->deleteDocument(1);
// 清空索引
$index->deleteAllDocuments();插件开发注意:
- Meilisearch是外部服务,需在服务器单独部署
- 适合大型网站替代WordPress默认搜索
- 需要配置索引同步任务
- 参考主题
inc/functions/ai/目录下的AI搜索集成 - 参考
inc/class/meilisearch-class.php(383行)
主题更新通知挂钩
插件可通过以下钩子在主题更新/新装时展示自己的运营提示:
// 主题更新时显示插件提示
add_action('zibll_update_notices', function ($version) {
?>
<div class="notice notice-info">
<p><?php printf(__('你的插件 v%s 已就绪,请查看 %s设置页%s。', 'your-textdomain'),
YOURPLUGIN_VERSION,
'<a href="' . admin_url('admin.php?page=yourplugin_options') . '">',
'</a>'
); ?></p>
</div>
<?php
});
// 主题新安装时显示
add_action('zibll_new_install_notices', function ($version) {
// 同上格式
});主题升级任务机制
主题 inc/options/upgrade.php 内有 zib_update_theme_tasks_X_Y() 系列(X.Y 为目标版本号),在新版安装/升级时自动调用。插件可参考此机制做自己的版本迁移:
// 在插件激活或特定版本时执行升级任务
function yourprefix_upgrade_to_1_1()
{
// 数据迁移、建表等
}
register_activation_hook(__FILE__, function () {
$version = get_option('yourprefix_version', '0.0.0');
if (version_compare($version, '1.1.0', '<')) {
yourprefix_upgrade_to_1_1();
update_option('yourprefix_version', '1.1.0');
}
});钩子与调试习惯
- 主题专有能力与扩展点见上文 「主题 PHP API 速查」;以下为通用习惯。
- 善用
do_action、apply_filters、add_action、add_filter;主题与 WordPress 核心钩子均可结合使用。 - 改写页面展示不必仅限 PHP,可按需配合前端 JS。
- 注意钩子优先级与性能:重逻辑加
is_admin()、wp_doing_ajax()等守卫。 - 全局搜索主题内
do_action/apply_filters找扩展点。
进阶优化建议
🛠️ 最佳实践与优化
1. CSF 字段类型兼容性白名单
根据实际插件开发经验,并非所有 CSF 字段类型在子比主题环境中都稳定可用。建议优先使用以下经过验证的字段类型:
| 字段类型 | 推荐使用 | 注意事项 |
|---|---|---|
text | ✅ | 基础文本输入,兼容性最佳 |
textarea | ✅ | 多行文本输入 |
select | ✅ | 下拉选择框 |
radio | ✅ | 单选按钮组 |
checkbox | ✅ | 复选框(推荐替代 switcher) |
number | ✅ | 数字输入框 |
color | ✅ | 颜色选择器 |
upload | ✅ | 文件上传 |
icon | ✅ | 图标选择器 |
switcher | ✅ | 开关控件,主题内大量使用且稳定 |
button_set | ✅ | 按钮组选择,主题广泛用于后台设置 |
spinner | ✅ | 数字步进器,带单位显示 |
submessage | ✅ | 提示信息块,用于分组说明 |
notice | ✅ | 通知提示框,支持 success/warning/danger/info |
repeater | ✅ | 重复字段组,适合列表型配置 |
group | ✅ | 字段组,可折叠 |
accordion | ✅ | 手风琴折叠面板 |
background | ✅ | 背景设置(颜色+图片) |
icon | ✅ | 图标选择器(支持 Font Awesome + zibsvg) |
gallery | ✅ | 图库选择 |
palette | ✅ | 调色板 |
code_editor | ✅ | 代码编辑器(CodeMirror) |
image_select | ⚠️ | 图片选择,需确保图片 URL 有效 |
使用示例(推荐方式):
// 使用 switcher(主题内广泛使用,稳定可靠)
array(
'id' => 'enabled',
'type' => 'switcher',
'title' => __('启用功能', 'your-textdomain'),
'default' => true,
),
// 或使用 checkbox(兼容性最佳)
array(
'id' => 'enabled_alt',
'type' => 'checkbox',
'title' => __('启用功能(备选)', 'your-textdomain'),
'default' => '1', // 字符串 '1'/'0' 而非布尔值
),2. AJAX 安全标准增强
参考 zibll-user 等插件的实际实现,AJAX 处理器应包含完整的安全校验:
function yourprefix_ajax_handler() {
// 1. 权限检查(优先)
if (!current_user_can('edit_posts')) {
wp_send_json_error(array('msg' => '权限不足'), 403);
}
// 2. Nonce 验证
check_ajax_referer('yourprefix_nonce', 'nonce');
// 3. 参数验证
if (!isset($_POST['data']) || empty($_POST['data'])) {
wp_send_json_error(array('msg' => '参数错误'), 400);
}
// 4. 参数清理
$data = sanitize_text_field(wp_unslash($_POST['data']));
// 5. 业务逻辑
try {
$result = yourprefix_process_data($data);
wp_send_json_success(array('result' => $result));
} catch (Exception $e) {
wp_send_json_error(array('msg' => '处理失败'), 500);
}
}
// 注册钩子(仅登录用户访问)
add_action('wp_ajax_yourprefix_action', 'yourprefix_ajax_handler');
// add_action('wp_ajax_nopriv_yourprefix_action', 'yourprefix_ajax_handler'); // 公开接口取消注释3. 主题函数兼容性封装
ZibPay 核心函数清单
| 函数 | 文件 | 用途 |
|---|---|---|
zibpay_get_user_balance($user_id) | zibpay-balance.php | 获取用户余额 |
zibpay_update_user_balance($user_id, $data) | zibpay-balance.php | 更新用户余额(推荐) |
zibpay_get_user_points($user_id) | zibpay-points.php | 获取用户积分 |
zibpay_update_user_points($user_id, $data) | zibpay-points.php | 更新用户积分 |
zibpay_is_paid($post_id, $user_id) | zibpay-ajax.php | 检查是否已购买 |
zibpay_get_post_paid_data_by_user($post_id, $user_id) | zibpay-ajax.php | 获取付费详情 |
更新余额/积分的数据格式:
$data = array(
'value' => 100, // 变动值(正数增加,负数减少)
'type' => 'manual_add', // 变动类型标识
'desc' => '手动增加余额', // 变动描述
);
zibpay_update_user_balance($user_id, $data);⚠️ 重要:切勿直接操作 user_meta 中的 balance 或 points,必须通过上述函数以保证日志记录和事务一致性。
对于余额、积分等主题核心功能,必须使用 function_exists 做兼容性检查:
/**
* 获取用户余额(带兼容性封装)
*/
function yourprefix_get_user_balance($user_id) {
if (function_exists('zibpay_get_user_balance')) {
return zibpay_get_user_balance($user_id);
}
// Fallback:直接读取 meta(不推荐,仅作最后兜底)
$balance = get_user_meta($user_id, 'balance', true);
return floatval($balance);
}
/**
* 更新用户余额(必须走主题统一接口)
*/
function yourprefix_update_user_balance($user_id, $amount, $type = 'add', $desc = '') {
if (!function_exists('zibpay_update_user_balance')) {
yourprefix_log_error('zibpay_update_user_balance 函数不存在');
return false;
}
$data = array(
'value' => $type === 'add' ? $amount : -$amount,
'type' => $desc,
'desc' => $desc,
);
return zibpay_update_user_balance($user_id, $data);
}4. CSF 菜单结构规范
创建多级菜单时,parent 必须使用 section id 而非显示标题:
// 正确:使用 section id 作为 parent
CSF::createSection($options_key, array(
'id' => 'parent_section',
'title' => '父级设置',
'icon' => 'fa fa-folder',
// 父 section 不包含 fields,仅作为容器
));
CSF::createSection($options_key, array(
'id' => 'child_section',
'title' => '子级设置',
'parent' => 'parent_section', // 使用 id,不是 '父级设置'
'fields' => array(
// 字段定义
),
));5. 调试工具与错误处理
WordPress 调试配置
在 wp-config.php 中启用调试:
// 启用调试模式
define('WP_DEBUG', true);
// 记录错误到日志文件
define('WP_DEBUG_LOG', true); // 日志位置:wp-content/debug.log
// 不在页面显示错误(生产环境建议 false)
define('WP_DEBUG_DISPLAY', false);
// 保存数据库查询(性能调试)
define('SAVEQUERIES', true);主题特定调试:
- 主题错误日志:
wp-content/debug.log - zibll 广告调试:
wp-content/zibll-ad-debug.log - 临时文件目录:
wp-content/zib-temp/
添加统一的日志记录和调试函数:
/**
* 记录错误日志
*/
function yourprefix_log_error($message, $data = array()) {
if (WP_DEBUG) {
$log_data = !empty($data) ? ' | Data: ' . print_r($data, true) : '';
error_log('[YourPlugin] ' . $message . $log_data);
}
}
/**
* 调试输出(仅开发环境)
*/
function yourprefix_debug($data, $label = '') {
if (!WP_DEBUG || !is_admin()) return;
$label = $label ? "<strong>$label:</strong><br>" : '';
echo "<pre style='background:#fff; padding:10px; border:1px solid #ccc; margin:10px;'>";
echo $label;
var_dump($data);
echo "</pre>";
}
/**
* 安全的选项读取(带默认值)
*/
function yourprefix_get_option($key, $default = false) {
static $options = null;
// 开发环境不缓存,便于调试
if (WP_DEBUG) {
$options = get_option('yourplugin_options');
return isset($options[$key]) ? $options[$key] : $default;
}
if ($options === null) {
$options = get_option('yourplugin_options');
}
return isset($options[$key]) ? $options[$key] : $default;
}6. 性能优化:缓存机制
参考主题 _pz() 函数的静态缓存模式,并结合 WP 缓存 API:
/**
* 获取选项(带多层缓存)
*/
function yourprefix_get_option($key, $default = false) {
$cache_key = 'yourplugin_option_' . $key;
// 尝试从 WP 缓存获取
if (function_exists('wp_cache_get')) {
$cached = wp_cache_get($cache_key, 'yourplugin');
if ($cached !== false) {
return $cached;
}
}
// 静态缓存作为备选
static $options = null;
if ($options === null) {
$options = get_option('yourplugin_options', array());
}
$value = isset($options[$key]) ? $options[$key] : $default;
// 设置 WP 缓存(有效期5分钟)
if (function_exists('wp_cache_set')) {
wp_cache_set($cache_key, $value, 'yourplugin', 300);
}
return $value;
}
/**
* 更新选项(同时清理缓存)
*/
function yourprefix_update_option($key, $value) {
$options = get_option('yourplugin_options', array());
$options[$key] = $value;
update_option('yourplugin_options', $options);
// 清理相关缓存
if (function_exists('wp_cache_delete')) {
wp_cache_delete('yourplugin_option_' . $key, 'yourplugin');
wp_cache_delete('yourplugin_options', 'yourplugin');
}
}7. 数据库查询优化
参考主题查询优化策略,使用高效的 WP_Query 参数:
/**
* 获取帖子列表(优化版)
*/
function yourprefix_get_posts($args = array()) {
$defaults = array(
'post_type' => 'post',
'post_status' => 'publish',
'posts_per_page' => 10,
'no_found_rows' => true, // 不需要总条数时设置为true
'update_post_term_cache' => false, // 不需要分类缓存时关闭
'update_post_meta_cache' => false, // 不需要meta缓存时关闭
'ignore_sticky_posts' => true,
'fields' => 'ids', // 只需要ID时使用
);
$args = wp_parse_args($args, $defaults);
$query = new WP_Query($args);
return $query->posts;
}8. 安全增强:输出转义规范
参考主题的转义实践,确保所有输出都经过正确转义:
| 场景 | 推荐函数 | 示例 |
|---|---|---|
| HTML内容 | esc_html() | echo esc_html($text); |
| HTML属性 | esc_attr() | <div class="<?php echo esc_attr($class); ?>"> |
| URL | esc_url() | <a href="<?php echo esc_url($url); ?>"> |
| JavaScript | esc_js() | var data = '<?php echo esc_js($data); ?>'; |
| 富文本内容 | wp_kses_post() | echo wp_kses_post($content); |
| SQL查询 | esc_sql() | $search = esc_sql($search); |
完整示例:
function yourprefix_render_post($post) {
if (!is_object($post)) return;
?>
<article id="post-<?php echo esc_attr($post->ID); ?>" class="post-card">
<h2><a href="<?php echo esc_url(get_permalink($post->ID)); ?>">
<?php echo esc_html(get_the_title($post->ID)); ?>
</a></h2>
<div class="post-content">
<?php echo wp_kses_post(get_the_content($post->ID)); ?>
</div>
<script>
var postData = {
id: <?php echo absint($post->ID); ?>,
title: '<?php echo esc_js(get_the_title($post->ID)); ?>'
};
</script>
</article>
<?php
}9. 权限检查最佳实践
主题统一权限判断函数
主题提供了统一的权限判断入口 zib_current_user_can(),支持多种能力类型:
/**
* 检查当前用户是否具有指定能力
*
* @param string $capability 能力名称
* @param mixed ...$args 额外参数(某些能力需要)
* @return bool
*/
function zib_current_user_can($capability, ...$args)
// 常用能力示例:
if (zib_current_user_can('new_post_add')) { /* 能否发布文章 */ }
if (zib_current_user_can('comment_view', $post)) { /* 能否查看评论 */ }
if (zib_current_user_can('view_order', $order)) { /* 能否查看订单 */ }
if (zib_current_user_can('order_close', $order)) { /* 能否关闭订单 */ }能力配置位置:主题后台 → 用户中心 → 权限设置,可自定义各角色对应的能力。
常用能力清单
| 能力名称 | 用途 | 需要对象参数 |
|---|---|---|
new_post_add | 能否发布文章 | 否 |
new_post_edit | 能否编辑文章 | 是($post) |
new_post_delete | 能否删除文章 | 是($post) |
comment_view | 能否查看评论 | 是($post) |
comment_edit | 能否编辑评论 | 是($comment) |
comment_delete | 能否删除评论 | 是($comment) |
view_order | 能否查看订单 | 是($order) |
order_close | 能否关闭订单 | 是($order) |
shop_product_add | 能否添加商品 | 否 |
shop_product_edit | 能否编辑商品 | 是($product) |
bbs_posts_add | 能否发布论坛帖子 | 否 |
bbs_posts_edit | 能否编辑论坛帖子 | 是($post) |
bbs_posts_essence | 能否设精华帖 | 是($post) |
bbs_posts_topping | 能否置顶帖子 | 是($post) |
user_ban | 能否封禁用户 | 是($user) |
user_auth | 能否审核认证 | 否 |
插件开发建议:
- 优先使用
zib_current_user_can()而非原生current_user_can(),因为它集成了主题的 VIP、等级、认证等扩展判断 - 对于主题特有的能力(如商城、论坛相关),必须使用此函数
- 通用 WordPress 能力(如
edit_posts)仍可使用原生函数
参考主题 zib_current_user_can() 的封装模式:
/**
* 检查用户权限(带日志记录)
*/
function yourprefix_current_user_can($capability, $object = null) {
// 管理员拥有所有权限
if (current_user_can('administrator')) {
return true;
}
// 检查标准权限
if (current_user_can($capability)) {
return true;
}
// 对象级权限检查(如订单、帖子等)
if ($object && is_object($object)) {
// 检查对象所有者
if (isset($object->user_id) && $object->user_id == get_current_user_id()) {
return true;
}
}
yourprefix_log_error('权限检查失败', array(
'capability' => $capability,
'user_id' => get_current_user_id()
));
return false;
}
/**
* AJAX权限检查快捷函数
*/
function yourprefix_check_ajax_permission($capability = 'edit_posts') {
if (!is_user_logged_in()) {
wp_send_json_error(array('msg' => '请先登录'), 401);
}
if (!current_user_can($capability)) {
wp_send_json_error(array('msg' => '权限不足'), 403);
}
}8. 代码组织与架构优化
参考主题的模块化架构,建议的插件目录结构:
your-plugin/
├── your-plugin.php # 入口文件(依赖检测 + 自动加载)
├── inc/
│ ├── core/
│ │ ├── bootstrap.php # 初始化与依赖检测
│ │ ├── hooks.php # 钩子注册中心
│ │ └── autoloader.php # 自动加载器
│ ├── admin/
│ │ ├── options.php # CSF 后台选项
│ │ ├── menus.php # 后台菜单注册
│ │ └── notices.php # 后台通知
│ ├── frontend/
│ │ ├── shortcodes.php # 短代码注册
│ │ ├── widgets.php # 小工具
│ │ └── templates.php # 模板函数
│ ├── ajax/
│ │ ├── handlers.php # AJAX 处理器
│ │ └── endpoints.php # REST API 端点
│ └── utils/
│ ├── validators.php # 验证工具
│ ├── sanitizers.php # 清理工具
│ └── helpers.php # 辅助函数
├── assets/
│ ├── css/
│ │ ├── frontend.css # 前台样式
│ │ └── admin.css # 后台样式
│ ├── js/
│ │ ├── frontend.js # 前台脚本
│ │ └── admin.js # 后台脚本
│ └── images/ # 图片资源
├── languages/ # 语言包
│ └── your-plugin-zh_CN.mo/po
├── templates/ # 模板文件(可选)
└── README.md # 说明文档✅ 自检清单
在发布插件前,请确保完成以下检查:
- [ ] 主题依赖:主题非 zibll 时已
return且不调用主题 API - [ ] CSF 钩子:CSF /
CSF_Widget仅出现在zib_require_end回调内 - [ ] 命名唯一性:
options_key、widget key、函数前缀全局唯一 - [ ] 小工具一致性:小工具输出函数名与
CSF::createWidget第一个参数一致 - [ ] 安全转义:对外输出已转义,权限与 nonce 按业务补齐
- [ ] AJAX 安全:接口已注册 nonce 验证 + 权限检查;公开接口同时注册
nopriv钩子 - [ ] JS 异步加载:前台 JS 使用
_win/zib_ajax/notyf前已处理异步加载或存在性判断 - [ ] CSS 复用:插件前台 HTML 优先使用
main.css工具类与 CSS 变量,避免与主题视觉脱节 - [ ] CSS 命名空间:插件自定义 CSS 类名带插件前缀,不覆盖主题全局类(
.zib-widget等) - [ ] 暗色模式适配:使用
var(--*)变量引用,不硬编码#fff/#333等色值 - [ ] jQuery 依赖:声明正确,不假设 WP 默认 jQuery 路径
- [ ] CSS 加载顺序:依赖
main确保在主题样式之后 - [ ] 版本管理:插件版本号、介绍、更新日志同步更新
- [ ] 函数存在性检查:使用
function_exists检查主题函数后再调用 - [ ] ZibPay 统一接口:余额/积分变更走主题统一更新接口(如
zibpay_update_user_balance)
📖 参考资源
核心文件路径
| 类型 | 路径 | 说明 |
|---|---|---|
| CSF 框架(活跃) | inc/csf-framework/ | 当前使用的 CSF 版本 |
| CSF 框架(旧版) | inc/codestar-framework/ | 旧版兼容 |
| CSF 选项示例 | inc/options/admin-options.php | 660KB,完整字段示例 |
| CSF Widget 类 | inc/csf-framework/classes/widget-options.class.php | Widget 基类 |
| Zib_CFSwidget | inc/widgets/widget-class.php | 兼容壳 |
| 小工具示例 | inc/widgets/widget-more.php | 参考实现 |
| 主题加载结束 | inc/inc.php:126 | do_action('zib_require_end') |
| _win 注入 | inc/functions/zib-footer.php:65-110 | 全局 JS 对象 |
| 前台脚本注册 | inc/functions/zib-theme.php:1044-1093 | _load_scripts / _jsloader / _cssloader |
| 主题主逻辑 | js/main.js | 与 js/loader.js 配合 |
| 前台全局样式 | css/main.css | 14736 行,线上为 main.min.css |
| 主题选项实现 | inc/dependent.php | _pz / _spz 函数定义 |
| 主题选项注册 | inc/options/options.php | 选项配置入口 |
| 主题升级任务 | inc/options/upgrade.php | 版本迁移逻辑 |
| 用户系统 | inc/functions/user/ | 用户相关功能 |
| UI 组件函数 | inc/functions/functions.php | 通用 UI 函数 |
| ZibPay 函数 | zibpay/functions/ | 付费系统核心 |













暂无评论内容