给 Zibll 商业主题写子主题,最容易犯的错不是不会写代码,而是改错了地方——改了父主题文件,下次更新全没了;或者写了看似正确、但运行起来毫无反应的代码。
这篇总结我在实际项目中踩过的坑,每个都有可复现的现象和确认过的原因。
一、子主题的基本结构
Zibll 的子主题只需要三个文件就能跑起来:
my-child/
├── style.css # 声明 Template: zibll
└── functions.php # 挂钩子
/*
Template: zibll
Version: 9.1
*/
⚠️ Version 必须写父主题版本号,不是子主题版本。写错的后果:后台会提示「可更新到 V9.1」,一键更新会覆盖父主题。
二、钩子的执行时机:为什么你的代码不生效
Zibll 的大量函数在 zib_require_end 之后才可用。如果你在 after_setup_theme 里直接调用它们,会得到「函数不存在」或者静默失败。
// ❌ 错误:此时父主题函数还没加载
add_action('after_setup_theme', function () {
zib_get_user_level(1); // 可能 fatal
});
// ✅ 正确:等父主题加载完
add_action('zib_require_end', function () {
zib_get_user_level(1);
});
三、资源文件路径的陷阱
子主题里用 get_theme_file_uri() 时,如果不传参,返回的是父主题目录,不是子主题。拼路径会 404。
// ❌ 拼出来是 zibll/xxx.js
wp_enqueue_script('x', get_theme_file_uri() . '/js/x.js');
// ✅ 传参,会自动回退:先找子主题,找不到再找父主题
wp_enqueue_script('x', get_theme_file_uri('js/x.js'));
四、修改模板的正确方式
Zibll 用 locate_template() 定位模板文件。要在子主题覆盖,路径必须完全一致:
父主题:zibll/inc/template/single-post.php
子主题:my-child/inc/template/single-post.php ✅ 同名同路径即覆盖
实测有效的排查方法:在父主题模板里临时加一行 echo __FILE__;,看实际加载的是哪个文件。
五、最危险的一类问题:静默失败
比起报错,更难查的是不报错但没效果。典型场景:
- 钩子名拼错(
zib_posts_content_after写成zib_post_content_after) - 优先级不对(代码在目标渲染之后才执行)
function_exists()检查恒假(函数名大小写或命名空间不符)
验证方式永远是在钩子回调里打点:
add_action('zib_posts_content_after', function () {
error_log('[MY-CHILD] hook fired'); // 看日志有没有这行
});
附:完整源码 —— 阅读进度条
<?php
/**
* 阅读进度条(子主题 functions.php 直接可用)
*/
add_action('wp_footer', function () {
if (!is_singular('post')) {
return;
}
?>
<div id="reading-progress"></div>
<style>
#reading-progress {
position: fixed;
top: 0; left: 0;
height: 3px;
width: 0;
background: var(--theme-color, #f04494);
z-index: 9999;
transition: width .1s linear;
}
</style>
<script>
(function () {
var bar = document.getElementById('reading-progress');
if (!bar) return;
function update() {
var h = document.documentElement.scrollHeight - window.innerHeight;
if (h <= 0) return;
var p = (window.pageYOffset / h) * 100;
bar.style.width = Math.min(100, Math.max(0, p)) + '%';
}
window.addEventListener('scroll', update, { passive: true });
window.addEventListener('resize', update);
update();
})();
</script>
<?php
}, 20);
附:Zibll 常用钩子速查
| 钩子 | 时机 | 典型用途 |
|---|---|---|
zib_require_end | 父主题加载完 | 调用父主题函数的入口 |
zib_posts_content_before | 正文前 | 插入提示、广告位 |
zib_posts_content_after | 正文后 | 相关推荐、评分 |
zib_article_content_after | 文章容器后 | 作者卡片、评论前 |
comment_footer_info | 评论底部 | 评论徽章、标记 |
user_ctnter_main_tabs_array | 用户中心 tab | 添加自定义 tab |
附:自检清单
- 子主题 style.css 的
Template是zibll吗? Version是父主题版本号吗?- 钩子挂在
zib_require_end之后了吗? - 资源路径传参了吗?
- 验证时打点了吗(而不是靠「看起来应该对」)?
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
暂无评论内容