主题和插件打架:样式覆盖、钩子顺序和怎么定位是谁改坏的

· zblog · 阅读 14
摘要

主题和插件同时改同一块区域,结果就是一团乱。 先分清谁在改。 插件挂的钩子一般比主题晚执行——主题在 Filter_Plugin_Zbp_Load 里注册,插件在插件加载阶段注册,顺序取决于「插件管理」里的排序,以及主题和插件谁先被 i

主题和插件同时改同一块区域,结果就是一团乱。

先分清谁在改。

插件挂的钩子一般比主题晚执行——主题在 Filter_Plugin_Zbp_Load 里注册,插件在插件加载阶段注册,顺序取决于「插件管理」里的排序,以及主题和插件谁先被 include。

实际排查靠的是「关掉再开」:把可疑插件禁用,刷新,问题消失,就锁定它了。

但插件不能随便关,关了前台可能有东西消失。所以更快的办法是看输出。

样式冲突。

插件往页面里塞 CSS,用 Filter_Plugin_ViewIndex_Footer 之类的钩子 echo 一段 <style>。这段样式排在主题 css 之后,优先级自然高,把主题的样式盖了。

确认方法:浏览器开发者工具选中元素,看 Computed 那一栏,哪条规则生效、来自哪个文件,写得清清楚楚。

定位到之后,解决方式按代价从低到高:

给主题的选择器提高权重,比如加一层父级 id。不优雅但有效,也不影响插件升级。

或者走 !important。能用,但会给自己埋下次冲突。

最干净的是调整加载顺序,让主题的 css 排在插件之后。这要改主题注册资源的时机,代价大一些。

钩子顺序。

同一个钩子上挂多个函数,执行顺序取决于挂载顺序。主题写得早,插件写得晚,插件就后跑。

如果两个都在改同一份数据,后跑的覆盖先跑的。

要控制顺序,可以用 Add_Filter_Plugin 的时候看是否有优先级参数——Z-Blog 的钩子本身不支持优先级,只能靠挂载的先后。

所以真正可控的办法只有一个:在插件管理里调整插件的加载顺序。

怎么定位是谁改坏的。

三步。

第一步,关掉所有非必要插件,只留主题。问题没了,说明跟插件有关。

第二步,二分法开插件。一次开一半,看问题是否重现,能快速缩到某一个。

第三步,锁定插件后,去它的 include.php 搜钩子名,看它 echo 了什么、append 了什么。

这三步比读代码靠谱得多。

最后一条经验。

主题里凡是准备被插件 hook 的地方,都留一个「空壳」。比如输出 header 之前,先留一个 Filter_Plugin_Theme_Header_Begin 之类的自定义钩子,让插件有地方可挂。

没有钩子的主题,插件只能硬改 DOM 或者用 JS 兜,两种情况都糟。

你站上装了几个插件?有没有改前台的?