<?xml version="1.0" encoding="utf-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"><channel><title>优杰简约响应式博客</title><link>http://acmecontract.blog.lwenl.cn/</link><description>体验极佳的主题演示</description><item><title>免费白嫖原生 GPT-5.5！注册即送 1 个月 Pro 会员，每周 66 刀额度爽薅教程</title><link>http://acmecontract.blog.lwenl.cn/?id=20</link><description>&lt;p data-path-to-node=&quot;3&quot;&gt;还在眼馋 GPT-5.5 强大的长文本处理、代码和复杂推理能力，却被高昂的订阅费劝退？今天给大家分享一个能&lt;strong data-path-to-node=&quot;3&quot; data-index-in-node=&quot;53&quot;&gt;零成本体验原生 GPT-5.5&lt;/strong&gt; 的宝藏网站 —— &lt;strong data-path-to-node=&quot;3&quot; data-index-in-node=&quot;78&quot;&gt;Freemodel&lt;/strong&gt;。&lt;/p&gt;&lt;p data-path-to-node=&quot;4&quot;&gt;只要通过专属链接注册，就能直接白嫖 1 个月的 Pro 会员，每周自动到账 66 美元的 API 消耗额度。全程无套路、&lt;strong data-path-to-node=&quot;4&quot; data-index-in-node=&quot;60&quot;&gt;无需绑定信用卡&lt;/strong&gt;，极其适合想先上车体验再决定是否长期订阅的朋友！&lt;/p&gt;&lt;h2 data-path-to-node=&quot;5&quot;&gt;🎁 核心福利一览&lt;/h2&gt;&lt;ul data-path-to-node=&quot;6&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;6,0,0&quot;&gt;&lt;strong data-path-to-node=&quot;6,0,0&quot; data-index-in-node=&quot;0&quot;&gt;适用模型&lt;/strong&gt;：原生 GPT-5.5（纯正体验，绝非降智套壳）&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;6,1,0&quot;&gt;&lt;strong data-path-to-node=&quot;6,1,0&quot; data-index-in-node=&quot;0&quot;&gt;专属权益&lt;/strong&gt;：新用户直升 1 个月 Pro 会员&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;6,2,0&quot;&gt;&lt;strong data-path-to-node=&quot;6,2,0&quot; data-index-in-node=&quot;0&quot;&gt;额度发放&lt;/strong&gt;：每周高达 &lt;strong data-path-to-node=&quot;6,2,0&quot; data-index-in-node=&quot;10&quot;&gt;66 美元&lt;/strong&gt;的等价 Token 额度&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;6,3,0&quot;&gt;&lt;strong data-path-to-node=&quot;6,3,0&quot; data-index-in-node=&quot;0&quot;&gt;刷新机制&lt;/strong&gt;：每周一自动刷新，无需每天辛苦打卡领取&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;6,4,0&quot;&gt;&lt;strong data-path-to-node=&quot;6,4,0&quot; data-index-in-node=&quot;0&quot;&gt;专属注册通道&lt;/strong&gt;：&lt;response-element class=&quot;&quot; ng-version=&quot;0.0.0-PLACEHOLDER&quot;&gt;&lt;link-block _nghost-ng-c3277958837=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;&lt;a href=&quot;https://freemodel.dev/invite/FRE-b307ef10&quot; target=&quot;_blank&quot; textvalue=&quot;点击直达 Freemodel 官网获取福利&quot;&gt;点击直达 Freemodel 官网获取福利&lt;/a&gt;&lt;/link-block&gt;&lt;/response-element&gt;&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-path-to-node=&quot;8&quot;&gt;💡 “每周 66 美元”到底有多经花？&lt;/h2&gt;&lt;p data-path-to-node=&quot;9&quot;&gt;很多小伙伴对按 Token 计费的额度没有具体概念，我们来算一笔账：&lt;/p&gt;&lt;ul data-path-to-node=&quot;10&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;10,0,0&quot;&gt;&lt;strong data-path-to-node=&quot;10,0,0&quot; data-index-in-node=&quot;0&quot;&gt;日常消耗&lt;/strong&gt;：一次普通的对话（几百字提问 + 几百字回复），大约只消耗 0.05–0.2 美元。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;10,1,0&quot;&gt;&lt;strong data-path-to-node=&quot;10,1,0&quot; data-index-in-node=&quot;0&quot;&gt;实际体验&lt;/strong&gt;：66 美元足够你每周进行&lt;strong data-path-to-node=&quot;10,1,0&quot; data-index-in-node=&quot;17&quot;&gt;上千轮&lt;/strong&gt;的日常对话，或者是执行几十轮非常复杂的长文本/代码指令。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;10,2,0&quot;&gt;&lt;strong data-path-to-node=&quot;10,2,0&quot; data-index-in-node=&quot;0&quot;&gt;结论&lt;/strong&gt;：对于绝大多数轻度、中度 AI 玩家来说，这个额度&lt;strong data-path-to-node=&quot;10,2,0&quot; data-index-in-node=&quot;27&quot;&gt;绰绰有余&lt;/strong&gt;，根本用不完。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-path-to-node=&quot;12&quot;&gt;🛠️ 极简上车步骤（1 分钟搞定）&lt;/h2&gt;&lt;p data-path-to-node=&quot;13&quot;&gt;全程只需要一个邮箱，操作极其简单：&lt;/p&gt;&lt;ol start=&quot;1&quot; data-path-to-node=&quot;14&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;14,0,0&quot;&gt;&lt;strong data-path-to-node=&quot;14,0,0&quot; data-index-in-node=&quot;0&quot;&gt;打开官网&lt;/strong&gt;：点击专属邀请链接 👉&lt;response-element class=&quot;&quot; ng-version=&quot;0.0.0-PLACEHOLDER&quot;&gt;&lt;link-block _nghost-ng-c3277958837=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;&lt;a href=&quot;https://freemodel.dev/invite/FRE-b307ef10&quot; target=&quot;_blank&quot; textvalue=&quot;https://freemodel.dev/invite/FRE-b307ef10&quot;&gt;https://freemodel.dev/invite/FRE-b307ef10&lt;/a&gt;&lt;/link-block&gt;&lt;/response-element&gt;&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;14,1,0&quot;&gt;&lt;strong data-path-to-node=&quot;14,1,0&quot; data-index-in-node=&quot;0&quot;&gt;邮箱注册&lt;/strong&gt;：填写邮箱并完成基础注册流程。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;14,2,0&quot;&gt;&lt;strong data-path-to-node=&quot;14,2,0&quot; data-index-in-node=&quot;0&quot;&gt;自动升级&lt;/strong&gt;：注册成功后无需任何额外操作，账号会自动升级为 1 个月 Pro 会员，直接开聊！&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;h2 data-path-to-node=&quot;16&quot;&gt;⭐ 为什么强烈推荐 Freemodel？&lt;/h2&gt;&lt;ul data-path-to-node=&quot;17&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;17,0,0&quot;&gt;&lt;strong data-path-to-node=&quot;17,0,0&quot; data-index-in-node=&quot;0&quot;&gt;真正的零门槛&lt;/strong&gt;：注册即送，&lt;strong data-path-to-node=&quot;17,0,0&quot; data-index-in-node=&quot;12&quot;&gt;不需要绑卡&lt;/strong&gt;，彻底杜绝了忘记取消订阅被反薅的风险。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;17,1,0&quot;&gt;&lt;strong data-path-to-node=&quot;17,1,0&quot; data-index-in-node=&quot;0&quot;&gt;模型保真&lt;/strong&gt;：后台调用的就是原生的 GPT-5.5，你可以完整体验到当前最强前沿模型的实力。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;17,2,0&quot;&gt;&lt;strong data-path-to-node=&quot;17,2,0&quot; data-index-in-node=&quot;0&quot;&gt;节奏稳定&lt;/strong&gt;：额度按周刷新，比起按月给固定额度，这种方式能防止你前几天就把额度全挥霍完。&lt;/p&gt;&lt;/li&gt;&lt;/ul&gt;&lt;h2 data-path-to-node=&quot;19&quot;&gt;⚠️ 避坑与注意事项&lt;/h2&gt;&lt;p data-path-to-node=&quot;20&quot;&gt;羊毛虽然香，但上车前也要注意以下几点：&lt;/p&gt;&lt;ol start=&quot;1&quot; data-path-to-node=&quot;21&quot; class=&quot; list-paddingleft-2&quot;&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;21,0,0&quot;&gt;&lt;strong data-path-to-node=&quot;21,0,0&quot; data-index-in-node=&quot;0&quot;&gt;降级提醒&lt;/strong&gt;：1 个月的 Pro 体验期结束后，账号会自动降级为免费版，届时模型会变旧（无法再免费使用 GPT-5.5）。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;21,1,0&quot;&gt;&lt;strong data-path-to-node=&quot;21,1,0&quot; data-index-in-node=&quot;0&quot;&gt;数据安全&lt;/strong&gt;：如果用它写代码或处理重要工作，&lt;strong data-path-to-node=&quot;21,1,0&quot; data-index-in-node=&quot;20&quot;&gt;建议定期导出并备份重要对话内容&lt;/strong&gt;，以防到期后影响查阅。&lt;/p&gt;&lt;/li&gt;&lt;li&gt;&lt;p data-path-to-node=&quot;21,2,0&quot;&gt;&lt;strong data-path-to-node=&quot;21,2,0&quot; data-index-in-node=&quot;0&quot;&gt;续费考量&lt;/strong&gt;：如果你在这一个月里用得很顺手，想要长期使用，建议提前去官网了解后续长期的续费价格，衡量性价比。&lt;/p&gt;&lt;/li&gt;&lt;/ol&gt;&lt;p data-path-to-node=&quot;22&quot;&gt;&lt;strong data-path-to-node=&quot;22&quot; data-index-in-node=&quot;0&quot;&gt;总结：这波羊毛适合谁？&lt;/strong&gt;如果你一直在观望 GPT-5.5，想免费测试它写代码、写文章、做数据分析的真实水平，然后再决定要不要掏真金白银买官方订阅，那 Freemodel 绝对是你目前最好的“试金石”。&lt;/p&gt;&lt;p data-path-to-node=&quot;23&quot;&gt;别犹豫了，趁着活动还在，&lt;a href=&quot;https://freemodel.dev/invite/FRE-b307ef10&quot; target=&quot;_blank&quot; textvalue=&quot;点此立即注册领 1 个月 Pro 会员&quot;&gt;&lt;strong data-path-to-node=&quot;23&quot; data-index-in-node=&quot;12&quot;&gt;&lt;link-block _nghost-ng-c3277958837=&quot;&quot; class=&quot;ng-star-inserted&quot;&gt;点此立即注册领 1 个月 Pro 会员&lt;/link-block&gt;&lt;/strong&gt;&lt;/a&gt;！&lt;/p&gt;&lt;p&gt;&lt;br/&gt;&lt;/p&gt;</description><pubDate>Fri, 22 May 2026 09:05:39 +0800</pubDate></item><item><title>做一个能上线的 Z-BlogPHP 项目，最后必须检查哪些东西？别等上线后再补救</title><link>http://acmecontract.blog.lwenl.cn/?id=19</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-12.png&quot; alt=&quot;做一个能上线的 Z-BlogPHP 项目，最后必须检查哪些东西？别等上线后再补救 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;前面这一整组文章，讲了环境、运行流程、文件职责、主题、模板、配置、插件、Hook、Metas、路由、评论和 API。&lt;/p&gt;
&lt;p&gt;但真实项目里，真正让人头疼的时刻，往往不是“开发中”，而是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你以为差不多了，准备上线了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这时候最容易发生的情况不是完全做不出来，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面能开，但细节没检查&lt;/li&gt;
&lt;li&gt;配置能存，但某些页面没消费&lt;/li&gt;
&lt;li&gt;评论能显示，但提交链路有坑&lt;/li&gt;
&lt;li&gt;搜索能用，但空结果和分页没测&lt;/li&gt;
&lt;li&gt;图片能传，但路径、权限、默认图还有问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以这一篇不讲新知识，专门讲收尾。&lt;/p&gt;
&lt;h2&gt;一、先别着急上线，先问自己是不是“真的做完了”&lt;/h2&gt;
&lt;p&gt;很多开发者对“做完”的判断，往往偏向代码视角：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文件写完了&lt;/li&gt;
&lt;li&gt;页面看起来差不多&lt;/li&gt;
&lt;li&gt;后台能保存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;但上线视角和开发视角不完全一样。&lt;/p&gt;
&lt;p&gt;上线前更该问的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关键路径都通了吗&lt;/li&gt;
&lt;li&gt;极端情况测了吗&lt;/li&gt;
&lt;li&gt;配置和缓存一致吗&lt;/li&gt;
&lt;li&gt;失败时用户会看到什么&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;上线前的核心能力，不是写新代码，而是把已经写好的东西完整验证一遍。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;二、先检查改动是不是落在了对的层&lt;/h2&gt;
&lt;p&gt;这一步看起来很基础，其实非常重要。&lt;/p&gt;
&lt;p&gt;上线前先回头看一眼：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面结构是不是主要落在主题模板&lt;/li&gt;
&lt;li&gt;主题逻辑是不是主要落在 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;后台设置是不是放在 &lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;通用流程功能是不是插件在接&lt;/li&gt;
&lt;li&gt;有没有为了赶工把不该改的东西改进核心&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果这一层已经乱了，哪怕功能暂时能跑，后面维护也会很痛。&lt;/p&gt;
&lt;h2&gt;三、主题层上线前要检查什么&lt;/h2&gt;
&lt;p&gt;至少要覆盖下面这些页面：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页&lt;/li&gt;
&lt;li&gt;分类页&lt;/li&gt;
&lt;li&gt;标签页&lt;/li&gt;
&lt;li&gt;文章详情页&lt;/li&gt;
&lt;li&gt;搜索页&lt;/li&gt;
&lt;li&gt;404 页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;检查重点包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题是否正常&lt;/li&gt;
&lt;li&gt;列表结构是否完整&lt;/li&gt;
&lt;li&gt;图片是否正常&lt;/li&gt;
&lt;li&gt;分页是否正常&lt;/li&gt;
&lt;li&gt;空状态是否合理&lt;/li&gt;
&lt;li&gt;公共头尾是否一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;不要只看首页和一篇文章就觉得差不多了。&lt;/p&gt;
&lt;h2&gt;四、详情页最容易漏什么&lt;/h2&gt;
&lt;p&gt;文章详情页上线前，至少检查这些：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题&lt;/li&gt;
&lt;li&gt;发布时间&lt;/li&gt;
&lt;li&gt;作者信息&lt;/li&gt;
&lt;li&gt;正文排版&lt;/li&gt;
&lt;li&gt;标签和分类链接&lt;/li&gt;
&lt;li&gt;相关推荐或延伸区块&lt;/li&gt;
&lt;li&gt;评论区是否显示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你做了下面这些增强，也别忘了核：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;目录&lt;/li&gt;
&lt;li&gt;下载区&lt;/li&gt;
&lt;li&gt;广告位&lt;/li&gt;
&lt;li&gt;作者卡片&lt;/li&gt;
&lt;li&gt;文章专属 SEO 字段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详情页通常是内容站最值钱的页面，最不该只看一眼就过。&lt;/p&gt;
&lt;h2&gt;五、主题配置项要按“保存-生效-兜底”三段检查&lt;/h2&gt;
&lt;p&gt;很多主题上线前最容易翻车的，不是页面，而是配置项。&lt;/p&gt;
&lt;p&gt;你至少要逐项确认：&lt;/p&gt;
&lt;h3&gt;1. 能保存&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;后台提交没报错&lt;/li&gt;
&lt;li&gt;刷新后值还在&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 能生效&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;前台相关位置真的变了&lt;/li&gt;
&lt;li&gt;不只是后台提示保存成功&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 有兜底&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;没填值时页面不会塌&lt;/li&gt;
&lt;li&gt;默认图、默认文案、默认开关都合理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要这三段有一段没走通，配置项就还不算真正完成。&lt;/p&gt;
&lt;h2&gt;六、&lt;code&gt;Metas&lt;/code&gt; 和自定义字段要检查“对象值优先、空值回退”&lt;/h2&gt;
&lt;p&gt;如果你做了文章、分类、标签字段，上线前一定要看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;填了值时，前台有没有优先使用&lt;/li&gt;
&lt;li&gt;没填值时，是否回退到默认逻辑&lt;/li&gt;
&lt;li&gt;列表页和详情页读取是否一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章封面&lt;/li&gt;
&lt;li&gt;SEO 标题&lt;/li&gt;
&lt;li&gt;SEO 描述&lt;/li&gt;
&lt;li&gt;分类介绍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些字段一旦前台消费不完整，线上效果会很别扭。&lt;/p&gt;
&lt;h2&gt;七、评论、搜索、分页，这三条线必须单独测&lt;/h2&gt;
&lt;p&gt;很多站点表面看没问题，真正上线后最先暴露问题的就是这三块。&lt;/p&gt;
&lt;h3&gt;评论&lt;/h3&gt;
&lt;p&gt;至少测：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正常提交&lt;/li&gt;
&lt;li&gt;异常提交&lt;/li&gt;
&lt;li&gt;审核状态&lt;/li&gt;
&lt;li&gt;错误提示&lt;/li&gt;
&lt;li&gt;Ajax 和普通提交流程&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;搜索&lt;/h3&gt;
&lt;p&gt;至少测：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;正常有结果&lt;/li&gt;
&lt;li&gt;空结果&lt;/li&gt;
&lt;li&gt;搜索结果页标题&lt;/li&gt;
&lt;li&gt;关键词切换&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;分页&lt;/h3&gt;
&lt;p&gt;至少测：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页分页&lt;/li&gt;
&lt;li&gt;分类分页&lt;/li&gt;
&lt;li&gt;搜索分页&lt;/li&gt;
&lt;li&gt;超出页码的处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这三条线不要只测“看起来能打开”。&lt;/p&gt;
&lt;h2&gt;八、SEO 相关检查，别只盯着首页&lt;/h2&gt;
&lt;p&gt;如果你的站点是内容站，这一块非常重要。&lt;/p&gt;
&lt;p&gt;至少要检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页 title&lt;/li&gt;
&lt;li&gt;文章页 title&lt;/li&gt;
&lt;li&gt;分类页 title&lt;/li&gt;
&lt;li&gt;标签页 title&lt;/li&gt;
&lt;li&gt;description 是否正常&lt;/li&gt;
&lt;li&gt;自定义 SEO 字段有没有被消费&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你做了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;canonical&lt;/li&gt;
&lt;li&gt;RSS&lt;/li&gt;
&lt;li&gt;搜索页独立标题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也要一起验证。&lt;/p&gt;
&lt;p&gt;很多开发时觉得“后面再补”的 SEO 输出，最后一拖就拖到上线后了。&lt;/p&gt;
&lt;h2&gt;九、路由和 API，上线前要特别注意边界&lt;/h2&gt;
&lt;h3&gt;路由&lt;/h3&gt;
&lt;p&gt;检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL 能不能稳定匹配&lt;/li&gt;
&lt;li&gt;参数是否正确传入&lt;/li&gt;
&lt;li&gt;异常路径会不会报错&lt;/li&gt;
&lt;li&gt;重定向有没有死循环&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;API&lt;/h3&gt;
&lt;p&gt;检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模块和动作是否正确&lt;/li&gt;
&lt;li&gt;权限是否合理&lt;/li&gt;
&lt;li&gt;写操作是否受控&lt;/li&gt;
&lt;li&gt;返回格式是否稳定&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;尤其是内部工具类站点，API 和路由一旦没验完整，线上定位会很麻烦。&lt;/p&gt;
&lt;h2&gt;十、上传和资源路径，不要最后才看&lt;/h2&gt;
&lt;p&gt;很多站点上线后才发现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;图片路径不对&lt;/li&gt;
&lt;li&gt;默认图路径写死在本地&lt;/li&gt;
&lt;li&gt;上传目录权限有问题&lt;/li&gt;
&lt;li&gt;某些资源链接还是测试地址&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以至少要检查：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章图片&lt;/li&gt;
&lt;li&gt;默认图&lt;/li&gt;
&lt;li&gt;主题静态资源&lt;/li&gt;
&lt;li&gt;上传附件&lt;/li&gt;
&lt;li&gt;CSS 和 JS 路径&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要是和 &lt;code&gt;host&lt;/code&gt;、主题目录、上传目录相关的路径，都值得过一遍。&lt;/p&gt;
&lt;h2&gt;十一、安全和后台边界，也别省略&lt;/h2&gt;
&lt;p&gt;哪怕不是重安全项目，至少也要看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后台设置保存有没有基础校验&lt;/li&gt;
&lt;li&gt;写操作有没有 &lt;code&gt;CheckIsRefererValid()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;评论有没有最基本的防滥用策略&lt;/li&gt;
&lt;li&gt;插件配置页有没有权限判断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多问题开发阶段没暴露，是因为你一直在管理员环境里操作。&lt;/p&gt;
&lt;p&gt;一上线，真实用户路径一跑，就会不一样。&lt;/p&gt;
&lt;h2&gt;十二、日志、缓存和回滚准备，是真正的上线保险&lt;/h2&gt;
&lt;p&gt;上线前最好先确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;日志目录你知道在哪里&lt;/li&gt;
&lt;li&gt;缓存目录你知道怎么判断&lt;/li&gt;
&lt;li&gt;模板或模块重建流程你知道怎么触发&lt;/li&gt;
&lt;li&gt;改坏了以后，怎么快速回退&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;别等出问题了才第一次去找：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;zb_users/logs/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;zb_users/cache/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些位置你应该在上线前就熟。&lt;/p&gt;
&lt;h2&gt;十三、一份够用的上线前检查清单&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 首页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 分类页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 标签页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 文章详情页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 搜索页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 404 页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 评论显示与提交正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 分页正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 主题配置项保存与生效正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; &lt;code&gt;Metas&lt;/code&gt; 字段优先级正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; SEO 标题和描述输出正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 路由匹配正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; API 请求正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 上传与静态资源路径正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 日志和缓存排查路径明确&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你能认真跑完这份单子，上线翻车概率会降很多。&lt;/p&gt;
&lt;h2&gt;十四、一个更现实的建议：上线前至少做两轮检查&lt;/h2&gt;
&lt;p&gt;第一轮，从开发者视角看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能有没有&lt;/li&gt;
&lt;li&gt;页面能不能开&lt;/li&gt;
&lt;li&gt;配置能不能存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;第二轮，从用户视角看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面顺不顺&lt;/li&gt;
&lt;li&gt;搜索和评论会不会卡&lt;/li&gt;
&lt;li&gt;某些空状态会不会很奇怪&lt;/li&gt;
&lt;li&gt;看不看得懂出错提示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多问题开发者自己很容易忽略，但用户一进来马上就能感觉到。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;一个能上线的 Z-BlogPHP 项目，不是“代码写完了”就算完。&lt;/p&gt;
&lt;p&gt;真正决定上线质量的，往往是这些看起来不那么性感的事情：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面全不全&lt;/li&gt;
&lt;li&gt;配置稳不稳&lt;/li&gt;
&lt;li&gt;评论、搜索、分页通不通&lt;/li&gt;
&lt;li&gt;SEO 有没有落地&lt;/li&gt;
&lt;li&gt;路由和 API 有没有边界&lt;/li&gt;
&lt;li&gt;出错以后能不能快速定位&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你只要把这套收尾习惯养起来，后面不管做博客主题、内容站、服务站，交付质量都会明显高很多。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:12:00 +0800</pubDate></item><item><title>路由、评论和 API 怎么啃？先抓住这三条链路</title><link>http://acmecontract.blog.lwenl.cn/?id=18</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-11.png&quot; alt=&quot;路由、评论和 API 怎么啃？先抓住这三条链路 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果说前面的主题、插件、Hook、Metas 还算是一条线往前学，那从这一篇开始，很多人会明显感觉：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;难度上来了。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最容易把人绊住的三块，通常就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由&lt;/li&gt;
&lt;li&gt;评论&lt;/li&gt;
&lt;li&gt;API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这三块的共同点是，它们都不是单纯的“改个模板”。&lt;/p&gt;
&lt;p&gt;你如果还拿“页面结构思维”去处理，通常会越改越乱。&lt;/p&gt;
&lt;p&gt;更稳的方式，是分别抓住它们各自的链路。&lt;/p&gt;
&lt;h2&gt;一、先说路由：它不是页面长什么样，而是 URL 怎么进系统&lt;/h2&gt;
&lt;p&gt;很多人一听路由，就容易立刻想到前端框架。&lt;/p&gt;
&lt;p&gt;但在 Z-BlogPHP 里，路由首先解决的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某个 URL 怎么被识别&lt;/li&gt;
&lt;li&gt;某类请求交给谁处理&lt;/li&gt;
&lt;li&gt;自定义页面怎么接进系统&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;常见的现代做法，是通过：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;$zbp-&amp;gt;RegRoute(...)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;来注册路由。&lt;/p&gt;
&lt;p&gt;也就是说，路由工作通常不是在模板里开始的，而是在更早的请求阶段开始的。&lt;/p&gt;
&lt;h2&gt;二、什么时候你真的需要自己注册路由&lt;/h2&gt;
&lt;p&gt;不是所有页面都要自定义路由。&lt;/p&gt;
&lt;p&gt;更适合用路由的，通常是这些场景：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义专题页 URL&lt;/li&gt;
&lt;li&gt;自定义工具页 URL&lt;/li&gt;
&lt;li&gt;特殊下载页&lt;/li&gt;
&lt;li&gt;搜索重写&lt;/li&gt;
&lt;li&gt;需要独立匹配规则的扩展页面&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果只是普通首页、分类页、文章页，其实大多已经有现成流程。&lt;/p&gt;
&lt;p&gt;不要为了“感觉高级”把能用现成模板解决的东西硬改成自定义路由。&lt;/p&gt;
&lt;h2&gt;三、注册路由时，你最该先看哪几个字段&lt;/h2&gt;
&lt;p&gt;一个路由定义里，常见会看到这些信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;posttype&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;type&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;name&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;call&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;urlrule&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;args&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你不用一开始把所有键都背下来。&lt;/p&gt;
&lt;p&gt;先抓住最核心的三个问题：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这个路由匹配什么 URL&lt;/li&gt;
&lt;li&gt;匹配后调哪个处理函数&lt;/li&gt;
&lt;li&gt;处理函数能拿到哪些参数&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这三件事先想明白，已经能做很多实际开发了。&lt;/p&gt;
&lt;h2&gt;四、路由处理函数最重要的意识：它拿到的是匹配结果&lt;/h2&gt;
&lt;p&gt;路由不是纯页面模板。&lt;/p&gt;
&lt;p&gt;它更像是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;URL 先被规则匹配&lt;/li&gt;
&lt;li&gt;提取出参数&lt;/li&gt;
&lt;li&gt;再进入处理函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你在处理函数里最先要做的，不是急着输出 HTML，而是先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;传进来的参数长什么样&lt;/li&gt;
&lt;li&gt;当前请求想干什么&lt;/li&gt;
&lt;li&gt;最终要不要交给模板、对象、重定向或其他逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这也是为什么路由问题更接近“请求链路”，不只是“页面结构”。&lt;/p&gt;
&lt;h2&gt;五、再说评论：真正难的不是列表，是提交链路&lt;/h2&gt;
&lt;p&gt;很多人一开始看评论，以为评论开发主要是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论列表长什么样&lt;/li&gt;
&lt;li&gt;回复按钮放哪里&lt;/li&gt;
&lt;li&gt;表单长什么样&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些当然重要，但真正最容易出问题的地方，其实是提交链路。&lt;/p&gt;
&lt;p&gt;一个评论提交的典型顺序，大致是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;前台表单发起提交&lt;/li&gt;
&lt;li&gt;请求进入评论处理流程&lt;/li&gt;
&lt;li&gt;平台做基本校验&lt;/li&gt;
&lt;li&gt;插件 Hook 可能介入&lt;/li&gt;
&lt;li&gt;评论被通过、审核或拒绝&lt;/li&gt;
&lt;li&gt;前台拿到成功或错误反馈&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;只要你开始理解这是一条链路，评论问题就容易拆开看。&lt;/p&gt;
&lt;h2&gt;六、评论问题到底先看模板还是先看 Hook&lt;/h2&gt;
&lt;p&gt;答案是：看你改的是什么。&lt;/p&gt;
&lt;h3&gt;更像模板问题的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;评论列表展示错位&lt;/li&gt;
&lt;li&gt;回复结构错乱&lt;/li&gt;
&lt;li&gt;表单字段排版问题&lt;/li&gt;
&lt;li&gt;评论区位置不对&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;更像流程问题的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;评论提交失败&lt;/li&gt;
&lt;li&gt;提交后被错误拦截&lt;/li&gt;
&lt;li&gt;审核状态不对&lt;/li&gt;
&lt;li&gt;反垃圾误判&lt;/li&gt;
&lt;li&gt;Ajax 和普通提交表现不一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_PostComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_CheckComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Error_Handler&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多人评论问题排不出来，就是因为它明明是流程问题，却只盯着模板。&lt;/p&gt;
&lt;h2&gt;七、评论调试时，最稳的排查顺序&lt;/h2&gt;
&lt;p&gt;我更建议你按这条线来：&lt;/p&gt;
&lt;h3&gt;1. 先看评论表单&lt;/h3&gt;
&lt;p&gt;确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提交地址对不对&lt;/li&gt;
&lt;li&gt;必填字段对不对&lt;/li&gt;
&lt;li&gt;有没有 Ajax 截获&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 再看平台校验&lt;/h3&gt;
&lt;p&gt;确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;验证码&lt;/li&gt;
&lt;li&gt;频率限制&lt;/li&gt;
&lt;li&gt;基础校验&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 再看插件 Hook&lt;/h3&gt;
&lt;p&gt;确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;有没有反垃圾插件&lt;/li&gt;
&lt;li&gt;有没有审核规则&lt;/li&gt;
&lt;li&gt;有没有把错误转成自定义提示&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 最后看前台反馈&lt;/h3&gt;
&lt;p&gt;确认：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提交失败时，前台到底收到了什么&lt;/li&gt;
&lt;li&gt;是后端真失败，还是前端解析错了&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这个顺序会比“到处猜”有效很多。&lt;/p&gt;
&lt;h2&gt;八、再看 API：它和普通页面是另一条路&lt;/h2&gt;
&lt;p&gt;很多人刚接触 Z-BlogPHP API 时，会下意识把它和前台页面混在一起理解。&lt;/p&gt;
&lt;p&gt;其实它们的重点不一样。&lt;/p&gt;
&lt;p&gt;前台页面更关心：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模板&lt;/li&gt;
&lt;li&gt;布局&lt;/li&gt;
&lt;li&gt;渲染&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;API 更关心：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模块&lt;/li&gt;
&lt;li&gt;动作&lt;/li&gt;
&lt;li&gt;权限&lt;/li&gt;
&lt;li&gt;字段&lt;/li&gt;
&lt;li&gt;返回结果&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;原生 API 的入口通常是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;zb_system/api.php?mod=&amp;lt;module&amp;gt;&amp;amp;act=&amp;lt;action&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个模式一旦理解了，后面很多工具化工作都会顺手很多。&lt;/p&gt;
&lt;h2&gt;九、原生 API 先看什么，不要一上来就自定义&lt;/h2&gt;
&lt;p&gt;很多需求其实原生模块已经覆盖不少了。&lt;/p&gt;
&lt;p&gt;高频模块包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;post&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comment&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;member&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;category&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tag&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;upload&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;module&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;app&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;system&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你要做的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章管理工具&lt;/li&gt;
&lt;li&gt;评论审核工具&lt;/li&gt;
&lt;li&gt;分类同步&lt;/li&gt;
&lt;li&gt;上传管理&lt;/li&gt;
&lt;li&gt;主题或插件状态切换&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先看原生 API，通常比自己再造一套更稳。&lt;/p&gt;
&lt;h2&gt;十、什么时候才该考虑自定义 API&lt;/h2&gt;
&lt;p&gt;更适合自定义 API 的，通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;原生模块覆盖不了&lt;/li&gt;
&lt;li&gt;你需要一套项目专属接口&lt;/li&gt;
&lt;li&gt;你要做插件级接口扩展&lt;/li&gt;
&lt;li&gt;你要把多个原子操作组合成自己的业务动作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时候常见思路是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;做插件&lt;/li&gt;
&lt;li&gt;注册新 API 模块&lt;/li&gt;
&lt;li&gt;定义自己的处理函数&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;如果只是现成模块已经能做的事情，不必为了“统一风格”全部重造。&lt;/p&gt;
&lt;h2&gt;十一、&lt;code&gt;ApiExecute(...)&lt;/code&gt; 为什么值得记一下&lt;/h2&gt;
&lt;p&gt;很多人一想到 API，就立刻想到 HTTP 请求。&lt;/p&gt;
&lt;p&gt;但在 Z-BlogPHP 里，还有一个很实用的思路：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;在 PHP 内部直接复用 API 行为。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这时常见会用到：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$result = ApiExecute(&amp;#39;post&amp;#39;, &amp;#39;get&amp;#39;, array(&amp;#39;id&amp;#39; =&amp;gt; 2));
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;它的意义是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;不走外部 HTTP&lt;/li&gt;
&lt;li&gt;直接在内部重用 API 能力&lt;/li&gt;
&lt;li&gt;适合插件或内部工具调用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这对做站内工具很有价值。&lt;/p&gt;
&lt;h2&gt;十二、这三块最容易踩的坑分别是什么&lt;/h2&gt;
&lt;h3&gt;路由的坑&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;把模板问题误当成路由问题&lt;/li&gt;
&lt;li&gt;还没想清 URL 设计就先注册规则&lt;/li&gt;
&lt;li&gt;只写匹配，不看处理函数拿到什么参数&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;评论的坑&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;只改评论模板，不看提交流程&lt;/li&gt;
&lt;li&gt;只看前端报错，不查后端 Hook&lt;/li&gt;
&lt;li&gt;Ajax 和普通提交只测一种&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;API 的坑&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;不先看原生模块，直接自定义&lt;/li&gt;
&lt;li&gt;忽略权限和鉴权&lt;/li&gt;
&lt;li&gt;不核对字段名和动作语义&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;十三、如果你现在就要动手，建议按这个顺序练&lt;/h2&gt;
&lt;h3&gt;第一步&lt;/h3&gt;
&lt;p&gt;先做一个简单自定义路由页面。&lt;/p&gt;
&lt;h3&gt;第二步&lt;/h3&gt;
&lt;p&gt;再完整走一遍评论提交流程排查。&lt;/p&gt;
&lt;h3&gt;第三步&lt;/h3&gt;
&lt;p&gt;最后用原生 API 做一个简单的文章或分类读取工具。&lt;/p&gt;
&lt;p&gt;这样你会非常清楚：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由在请求开始前&lt;/li&gt;
&lt;li&gt;评论是提交流程&lt;/li&gt;
&lt;li&gt;API 是另一条程序入口&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;路由、评论和 API 难，不是因为它们神秘，而是因为它们都比普通模板更靠近“流程”。&lt;/p&gt;
&lt;p&gt;你只要先抓住各自的主线：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由看 URL 怎么进系统&lt;/li&gt;
&lt;li&gt;评论看提交怎么流转&lt;/li&gt;
&lt;li&gt;API 看模块、动作和权限&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面再进细节时，心里就不会乱。&lt;/p&gt;
&lt;p&gt;下一篇我们把这整个系列收住，讲一个真正能上线的 Z-BlogPHP 项目，最后到底该检查哪些东西。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:11:00 +0800</pubDate></item><item><title>Metas、自定义字段和后台扩展怎么做？别把全局配置和文章字段混了</title><link>http://acmecontract.blog.lwenl.cn/?id=17</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-10.png&quot; alt=&quot;Metas、自定义字段和后台扩展怎么做？别把全局配置和文章字段混了 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;很多人学到主题配置和插件 Hook 以后，马上就会碰到一个更实用的问题：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;怎么给文章、分类、标签这些对象，加上自己的字段？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给文章加 SEO 标题&lt;/li&gt;
&lt;li&gt;给文章加封面图&lt;/li&gt;
&lt;li&gt;给分类加描述&lt;/li&gt;
&lt;li&gt;给标签加扩展信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时候如果你还用“全局配置”的思路去处理，很快就会乱掉。&lt;/p&gt;
&lt;p&gt;因为这类数据往往不是属于整个主题，而是属于某一个对象。&lt;/p&gt;
&lt;p&gt;这就是 &lt;code&gt;Metas&lt;/code&gt; 发挥作用的地方。&lt;/p&gt;
&lt;h2&gt;一、先分清：&lt;code&gt;Config&lt;/code&gt; 和 &lt;code&gt;Metas&lt;/code&gt; 不是一回事&lt;/h2&gt;
&lt;p&gt;很多人第一次做自定义字段，最容易在这里混。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;Config&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题全局设置&lt;/li&gt;
&lt;li&gt;插件全局设置&lt;/li&gt;
&lt;li&gt;默认图&lt;/li&gt;
&lt;li&gt;首页文案&lt;/li&gt;
&lt;li&gt;API Key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;全局都适用的值。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;Metas&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某篇文章自己的 SEO 标题&lt;/li&gt;
&lt;li&gt;某篇文章自己的封面图&lt;/li&gt;
&lt;li&gt;某个分类自己的说明&lt;/li&gt;
&lt;li&gt;某个标签自己的模板参数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;挂在单个对象上的值。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你把这两类东西混了，后面编辑体验会非常糟糕。&lt;/p&gt;
&lt;h2&gt;二、什么时候你应该立刻想到 &lt;code&gt;Metas&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;只要需求符合下面任意一条，你都应该优先考虑 &lt;code&gt;Metas&lt;/code&gt;：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;值只属于一篇文章&lt;/li&gt;
&lt;li&gt;值只属于一个分类&lt;/li&gt;
&lt;li&gt;值只属于一个标签&lt;/li&gt;
&lt;li&gt;不同内容对象之间需要各自独立维护&lt;/li&gt;
&lt;li&gt;前台模板需要按对象读取&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章封面&lt;/li&gt;
&lt;li&gt;文章 SEO 描述&lt;/li&gt;
&lt;li&gt;分类顶部说明&lt;/li&gt;
&lt;li&gt;标签页附加介绍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类数据都不应该做成主题 &lt;code&gt;Config&lt;/code&gt;。&lt;/p&gt;
&lt;h2&gt;三、Z-BlogPHP 里，&lt;code&gt;Metas&lt;/code&gt; 最常见的落地思路&lt;/h2&gt;
&lt;p&gt;常见路径其实很清楚：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;在编辑页注入一个字段&lt;/li&gt;
&lt;li&gt;提交时使用 &lt;code&gt;meta_&amp;lt;key&amp;gt;&lt;/code&gt; 的命名&lt;/li&gt;
&lt;li&gt;前台通过 &lt;code&gt;$object-&amp;gt;Metas-&amp;gt;key&lt;/code&gt; 读取&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;也就是说，&lt;code&gt;Metas&lt;/code&gt; 的关键不只是“存”，而是这条链路要完整。&lt;/p&gt;
&lt;h2&gt;四、文章自定义字段，通常从编辑页 Hook 开始&lt;/h2&gt;
&lt;p&gt;如果你要给文章编辑页加一个字段，常见会从这些 Hook 里找落点：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response2&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response3&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;具体挂哪一个，取决于你想插到编辑页的什么位置。&lt;/p&gt;
&lt;p&gt;你不需要一开始就死背顺序，先知道这类需求该往 &lt;code&gt;Edit_Response&lt;/code&gt; 家族找就够了。&lt;/p&gt;
&lt;h2&gt;五、字段名为什么常写成 &lt;code&gt;meta_&amp;lt;key&amp;gt;&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;这是一个很实用的约定。&lt;/p&gt;
&lt;p&gt;如果你要给文章加一个 SEO 标题字段，常见会写成：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;meta_seotitle&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你要加封面图字段，可能是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;&amp;lt;input type=&amp;quot;text&amp;quot; name=&amp;quot;meta_cover&amp;quot; value=&amp;quot;&amp;quot; /&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这种命名方式的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;语义清楚&lt;/li&gt;
&lt;li&gt;容易和普通表单项区分&lt;/li&gt;
&lt;li&gt;后面读取时也容易对应回 &lt;code&gt;$article-&amp;gt;Metas-&amp;gt;seotitle&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;六、前台读取时，怎么读才自然&lt;/h2&gt;
&lt;p&gt;如果字段属于文章，就从文章对象上读：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$article-&amp;gt;Metas-&amp;gt;seotitle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果字段属于分类，就从分类对象上读：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$category-&amp;gt;Metas-&amp;gt;seotitle
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果字段属于标签，就从标签对象上读：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$tag-&amp;gt;Metas-&amp;gt;intro_extra
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个思路非常直观：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;字段挂在哪个对象&lt;/li&gt;
&lt;li&gt;就从哪个对象的 &lt;code&gt;Metas&lt;/code&gt; 里读&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;七、一个最常见的例子：给文章加 SEO 标题和描述&lt;/h2&gt;
&lt;p&gt;这类需求特别适合拿来练手。&lt;/p&gt;
&lt;p&gt;思路通常是这样的：&lt;/p&gt;
&lt;h3&gt;第一步，在文章编辑页注入字段&lt;/h3&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;meta_seotitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;meta_seodescription&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第二步，编辑文章时填写&lt;/h3&gt;
&lt;p&gt;也就是让内容编辑者在后台每篇文章里单独填。&lt;/p&gt;
&lt;h3&gt;第三步，前台 &lt;code&gt;header.php&lt;/code&gt; 读取&lt;/h3&gt;
&lt;p&gt;例如先判断：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;当前文章有没有专属 SEO 标题&lt;/li&gt;
&lt;li&gt;如果有，就优先输出&lt;/li&gt;
&lt;li&gt;如果没有，再回退到普通标题或主题默认值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是一个非常标准的 &lt;code&gt;Metas&lt;/code&gt; 使用场景。&lt;/p&gt;
&lt;h2&gt;八、分类和标签的自定义字段也很值得做&lt;/h2&gt;
&lt;p&gt;很多人只想到文章字段，忽略了分类和标签。&lt;/p&gt;
&lt;p&gt;但对于内容站来说，分类和标签页本身就经常需要更多信息。&lt;/p&gt;
&lt;p&gt;比如你可能想给分类加：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面标题补充&lt;/li&gt;
&lt;li&gt;页面描述&lt;/li&gt;
&lt;li&gt;顶部介绍文本&lt;/li&gt;
&lt;li&gt;横幅图&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时就可以考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Category_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Tag_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这两个入口很常用。&lt;/p&gt;
&lt;p&gt;尤其做 SEO 站的时候，分类和标签字段的价值很高。&lt;/p&gt;
&lt;h2&gt;九、后台扩展不只是“加一个输入框”&lt;/h2&gt;
&lt;p&gt;很多人第一次做编辑页字段，只盯着那个输入框本身。&lt;/p&gt;
&lt;p&gt;其实完整度更重要。&lt;/p&gt;
&lt;p&gt;至少要同时考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个字段属于谁&lt;/li&gt;
&lt;li&gt;应该出现在哪个编辑页&lt;/li&gt;
&lt;li&gt;前台哪个位置会消费它&lt;/li&gt;
&lt;li&gt;空值怎么处理&lt;/li&gt;
&lt;li&gt;全局默认值和对象值怎么配合&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果这些没想清楚，就很容易出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后台能填&lt;/li&gt;
&lt;li&gt;前台不读取&lt;/li&gt;
&lt;li&gt;字段意义模糊&lt;/li&gt;
&lt;li&gt;编辑体验很差&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;十、&lt;code&gt;Metas&lt;/code&gt; 和默认值怎么配合最稳&lt;/h2&gt;
&lt;p&gt;这也是实际开发里很常见的需求。&lt;/p&gt;
&lt;p&gt;比如文章封面图，很多时候不会要求每篇都填。&lt;/p&gt;
&lt;p&gt;这时更稳的顺序通常是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先看文章 &lt;code&gt;Metas&lt;/code&gt; 里有没有专属封面&lt;/li&gt;
&lt;li&gt;没有的话，再看文章正文能不能提取首图&lt;/li&gt;
&lt;li&gt;还没有，再回退到主题默认图&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个思路也适用于 SEO 标题、摘要描述之类的字段。&lt;/p&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;code&gt;Metas&lt;/code&gt; 常常是优先值，不一定是唯一值。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;十一、最常见的 6 个坑&lt;/h2&gt;
&lt;h3&gt;1. 本该做 &lt;code&gt;Metas&lt;/code&gt; 的东西，硬做成全局配置&lt;/h3&gt;
&lt;p&gt;后面每篇文章都得共享同一个值，很别扭。&lt;/p&gt;
&lt;h3&gt;2. 字段注入了，但前台没消费&lt;/h3&gt;
&lt;p&gt;这是最常见的问题之一。&lt;/p&gt;
&lt;h3&gt;3. 前台直接读 &lt;code&gt;Metas&lt;/code&gt;，但没有空值兜底&lt;/h3&gt;
&lt;p&gt;一旦没填，页面结构就开始出问题。&lt;/p&gt;
&lt;h3&gt;4. 字段名没有统一命名习惯&lt;/h3&gt;
&lt;p&gt;后面排查和维护会很难受。&lt;/p&gt;
&lt;h3&gt;5. 分类字段、标签字段只做后台，不做前台落地&lt;/h3&gt;
&lt;p&gt;那它们的价值就打了折。&lt;/p&gt;
&lt;h3&gt;6. 把后台扩展写得太重&lt;/h3&gt;
&lt;p&gt;第一版先把字段链路跑通，比一开始做复杂后台体验更重要。&lt;/p&gt;
&lt;h2&gt;十二、一个很实用的开发顺序&lt;/h2&gt;
&lt;p&gt;如果你第一次做 &lt;code&gt;Metas&lt;/code&gt;，我建议按这个顺序练：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先给文章加一个简单字段&lt;/li&gt;
&lt;li&gt;在前台详情页把它读出来&lt;/li&gt;
&lt;li&gt;再给 &lt;code&gt;header.php&lt;/code&gt; 或列表页接入真实用途&lt;/li&gt;
&lt;li&gt;接着再做分类字段&lt;/li&gt;
&lt;li&gt;最后再做标签字段&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这样你会很快从“知道有 &lt;code&gt;Metas&lt;/code&gt;”进入“真的会用 &lt;code&gt;Metas&lt;/code&gt;”。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Metas&lt;/code&gt; 最有价值的地方，不是它名字特别，而是它把“对象自己的数据”这件事处理得很自然。&lt;/p&gt;
&lt;p&gt;只要你先把这条边界守住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;全局设置走 &lt;code&gt;Config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;对象字段走 &lt;code&gt;Metas&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;再把下面这条链路跑通：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;编辑页注入字段&lt;/li&gt;
&lt;li&gt;字段命名清楚&lt;/li&gt;
&lt;li&gt;前台正确读取&lt;/li&gt;
&lt;li&gt;空值有兜底&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面你做文章 SEO、文章封面、分类介绍、标签扩展，都会顺很多。&lt;/p&gt;
&lt;p&gt;下一篇我们继续攻最容易卡人的三块：路由、评论和 API。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:10:00 +0800</pubDate></item><item><title>Hook 到底怎么找、怎么用？先别死记名字</title><link>http://acmecontract.blog.lwenl.cn/?id=16</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-09.png&quot; alt=&quot;Hook 到底怎么找、怎么用？先别死记名字 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;很多人学 Z-BlogPHP 插件开发，卡的不是 PHP 语法，而是 Hook。&lt;/p&gt;
&lt;p&gt;最常见的状态是这样的：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;知道系统里有很多 Hook&lt;/li&gt;
&lt;li&gt;也知道插件离不开 Hook&lt;/li&gt;
&lt;li&gt;但一到真要改东西的时候，完全不知道该找哪个&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;于是就会出现两种极端：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;要么全站乱搜，越搜越晕&lt;/li&gt;
&lt;li&gt;要么开始死背 Hook 名字，最后还是不会用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其实 Hook 这件事，最重要的从来不是记忆力，而是分类能力。&lt;/p&gt;
&lt;p&gt;你只要先把需求归类，再去找对应 Hook 家族，效率会高很多。&lt;/p&gt;
&lt;h2&gt;一、先别把 Hook 想得太玄&lt;/h2&gt;
&lt;p&gt;在 Z-BlogPHP 里，Hook 可以先粗暴理解成一句话：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;系统在某个阶段，留了一个能让主题或插件插入逻辑的位置。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以 Hook 不是另外一套平行系统。&lt;/p&gt;
&lt;p&gt;它只是让你在：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;请求开始前后&lt;/li&gt;
&lt;li&gt;列表页渲染前后&lt;/li&gt;
&lt;li&gt;文章页渲染前后&lt;/li&gt;
&lt;li&gt;评论提交前后&lt;/li&gt;
&lt;li&gt;后台菜单、编辑页、表格输出时&lt;/li&gt;
&lt;li&gt;API 处理时&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些节点里，挂进自己的代码。&lt;/p&gt;
&lt;p&gt;你一旦这样理解，Hook 就没那么吓人了。&lt;/p&gt;
&lt;h2&gt;二、找 Hook 前，先问自己在改什么&lt;/h2&gt;
&lt;p&gt;这是最关键的一步。&lt;/p&gt;
&lt;p&gt;与其一上来问“有哪些 Hook”，不如先问：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;我是在改前台页面&lt;/li&gt;
&lt;li&gt;还是在改后台&lt;/li&gt;
&lt;li&gt;还是在改评论&lt;/li&gt;
&lt;li&gt;还是在改路由&lt;/li&gt;
&lt;li&gt;还是在改 API&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要这个问题先答清楚，搜索范围就会立刻缩小很多。&lt;/p&gt;
&lt;h2&gt;三、最常见的 Hook 家族，大致可以分成这几类&lt;/h2&gt;
&lt;h3&gt;1. 前台页面相关&lt;/h3&gt;
&lt;p&gt;如果你改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;文章页&lt;/li&gt;
&lt;li&gt;搜索页&lt;/li&gt;
&lt;li&gt;模板选择&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那优先关注前台视图相关 Hook。&lt;/p&gt;
&lt;p&gt;最常见的一组包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewSearch_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Template&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Template&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它们适合处理的方向大致是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;列表页数据准备&lt;/li&gt;
&lt;li&gt;文章页数据准备&lt;/li&gt;
&lt;li&gt;搜索结果处理&lt;/li&gt;
&lt;li&gt;页面模板切换&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. 后台相关&lt;/h3&gt;
&lt;p&gt;如果你改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后台菜单&lt;/li&gt;
&lt;li&gt;后台表格&lt;/li&gt;
&lt;li&gt;编辑页字段&lt;/li&gt;
&lt;li&gt;后台全局头尾&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就优先看后台 Hook 家族。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Admin_Header&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Admin_Footer&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Admin_TopMenu&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Admin_ArticleMng_Table&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Category_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Tag_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类 Hook 的价值非常高，因为很多后台扩展根本不需要改核心文件。&lt;/p&gt;
&lt;h3&gt;3. 请求和启动阶段相关&lt;/h3&gt;
&lt;p&gt;如果你改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由&lt;/li&gt;
&lt;li&gt;早期初始化&lt;/li&gt;
&lt;li&gt;权限拦截&lt;/li&gt;
&lt;li&gt;全局预处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就先看早期请求相关 Hook。&lt;/p&gt;
&lt;p&gt;最常见的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_Load&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_Load_Pre&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;其中最常见的一个用途，就是路由注册。&lt;/p&gt;
&lt;h3&gt;4. 评论相关&lt;/h3&gt;
&lt;p&gt;如果你改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论校验&lt;/li&gt;
&lt;li&gt;评论审核&lt;/li&gt;
&lt;li&gt;反垃圾&lt;/li&gt;
&lt;li&gt;评论错误处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就优先看评论 Hook。&lt;/p&gt;
&lt;p&gt;最常见的一组包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_PostComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_CheckComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_CheckComment_Succeed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Error_Handler&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;评论这一块常常不是模板问题，而是流程问题，所以很多时候真正该看的不是 &lt;code&gt;comments.php&lt;/code&gt;，而是这些 Hook。&lt;/p&gt;
&lt;h3&gt;5. API 相关&lt;/h3&gt;
&lt;p&gt;如果你改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;自定义 API 模块&lt;/li&gt;
&lt;li&gt;API 请求过滤&lt;/li&gt;
&lt;li&gt;API 返回数据调整&lt;/li&gt;
&lt;li&gt;CSRF 例外控制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就看 API Hook 家族。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_API_Extend_Mods&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_API_CheckMods&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_API_Result_Data&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_API_Response&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这组更偏进阶，但一旦做内部工具或对接系统，就会用得上。&lt;/p&gt;
&lt;h2&gt;四、最稳的找 Hook 方法，不是全站乱搜&lt;/h2&gt;
&lt;p&gt;我更建议按这个顺序来。&lt;/p&gt;
&lt;h3&gt;第一步，先在目标插件或主题里搜&lt;/h3&gt;
&lt;p&gt;比如先搜：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rg -n &amp;quot;RegisterPlugin|Add_Filter_Plugin|RegRoute&amp;quot; zb_users
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样做的好处是，你先看到当前项目里“已经在怎么挂接”。&lt;/p&gt;
&lt;p&gt;很多时候，现成写法比空背文档有用得多。&lt;/p&gt;
&lt;h3&gt;第二步，再按需求搜 Hook 家族&lt;/h3&gt;
&lt;p&gt;比如你在做评论，就搜：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rg -n &amp;quot;PostComment|CheckComment|Error_Handler&amp;quot; zb_users zb_system
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果你在做编辑页扩展，就搜：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-bash&quot;&gt;rg -n &amp;quot;Edit_Response|Category_Edit_Response|Tag_Edit_Response&amp;quot; zb_users zb_system
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;第三步，最后再去看平台定义&lt;/h3&gt;
&lt;p&gt;如果项目层还不够清楚，再看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;zb_system/function/c_system_plugin.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;相关参考文档&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时你带着问题去看，会比一上来翻平台文件有效得多。&lt;/p&gt;
&lt;h2&gt;五、看到 Hook 名字后，怎么判断它离需求近不近&lt;/h2&gt;
&lt;p&gt;不要只看名字像不像。&lt;/p&gt;
&lt;p&gt;更稳的判断方式是看三件事：&lt;/p&gt;
&lt;h3&gt;1. 它发生在前台还是后台&lt;/h3&gt;
&lt;p&gt;这决定了你是不是已经找错层。&lt;/p&gt;
&lt;h3&gt;2. 它发生在数据准备阶段还是模板输出阶段&lt;/h3&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;ViewList_Core&lt;/code&gt; 更像逻辑准备&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ViewPost_Template&lt;/code&gt; 更像模板选择&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. 它发生在提交前还是提交后&lt;/h3&gt;
&lt;p&gt;比如评论、保存、删除，这个顺序差别很大。&lt;/p&gt;
&lt;p&gt;你要做校验，通常挂“前”。&lt;/p&gt;
&lt;p&gt;你要做成功后的副作用，通常挂“后”。&lt;/p&gt;
&lt;h2&gt;六、别死记具体名字，先记住几个高价值入口&lt;/h2&gt;
&lt;p&gt;如果你刚开始，不必背完整表。&lt;/p&gt;
&lt;p&gt;先记这些就够用很多了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_Load&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Template&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Template&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Category_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Tag_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_PostComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些覆盖了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;路由&lt;/li&gt;
&lt;li&gt;启动&lt;/li&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;详情页&lt;/li&gt;
&lt;li&gt;模板切换&lt;/li&gt;
&lt;li&gt;编辑页字段&lt;/li&gt;
&lt;li&gt;评论流程&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;已经足够支撑很多常见开发了。&lt;/p&gt;
&lt;h2&gt;七、一个 Hook 的基本使用骨架长什么样&lt;/h2&gt;
&lt;p&gt;不管具体挂哪个 Hook，结构通常都长这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;RegisterPlugin(&amp;quot;MyPlugin&amp;quot;, &amp;quot;ActivePlugin_MyPlugin&amp;quot;);

function ActivePlugin_MyPlugin() {
    Add_Filter_Plugin(&amp;#39;Filter_Plugin_Zbp_Load&amp;#39;, &amp;#39;MyPlugin_Init&amp;#39;);
}

function MyPlugin_Init() {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你真正要替换的，其实只有两处：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;挂哪个 Hook&lt;/li&gt;
&lt;li&gt;处理函数具体做什么&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以 Hook 学不会，往往不是不会写这几行，而是还没有建立“需求 -&amp;gt; Hook 家族”的映射。&lt;/p&gt;
&lt;h2&gt;八、几种特别常见的需求，对应先看哪些 Hook&lt;/h2&gt;
&lt;h3&gt;想给文章编辑页加一个 SEO 字段&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想给分类编辑页加一个描述字段&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Category_Edit_Response&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想调整列表页渲染前的数据&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Core&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想给某些请求注册自定义路由&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;想拦评论、做反垃圾或审核&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_PostComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_CheckComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这就是为什么我一直说，Hook 更像一张地图，而不是一本词典。&lt;/p&gt;
&lt;h2&gt;九、最常见的 5 个误区&lt;/h2&gt;
&lt;h3&gt;1. 先背名字，再找场景&lt;/h3&gt;
&lt;p&gt;顺序反了。&lt;/p&gt;
&lt;h3&gt;2. 找到一个名字像的 Hook 就直接挂&lt;/h3&gt;
&lt;p&gt;不看阶段、不看上下文，后面很容易挂偏。&lt;/p&gt;
&lt;h3&gt;3. 一个问题只盯模板，不看 Hook&lt;/h3&gt;
&lt;p&gt;很多流程问题根本不在模板层。&lt;/p&gt;
&lt;h3&gt;4. 只搜 &lt;code&gt;zb_system&lt;/code&gt;，不先看项目代码&lt;/h3&gt;
&lt;p&gt;这样常常会把自己带得太深。&lt;/p&gt;
&lt;h3&gt;5. 看到 Hook 多就害怕&lt;/h3&gt;
&lt;p&gt;实际上你前期真正高频用到的，就是那几组。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;Hook 这件事，一旦从“背单词”切到“看地图”，难度会一下降很多。&lt;/p&gt;
&lt;p&gt;你真正要练出来的是这条路径：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先判断自己在改什么&lt;/li&gt;
&lt;li&gt;再锁定 Hook 家族&lt;/li&gt;
&lt;li&gt;再去搜当前项目写法&lt;/li&gt;
&lt;li&gt;最后才看平台定义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要这条路熟了，后面你写字段、写评论插件、写路由、写后台扩展，都会顺很多。&lt;/p&gt;
&lt;p&gt;下一篇我们继续讲 &lt;code&gt;Metas&lt;/code&gt; 和自定义字段，这正是 Hook 最常见、也最实用的一块落地场景。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:09:00 +0800</pubDate></item><item><title>Z-BlogPHP 插件开发入门：RegisterPlugin、Add_Filter_Plugin、main.php 怎么配合？先别急着背 Hook</title><link>http://acmecontract.blog.lwenl.cn/?id=15</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-08.png&quot; alt=&quot;Z-BlogPHP 插件开发入门：RegisterPlugin、Add_Filter_Plugin、main.php 怎么配合？先别急着背 Hook 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;如果说主题开发解决的是“站点怎么长”，那插件开发更像是在解决：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;站点某个流程怎么接管、怎么增强、怎么复用。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但很多人第一次学 Z-BlogPHP 插件时，会被几个点同时卡住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;plugin.xml&lt;/code&gt; 是做什么的&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegisterPlugin(...)&lt;/code&gt; 到底注册了什么&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Add_Filter_Plugin(...)&lt;/code&gt; 到底把逻辑挂到了哪&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt; 又为什么经常一起出现&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这篇就专门把插件开发最基础的骨架讲清楚。&lt;/p&gt;
&lt;h2&gt;一、先记住：插件不是换皮，插件是接流程&lt;/h2&gt;
&lt;p&gt;主题开发和插件开发最根本的差异，不是目录不同，而是职责不同。&lt;/p&gt;
&lt;p&gt;主题更偏：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面结构&lt;/li&gt;
&lt;li&gt;前台外观&lt;/li&gt;
&lt;li&gt;主题级配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;插件更偏：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;功能扩展&lt;/li&gt;
&lt;li&gt;流程插入&lt;/li&gt;
&lt;li&gt;后台增强&lt;/li&gt;
&lt;li&gt;评论和接口处理&lt;/li&gt;
&lt;li&gt;字段注入&lt;/li&gt;
&lt;li&gt;通用逻辑复用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你学插件开发时，脑子里要先切换一个视角：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;你不是在“写一个页面”，而是在“接管一个系统阶段”。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;二、一个最小可用插件，目录通常长这样&lt;/h2&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;zb_users/plugin/&amp;lt;plugin&amp;gt;/
├── plugin.xml
├── include.php
├── main.php
├── includes/
└── vendor/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你第一次做插件，不一定全都用上。&lt;/p&gt;
&lt;p&gt;但至少这三个位置，最好尽早理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;plugin.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;三、&lt;code&gt;plugin.xml&lt;/code&gt; 是插件元信息，不是行为实现层&lt;/h2&gt;
&lt;p&gt;它和主题里的 &lt;code&gt;theme.xml&lt;/code&gt; 很像，主要负责插件的基础身份信息。&lt;/p&gt;
&lt;p&gt;通常包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件 ID&lt;/li&gt;
&lt;li&gt;插件名称&lt;/li&gt;
&lt;li&gt;版本&lt;/li&gt;
&lt;li&gt;作者&lt;/li&gt;
&lt;li&gt;后台入口&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一个简化示意大概像这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;plugin version=&amp;quot;php&amp;quot;&amp;gt;
  &amp;lt;id&amp;gt;MyPlugin&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;My Plugin&amp;lt;/name&amp;gt;
  &amp;lt;note&amp;gt;一个用于演示 Hook 注册的插件&amp;lt;/note&amp;gt;
  &amp;lt;path&amp;gt;main.php&amp;lt;/path&amp;gt;
  &amp;lt;level&amp;gt;1&amp;lt;/level&amp;gt;
&amp;lt;/plugin&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里最重要的不是字段多复杂，而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件 ID 稳定&lt;/li&gt;
&lt;li&gt;目录名和 ID 尽量一致&lt;/li&gt;
&lt;li&gt;后台入口路径明确&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、&lt;code&gt;include.php&lt;/code&gt; 才是插件真正开始生效的地方&lt;/h2&gt;
&lt;p&gt;如果你想知道一个插件“到底从哪开始挂进系统”，答案通常就是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;include.php
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;因为插件最关键的两步，通常都会在这里开始：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;注册插件&lt;/li&gt;
&lt;li&gt;注册 Hook&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;最常见的入口骨架就是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;RegisterPlugin(&amp;quot;MyPlugin&amp;quot;, &amp;quot;ActivePlugin_MyPlugin&amp;quot;);

function ActivePlugin_MyPlugin() {
    Add_Filter_Plugin(&amp;#39;Filter_Plugin_Zbp_Load&amp;#39;, &amp;#39;MyPlugin_Init&amp;#39;);
}

function MyPlugin_Init() {
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段代码要怎么理解？&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;RegisterPlugin(...)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;它的意思可以简单理解成：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;告诉系统，这个插件的激活入口函数是谁。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;ActivePlugin_MyPlugin()&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这个函数通常是插件启用后开始挂接逻辑的地方。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;Add_Filter_Plugin(...)&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这个才是把具体行为挂到某个系统阶段里去。&lt;/p&gt;
&lt;p&gt;也就是说，真正的关键不只是“写一个函数”，而是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;把函数挂到对的阶段。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;五、为什么 &lt;code&gt;Add_Filter_Plugin(...)&lt;/code&gt; 是插件开发的核心&lt;/h2&gt;
&lt;p&gt;因为 Z-BlogPHP 的插件机制，很大一部分就是靠 Hook 驱动的。&lt;/p&gt;
&lt;p&gt;这意味着：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;你不需要改系统核心文件&lt;/li&gt;
&lt;li&gt;你不需要复制整条平台流程&lt;/li&gt;
&lt;li&gt;你只需要在合适的时机插进去&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这也是插件比硬改核心更稳的原因。&lt;/p&gt;
&lt;p&gt;比如你想做的事情可能是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论前做校验&lt;/li&gt;
&lt;li&gt;文章编辑页加字段&lt;/li&gt;
&lt;li&gt;后台列表多一列&lt;/li&gt;
&lt;li&gt;前台页面在某个阶段补充数据&lt;/li&gt;
&lt;li&gt;注册一个自定义路由&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些都不是“重写整个系统”，而是“找到正确 Hook 再挂进去”。&lt;/p&gt;
&lt;h2&gt;六、&lt;code&gt;main.php&lt;/code&gt; 在插件里通常负责什么&lt;/h2&gt;
&lt;p&gt;很多人第一次看插件，会误以为 &lt;code&gt;main.php&lt;/code&gt; 是主逻辑文件。&lt;/p&gt;
&lt;p&gt;其实它更像：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;插件的后台管理入口。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;最常见的职责包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权限检查&lt;/li&gt;
&lt;li&gt;插件启用检查&lt;/li&gt;
&lt;li&gt;表单保存&lt;/li&gt;
&lt;li&gt;配置项管理&lt;/li&gt;
&lt;li&gt;简单后台工具页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以一个插件的职责通常是这样分：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;plugin.xml&lt;/code&gt;：身份信息&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt;：挂接逻辑&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt;：后台设置和管理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要这层分工一清楚，插件目录就不会越写越乱。&lt;/p&gt;
&lt;h2&gt;七、一个“最小插件”可以先做成什么样&lt;/h2&gt;
&lt;p&gt;第一次写插件，不建议一上来就做特别重的东西。&lt;/p&gt;
&lt;p&gt;更稳的起点是做一个很小但路径完整的功能。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;给后台加一个设置页&lt;/li&gt;
&lt;li&gt;给前台某类页面挂一个小开关&lt;/li&gt;
&lt;li&gt;给文章页增加一个可配置提示区&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类需求的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;容易看出插件入口&lt;/li&gt;
&lt;li&gt;容易练到配置保存&lt;/li&gt;
&lt;li&gt;容易理解 Hook 是怎么插进去的&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;八、插件配置项怎么和主题配置项区分&lt;/h2&gt;
&lt;p&gt;它们保存方式很像，都是：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$zbp-&amp;gt;Config(&amp;#39;AppID&amp;#39;)-&amp;gt;SomeKey = $value;
$zbp-&amp;gt;SaveConfig(&amp;#39;AppID&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但职责不同。&lt;/p&gt;
&lt;h3&gt;更适合做成插件配置的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;API Key&lt;/li&gt;
&lt;li&gt;开关规则&lt;/li&gt;
&lt;li&gt;评论审核策略&lt;/li&gt;
&lt;li&gt;后台功能项&lt;/li&gt;
&lt;li&gt;复用模块参数&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;更适合做成主题配置的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;首页主标题&lt;/li&gt;
&lt;li&gt;默认缩略图&lt;/li&gt;
&lt;li&gt;页脚文案&lt;/li&gt;
&lt;li&gt;主题展示开关&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是说：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;和功能流程绑定的，更像插件配置。&lt;br&gt;和站点外观绑定的，更像主题配置。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;九、写插件时，先怎么判断应该挂哪个 Hook&lt;/h2&gt;
&lt;p&gt;很多新手不是不会写函数，而是不知道函数该挂哪。&lt;/p&gt;
&lt;p&gt;你可以先按需求类别判断：&lt;/p&gt;
&lt;h3&gt;要改前台页面准备逻辑&lt;/h3&gt;
&lt;p&gt;优先关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;相关视图阶段 Hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;要改模板选择或页面模板行为&lt;/h3&gt;
&lt;p&gt;优先关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewList_Template&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_ViewPost_Template&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;要改后台菜单、后台表格、编辑页&lt;/h3&gt;
&lt;p&gt;优先关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后台菜单 Hook&lt;/li&gt;
&lt;li&gt;后台表格 Hook&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Edit_Response&lt;/code&gt; 系列 Hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;要改评论流程&lt;/h3&gt;
&lt;p&gt;优先关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_PostComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_CheckComment_Core&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Error_Handler&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;要做路由或早期请求处理&lt;/h3&gt;
&lt;p&gt;优先关注：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_Load&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你会发现，插件开发最重要的技能之一，不是写多复杂，而是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;先把需求归类，再找 Hook 家族。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;十、什么时候应该把逻辑从主题里抽成插件&lt;/h2&gt;
&lt;p&gt;这是很多项目后期都会遇到的问题。&lt;/p&gt;
&lt;p&gt;如果某段逻辑开始出现这些特征，就该认真考虑插件化：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;多主题都可能复用&lt;/li&gt;
&lt;li&gt;不只影响模板结构&lt;/li&gt;
&lt;li&gt;涉及后台页面&lt;/li&gt;
&lt;li&gt;涉及评论、接口、校验、路由&lt;/li&gt;
&lt;li&gt;明显属于功能，不属于页面长相&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;反过来，如果某段逻辑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;强绑定当前主题&lt;/li&gt;
&lt;li&gt;只服务某个页面的视觉结构&lt;/li&gt;
&lt;li&gt;换主题就没有意义&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那它大概率还是主题职责。&lt;/p&gt;
&lt;h2&gt;十一、插件开发里最常见的 6 个坑&lt;/h2&gt;
&lt;h3&gt;1. &lt;code&gt;plugin.xml&lt;/code&gt; 只是建了，但没建立清晰入口&lt;/h3&gt;
&lt;p&gt;结果后面自己都找不到插件从哪开始生效。&lt;/p&gt;
&lt;h3&gt;2. Hook 注册和具体实现全塞一个超长文件&lt;/h3&gt;
&lt;p&gt;前期还好，后面会越来越难读。&lt;/p&gt;
&lt;h3&gt;3. 一开始就写过重插件&lt;/h3&gt;
&lt;p&gt;更好的起点是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先做一个完整的小功能&lt;/li&gt;
&lt;li&gt;先把注册、Hook、配置页跑通&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 把主题专属展示逻辑全抽成插件&lt;/h3&gt;
&lt;p&gt;最后职责会变得很拧巴。&lt;/p&gt;
&lt;h3&gt;5. 配置页能保存，但前台或流程根本没消费&lt;/h3&gt;
&lt;p&gt;这和主题配置项是同一个坑型。&lt;/p&gt;
&lt;h3&gt;6. 找 Hook 时不按家族找，直接硬搜全站&lt;/h3&gt;
&lt;p&gt;效率会很低。&lt;/p&gt;
&lt;h2&gt;十二、第一次写插件，建议你这样练&lt;/h2&gt;
&lt;p&gt;我更建议你用这个顺序练手：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;建插件目录&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;plugin.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;完成 &lt;code&gt;RegisterPlugin(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;挂一个最简单的 Hook&lt;/li&gt;
&lt;li&gt;新建 &lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;做一个最小设置项&lt;/li&gt;
&lt;li&gt;验证插件启用、保存、前台或后台生效&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;只要这条链路你跑通一次，后面再学评论插件、后台扩展插件、API 插件，都会容易很多。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 插件开发最重要的，不是先记住几十个 Hook 名字，而是先建立这套骨架理解：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;plugin.xml&lt;/code&gt; 负责身份&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt; 负责注册和挂接&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt; 负责后台设置和管理&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegisterPlugin(...)&lt;/code&gt; 负责告诉系统入口&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Add_Filter_Plugin(...)&lt;/code&gt; 负责把逻辑挂到正确阶段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你只要先把这套配合关系想明白，插件开发就已经真正入门了。&lt;/p&gt;
&lt;p&gt;下一篇我们专门讲 Hook 怎么找、怎么用，把这套挂接思路再往前推进一步。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:08:00 +0800</pubDate></item><item><title>主题配置项怎么做？从后台设置到前台输出，别只做表单不落地</title><link>http://acmecontract.blog.lwenl.cn/?id=14</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-07.png&quot; alt=&quot;主题配置项怎么做？从后台设置到前台输出，别只做表单不落地 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;很多主题第一版都喜欢把内容写死：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页标题写死&lt;/li&gt;
&lt;li&gt;默认缩略图写死&lt;/li&gt;
&lt;li&gt;CTA 文案写死&lt;/li&gt;
&lt;li&gt;页脚说明写死&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样起步快，但主题一旦要维护，就会很难受。&lt;/p&gt;
&lt;p&gt;因为你很快就会碰到这些问题：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;改一句首页文案还得改代码&lt;/li&gt;
&lt;li&gt;默认图片变了还得进模板找路径&lt;/li&gt;
&lt;li&gt;某个模块要不要显示，没法后台开关&lt;/li&gt;
&lt;li&gt;不同站点复用同一主题时，每次都得手工改文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以一个真正能用的主题，迟早要做配置项。&lt;/p&gt;
&lt;p&gt;这一篇我们就把这条链路讲完整：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;后台怎么做配置，配置怎么保存，前台又怎么把它用起来。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;一、先分清：什么东西适合做成主题配置&lt;/h2&gt;
&lt;p&gt;不是所有东西都该做成配置项。&lt;/p&gt;
&lt;p&gt;更适合做成主题配置的，通常是这些：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页主标题&lt;/li&gt;
&lt;li&gt;首页副标题&lt;/li&gt;
&lt;li&gt;默认缩略图&lt;/li&gt;
&lt;li&gt;页脚版权文案&lt;/li&gt;
&lt;li&gt;某个首页模块开关&lt;/li&gt;
&lt;li&gt;列表摘要长度&lt;/li&gt;
&lt;li&gt;主题级 SEO 默认值&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些东西有一个共同点：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;它们属于全局设置，而不是某篇文章自己的数据。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;所以它们更适合放进主题配置，而不是塞进文章字段里。&lt;/p&gt;
&lt;h2&gt;二、Z-BlogPHP 里，主题配置通常放在哪&lt;/h2&gt;
&lt;p&gt;主题或插件的全局配置，通常会走：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$zbp-&amp;gt;Config(&amp;#39;AppID&amp;#39;)-&amp;gt;SomeKey = $value;
$zbp-&amp;gt;SaveConfig(&amp;#39;AppID&amp;#39;);
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;读取时也很直接：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$value = $zbp-&amp;gt;Config(&amp;#39;AppID&amp;#39;)-&amp;gt;SomeKey;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这意味着你做主题配置时，核心其实就是三件事：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;后台给它一个表单入口&lt;/li&gt;
&lt;li&gt;保存时写进 &lt;code&gt;Config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;前台读取并参与渲染&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;三、从流程上看，主题配置项通常会经过这 4 步&lt;/h2&gt;
&lt;h3&gt;第 1 步：决定配置项长什么样&lt;/h3&gt;
&lt;p&gt;比如你准备先做这三个：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页主标题 &lt;code&gt;HomeHeroTitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;首页副标题 &lt;code&gt;HomeHeroSubtitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;默认缩略图 &lt;code&gt;DefaultThumb&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;先把名字定清楚，后面会省很多麻烦。&lt;/p&gt;
&lt;h3&gt;第 2 步：在后台设置页输出表单&lt;/h3&gt;
&lt;p&gt;也就是主题的 &lt;code&gt;main.php&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;第 3 步：保存时写入 &lt;code&gt;Config&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;保存逻辑通常还是在 &lt;code&gt;main.php&lt;/code&gt; 里。&lt;/p&gt;
&lt;h3&gt;第 4 步：前台模板或主题逻辑读取&lt;/h3&gt;
&lt;p&gt;最终常见落点会是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、后台设置页保存逻辑，最核心的是这几件事&lt;/h2&gt;
&lt;p&gt;主题后台页的保存逻辑，重点不是“表单长什么样”，而是流程要完整。&lt;/p&gt;
&lt;p&gt;比较稳的顺序通常是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;接收提交&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CheckIsRefererValid()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;读取表单值&lt;/li&gt;
&lt;li&gt;写入 &lt;code&gt;Config&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SaveConfig()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;需要时执行 &lt;code&gt;BuildTemplate()&lt;/code&gt; 或其他重建&lt;/li&gt;
&lt;li&gt;成功提示或跳转&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;一个简化示意大概像这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;if (count($_POST) &amp;gt; 0) {
    CheckIsRefererValid();

    $zbp-&amp;gt;Config(&amp;#39;MyTheme&amp;#39;)-&amp;gt;HomeHeroTitle = trim(GetVars(&amp;#39;HomeHeroTitle&amp;#39;, &amp;#39;POST&amp;#39;));
    $zbp-&amp;gt;Config(&amp;#39;MyTheme&amp;#39;)-&amp;gt;HomeHeroSubtitle = trim(GetVars(&amp;#39;HomeHeroSubtitle&amp;#39;, &amp;#39;POST&amp;#39;));
    $zbp-&amp;gt;Config(&amp;#39;MyTheme&amp;#39;)-&amp;gt;DefaultThumb = trim(GetVars(&amp;#39;DefaultThumb&amp;#39;, &amp;#39;POST&amp;#39;));

    $zbp-&amp;gt;SaveConfig(&amp;#39;MyTheme&amp;#39;);
    $zbp-&amp;gt;BuildTemplate();
    $zbp-&amp;gt;SetHint(&amp;#39;good&amp;#39;);
    Redirect(&amp;#39;./main.php&amp;#39;);
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;你会发现真正关键的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;提交安全校验&lt;/li&gt;
&lt;li&gt;配置写入&lt;/li&gt;
&lt;li&gt;保存&lt;/li&gt;
&lt;li&gt;重建&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这才是“配置项能落地”的骨架。&lt;/p&gt;
&lt;h2&gt;五、为什么保存配置时常常要 &lt;code&gt;CheckIsRefererValid()&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;很多人写后台保存逻辑时，容易把这一步忘掉。&lt;/p&gt;
&lt;p&gt;但它很重要。&lt;/p&gt;
&lt;p&gt;因为主题配置页本质上是后台写操作。&lt;/p&gt;
&lt;p&gt;只要是写操作，就不应该只是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;用户打开页面&lt;/li&gt;
&lt;li&gt;发个 POST&lt;/li&gt;
&lt;li&gt;系统就无条件保存&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;`CheckIsRefererValid()`` 的作用，可以理解成：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;给后台保存动作补一层基础校验。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;你后面写插件设置页时，这个习惯也同样重要。&lt;/p&gt;
&lt;h2&gt;六、什么时候要 &lt;code&gt;BuildTemplate()&lt;/code&gt;，什么时候不一定要&lt;/h2&gt;
&lt;p&gt;这也是很多人第一次做配置时容易迷糊的地方。&lt;/p&gt;
&lt;p&gt;如果一个设置会影响前台渲染结果，比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页标题&lt;/li&gt;
&lt;li&gt;模块显示&lt;/li&gt;
&lt;li&gt;页脚文案&lt;/li&gt;
&lt;li&gt;头部 meta&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那保存之后往往要考虑重建模板相关结果。&lt;/p&gt;
&lt;p&gt;这时常见就会用到：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;$zbp-&amp;gt;BuildTemplate();
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;如果改的是模块结构、缓存结果，还可能涉及：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;BuildModule()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SaveCache()&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你不用机械地每次都全重建，但至少要建立这个意识：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;保存成功，不等于前台立刻按你期待刷新。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;有些改动和模板、模块、缓存是有关联的。&lt;/p&gt;
&lt;h2&gt;七、前台怎么读取主题配置，才不会越写越乱&lt;/h2&gt;
&lt;p&gt;这里最容易犯的错是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;模板里到处直接读配置&lt;/li&gt;
&lt;li&gt;读不到时没有兜底&lt;/li&gt;
&lt;li&gt;同一个配置在多个模板写重复判断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更稳的写法一般有两种。&lt;/p&gt;
&lt;h3&gt;写法 1：模板直接读取简单值&lt;/h3&gt;
&lt;p&gt;如果逻辑非常简单，模板里直接读也可以：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;{php}
$heroTitle = $zbp-&amp;gt;Config(&amp;#39;MyTheme&amp;#39;)-&amp;gt;HomeHeroTitle;
{/php}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;但这种方式更适合很轻的场景。&lt;/p&gt;
&lt;h3&gt;写法 2：在 &lt;code&gt;include.php&lt;/code&gt; 里统一做兜底&lt;/h3&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-php&quot;&gt;function MyTheme_GetDefaultThumb() {
    global $zbp;
    $thumb = $zbp-&amp;gt;Config(&amp;#39;MyTheme&amp;#39;)-&amp;gt;DefaultThumb;
    return !empty($thumb) ? $thumb : $zbp-&amp;gt;host . &amp;#39;zb_users/theme/MyTheme/assets/default-cover.jpg&amp;#39;;
}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样前台模板拿到的是一个已经处理过的结果。&lt;/p&gt;
&lt;p&gt;只要配置项开始有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;默认值&lt;/li&gt;
&lt;li&gt;兜底逻辑&lt;/li&gt;
&lt;li&gt;路径拼接&lt;/li&gt;
&lt;li&gt;多模板复用&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;我都更建议你回到 &lt;code&gt;include.php&lt;/code&gt; 统一处理。&lt;/p&gt;
&lt;h2&gt;八、一个完整的配置示例该怎么想&lt;/h2&gt;
&lt;p&gt;假设你要做“首页主视觉配置”。&lt;/p&gt;
&lt;p&gt;这类需求通常包括：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主标题&lt;/li&gt;
&lt;li&gt;副标题&lt;/li&gt;
&lt;li&gt;主按钮文案&lt;/li&gt;
&lt;li&gt;是否显示该区块&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这时候最自然的拆法就是：&lt;/p&gt;
&lt;h3&gt;后台配置层&lt;/h3&gt;
&lt;p&gt;提供四个表单项：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;HomeHeroTitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HomeHeroSubtitle&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HomeHeroButtonText&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;HomeHeroEnabled&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;保存层&lt;/h3&gt;
&lt;p&gt;写入主题 &lt;code&gt;Config&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;前台消费层&lt;/h3&gt;
&lt;p&gt;在首页模板或相关辅助函数里做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;读值&lt;/li&gt;
&lt;li&gt;空值兜底&lt;/li&gt;
&lt;li&gt;开关判断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这样这套配置才算真正闭环。&lt;/p&gt;
&lt;h2&gt;九、主题配置和文章字段，不要混着用&lt;/h2&gt;
&lt;p&gt;这一点必须强调。&lt;/p&gt;
&lt;h3&gt;适合做主题配置的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;默认缩略图&lt;/li&gt;
&lt;li&gt;页脚文案&lt;/li&gt;
&lt;li&gt;首页大标题&lt;/li&gt;
&lt;li&gt;首页模块开关&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;不适合做主题配置的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;某一篇文章专属 SEO 标题&lt;/li&gt;
&lt;li&gt;某一篇文章专属封面图&lt;/li&gt;
&lt;li&gt;某个分类自己的描述&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些更适合用 &lt;code&gt;Metas&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;如果你把文章级数据硬塞进主题配置，后面编辑体验会非常糟糕。&lt;/p&gt;
&lt;h2&gt;十、做主题配置时最常见的 6 个坑&lt;/h2&gt;
&lt;h3&gt;1. 只做表单，不做前台消费&lt;/h3&gt;
&lt;p&gt;后台能保存，但前台根本没读。&lt;/p&gt;
&lt;h3&gt;2. 只做保存，不做默认值兜底&lt;/h3&gt;
&lt;p&gt;结果一旦配置为空，模板就开始出现空块。&lt;/p&gt;
&lt;h3&gt;3. 忘记 &lt;code&gt;CheckIsRefererValid()&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是后台保存流程里很容易漏的一步。&lt;/p&gt;
&lt;h3&gt;4. 保存后不重建相关结果&lt;/h3&gt;
&lt;p&gt;导致你误以为配置没生效。&lt;/p&gt;
&lt;h3&gt;5. 把复杂逻辑全塞模板里&lt;/h3&gt;
&lt;p&gt;前台一旦开始多处使用，维护会越来越痛。&lt;/p&gt;
&lt;h3&gt;6. 把对象级字段错做成主题全局设置&lt;/h3&gt;
&lt;p&gt;这会直接把内容编辑流程弄乱。&lt;/p&gt;
&lt;h2&gt;十一、做完配置项以后，至少这样验证&lt;/h2&gt;
&lt;p&gt;不要只看“后台保存成功”。&lt;/p&gt;
&lt;p&gt;至少要验证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 表单值能正确保存&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 刷新后台后能读回原值&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 前台确实读取到了配置&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 空值时有兜底&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 相关模板更新正常&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 多页面使用同一配置时结果一致&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这才是真正的“配置项做完了”。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;主题配置项的本质，不是做几个输入框，而是把：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;后台表单&lt;/li&gt;
&lt;li&gt;提交安全&lt;/li&gt;
&lt;li&gt;配置保存&lt;/li&gt;
&lt;li&gt;模板重建&lt;/li&gt;
&lt;li&gt;前台消费&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这一整条链路做通。&lt;/p&gt;
&lt;p&gt;只要你把这套闭环做顺了，后面再加首页配置、默认图、模块开关、SEO 默认值，就都会顺很多。&lt;/p&gt;
&lt;p&gt;下一篇我们进入插件开发入门，讲 &lt;code&gt;RegisterPlugin&lt;/code&gt;、&lt;code&gt;Add_Filter_Plugin&lt;/code&gt;、&lt;code&gt;main.php&lt;/code&gt; 这些东西到底怎么配合。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:07:00 +0800</pubDate></item><item><title>模板开发实战：首页、列表页、文章页、搜索页怎么拆？别全堆进一个文件</title><link>http://acmecontract.blog.lwenl.cn/?id=13</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-06.png&quot; alt=&quot;模板开发实战：首页、列表页、文章页、搜索页怎么拆？别全堆进一个文件 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;很多人开始做 Z-BlogPHP 主题以后，最先卡住的不是不会写 HTML，而是不会拆模板。&lt;/p&gt;
&lt;p&gt;最典型的几种乱法是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页、分类页、搜索页全堆进一个文件&lt;/li&gt;
&lt;li&gt;&lt;code&gt;header.php&lt;/code&gt; 里塞了一堆页面专属逻辑&lt;/li&gt;
&lt;li&gt;文章详情和独立页面共用一套结构，最后谁都不合适&lt;/li&gt;
&lt;li&gt;明明是逻辑问题，却在模板里反复复制判断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这篇我们就专门解决一件事：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Z-BlogPHP 模板到底该怎么拆，才能既跑得通，又好维护。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;一、先记住：模板拆分不是为了好看，是为了职责清楚&lt;/h2&gt;
&lt;p&gt;很多人理解“拆模板”，会下意识想到前端组件化。&lt;/p&gt;
&lt;p&gt;但在 Z-BlogPHP 里，更重要的不是炫技，而是三个目标：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;公共部分只写一次&lt;/li&gt;
&lt;li&gt;不同页面类型各有自己的位置&lt;/li&gt;
&lt;li&gt;页面结构和展示逻辑尽量不要混成一锅&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以模板拆分最核心的问题不是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;能不能拆得很细&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;而是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;哪一层是公共的&lt;/li&gt;
&lt;li&gt;哪一层是页面专属的&lt;/li&gt;
&lt;li&gt;哪些判断该留在模板，哪些该回逻辑层&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;二、最常见的几个模板文件，各自负责什么&lt;/h2&gt;
&lt;p&gt;在 Z-BlogPHP 主题里，最常用的一批模板文件通常是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;page.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;search.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以先把它们理解成下面这张职责图。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更像全站公共头部。&lt;/p&gt;
&lt;p&gt;适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 里的 title、meta、CSS&lt;/li&gt;
&lt;li&gt;公共导航&lt;/li&gt;
&lt;li&gt;站点头部结构&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更像全站公共尾部。&lt;/p&gt;
&lt;p&gt;适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页脚结构&lt;/li&gt;
&lt;li&gt;结尾脚本&lt;/li&gt;
&lt;li&gt;公共尾部信息&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更像列表页总入口。&lt;/p&gt;
&lt;p&gt;通常承接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页&lt;/li&gt;
&lt;li&gt;分类页&lt;/li&gt;
&lt;li&gt;标签页&lt;/li&gt;
&lt;li&gt;作者页&lt;/li&gt;
&lt;li&gt;日期页&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;更像文章详情页。&lt;/p&gt;
&lt;p&gt;通常承接：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章标题&lt;/li&gt;
&lt;li&gt;元信息&lt;/li&gt;
&lt;li&gt;正文&lt;/li&gt;
&lt;li&gt;标签&lt;/li&gt;
&lt;li&gt;评论区&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;page.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;如果你单独做它，通常给独立页面用。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;search.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;专门处理搜索结果。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;专门处理评论列表和评论表单。&lt;/p&gt;
&lt;h2&gt;三、首页和列表页，为什么通常从 &lt;code&gt;index.php&lt;/code&gt; 起步&lt;/h2&gt;
&lt;p&gt;很多主题的 &lt;code&gt;index.php&lt;/code&gt; 不只是首页。&lt;/p&gt;
&lt;p&gt;它经常还负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;分类列表&lt;/li&gt;
&lt;li&gt;标签列表&lt;/li&gt;
&lt;li&gt;作者列表&lt;/li&gt;
&lt;li&gt;日期归档&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以 &lt;code&gt;index.php&lt;/code&gt; 常常是“列表型页面”的总入口。&lt;/p&gt;
&lt;p&gt;这类页面的共性通常有：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;都要展示文章列表&lt;/li&gt;
&lt;li&gt;都要有分页&lt;/li&gt;
&lt;li&gt;都会有卡片或摘要结构&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;因此你拆的时候，可以先做一层共同结构，再按页面类型做小分支。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{template:header}

&amp;lt;main class=&amp;quot;archive-main&amp;quot;&amp;gt;
  {if $type==&amp;#39;index&amp;#39;}
    &amp;lt;h1&amp;gt;最新文章&amp;lt;/h1&amp;gt;
  {elseif $type==&amp;#39;category&amp;#39;}
    &amp;lt;h1&amp;gt;{$category.Name}&amp;lt;/h1&amp;gt;
  {elseif $type==&amp;#39;tag&amp;#39;}
    &amp;lt;h1&amp;gt;{$tag.Name}&amp;lt;/h1&amp;gt;
  {else}
    &amp;lt;h1&amp;gt;文章列表&amp;lt;/h1&amp;gt;
  {/if}

  {foreach $articles as $article}
    &amp;lt;article class=&amp;quot;post-card&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;{$article.Url}&amp;quot;&amp;gt;{$article.Title}&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;{$article.Intro}&amp;lt;/p&amp;gt;
    &amp;lt;/article&amp;gt;
  {/foreach}
&amp;lt;/main&amp;gt;

{template:footer}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这个写法的关键不在于样式，而在于：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;结构是共用的&lt;/li&gt;
&lt;li&gt;页面类型差异只留在必要分支里&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、文章页为什么应该尽量独立给 &lt;code&gt;single.php&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;详情页和列表页的目标完全不一样。&lt;/p&gt;
&lt;p&gt;列表页更强调：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;扫读&lt;/li&gt;
&lt;li&gt;跳转&lt;/li&gt;
&lt;li&gt;比较&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详情页更强调：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;阅读&lt;/li&gt;
&lt;li&gt;结构完整&lt;/li&gt;
&lt;li&gt;评论和延伸信息&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以文章页最好别混进 &lt;code&gt;index.php&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;一个最小的 &lt;code&gt;single.php&lt;/code&gt; 大致可以这样起步：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{template:header}

&amp;lt;article class=&amp;quot;post-single&amp;quot;&amp;gt;
  &amp;lt;header class=&amp;quot;post-header&amp;quot;&amp;gt;
    &amp;lt;h1&amp;gt;{$article.Title}&amp;lt;/h1&amp;gt;
    &amp;lt;div class=&amp;quot;post-meta&amp;quot;&amp;gt;
      &amp;lt;span&amp;gt;{$article.Author.Name}&amp;lt;/span&amp;gt;
      &amp;lt;span&amp;gt;{$article.Time(&amp;#39;Y-m-d&amp;#39;)}&amp;lt;/span&amp;gt;
    &amp;lt;/div&amp;gt;
  &amp;lt;/header&amp;gt;

  &amp;lt;div class=&amp;quot;post-content&amp;quot;&amp;gt;
    {$article.Content}
  &amp;lt;/div&amp;gt;

  {template:comments}
&amp;lt;/article&amp;gt;

{template:footer}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是一个清晰的详情页骨架：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;头部信息&lt;/li&gt;
&lt;li&gt;正文区域&lt;/li&gt;
&lt;li&gt;评论区域&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面再慢慢补：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;相关推荐&lt;/li&gt;
&lt;li&gt;目录&lt;/li&gt;
&lt;li&gt;作者卡片&lt;/li&gt;
&lt;li&gt;广告位&lt;/li&gt;
&lt;li&gt;下载区&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;五、搜索页最好单独拆，不要完全依赖列表页回落&lt;/h2&gt;
&lt;p&gt;有些主题没有单独的 &lt;code&gt;search.php&lt;/code&gt;，搜索结果会直接用 &lt;code&gt;index.php&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;能跑，但不够清楚。&lt;/p&gt;
&lt;p&gt;因为搜索页通常至少有两件事和普通列表页不一样：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;标题应该说明当前是搜索结果&lt;/li&gt;
&lt;li&gt;空结果时要有专属提示&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;所以只要你打算认真做内容站，搜索页最好独立出来。&lt;/p&gt;
&lt;p&gt;例如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{template:header}

&amp;lt;main class=&amp;quot;search-main&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;搜索结果&amp;lt;/h1&amp;gt;

  {if count($articles)&amp;gt;0}
    {foreach $articles as $article}
      &amp;lt;article class=&amp;quot;post-card&amp;quot;&amp;gt;
        &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;{$article.Url}&amp;quot;&amp;gt;{$article.Title}&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;
      &amp;lt;/article&amp;gt;
    {/foreach}
  {else}
    &amp;lt;p&amp;gt;没有找到相关内容，请尝试更换关键词。&amp;lt;/p&amp;gt;
  {/if}
&amp;lt;/main&amp;gt;

{template:footer}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这样后面你做搜索体验优化时，落点就非常明确。&lt;/p&gt;
&lt;h2&gt;六、公共区域怎么拆，才不会越拆越乱&lt;/h2&gt;
&lt;p&gt;模板拆分不是越碎越好。&lt;/p&gt;
&lt;p&gt;很多人一开始就拆十几个片段，最后自己都找不到页面结构。&lt;/p&gt;
&lt;p&gt;更稳的顺序是：&lt;/p&gt;
&lt;h3&gt;第一层，先拆全站公共部分&lt;/h3&gt;
&lt;p&gt;通常就是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第二层，再拆高频复用区&lt;/h3&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;sidebar.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;navbar.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第三层，最后才拆页面内部片段&lt;/h3&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;列表卡片片段&lt;/li&gt;
&lt;li&gt;文章头部片段&lt;/li&gt;
&lt;li&gt;相关推荐片段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;除非你的主题已经比较成熟，否则不要一开始拆得过细。&lt;/p&gt;
&lt;h2&gt;七、模板里哪些逻辑可以留，哪些应该回 &lt;code&gt;include.php&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;这是模板开发最常见的边界问题。&lt;/p&gt;
&lt;h3&gt;可以留在模板里的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;页面类型分支&lt;/li&gt;
&lt;li&gt;显示与否判断&lt;/li&gt;
&lt;li&gt;遍历列表&lt;/li&gt;
&lt;li&gt;结构顺序控制&lt;/li&gt;
&lt;li&gt;少量显示相关条件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页显示大标题，分类页显示分类名&lt;/li&gt;
&lt;li&gt;有图就显示图，没有图就显示占位&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这类判断留模板里通常没问题。&lt;/p&gt;
&lt;h3&gt;更适合回 &lt;code&gt;include.php&lt;/code&gt; 的&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;复用的缩略图逻辑&lt;/li&gt;
&lt;li&gt;复用的摘要截断逻辑&lt;/li&gt;
&lt;li&gt;复用的时间格式逻辑&lt;/li&gt;
&lt;li&gt;需要读配置再计算的派生值&lt;/li&gt;
&lt;li&gt;多个模板都会用到的业务判断&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;模板保留“怎么显示”，逻辑层负责“显示什么结果更合适”。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;八、一个更实战的拆法思路&lt;/h2&gt;
&lt;p&gt;如果你现在要做一个内容站主题，建议按下面顺序拆：&lt;/p&gt;
&lt;h3&gt;第一步&lt;/h3&gt;
&lt;p&gt;先把：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;跑通。&lt;/p&gt;
&lt;h3&gt;第二步&lt;/h3&gt;
&lt;p&gt;把搜索页单独拆成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;search.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第三步&lt;/h3&gt;
&lt;p&gt;把评论区单独拆成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;第四步&lt;/h3&gt;
&lt;p&gt;如果分类页、标签页和首页差异越来越大，再考虑：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;category.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;tag.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;或者在 &lt;code&gt;index.php&lt;/code&gt; 里做更清楚的分支。&lt;/p&gt;
&lt;h2&gt;九、模板开发里最常见的 6 个坑&lt;/h2&gt;
&lt;h3&gt;1. 把所有页面都压进 &lt;code&gt;index.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;短期省事，后面最难维护。&lt;/p&gt;
&lt;h3&gt;2. 在 &lt;code&gt;header.php&lt;/code&gt; 写页面专属结构&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;header.php&lt;/code&gt; 更适合全站共用内容，不适合塞一堆详情页专属区块。&lt;/p&gt;
&lt;h3&gt;3. 把复用逻辑复制到多个模板&lt;/h3&gt;
&lt;p&gt;一旦缩略图、摘要、时间格式需要统一调整，就会很痛。&lt;/p&gt;
&lt;h3&gt;4. 搜索页没有独立处理空结果&lt;/h3&gt;
&lt;p&gt;对内容站来说，体验和 SEO 都不够好。&lt;/p&gt;
&lt;h3&gt;5. 评论区逻辑和详情页混写过重&lt;/h3&gt;
&lt;p&gt;后面调评论交互、审核提示、回复结构时会非常累。&lt;/p&gt;
&lt;h3&gt;6. 页面结构刚有点复杂，就开始无限拆片段&lt;/h3&gt;
&lt;p&gt;拆得过早、过碎，也会让主题越来越难看懂。&lt;/p&gt;
&lt;h2&gt;十、模板开发完成后，至少这样验证&lt;/h2&gt;
&lt;p&gt;写完模板以后，建议不要只看首页。&lt;/p&gt;
&lt;p&gt;至少要逐个验证：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 首页&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 分类页&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 标签页&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 文章详情页&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 搜索页&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 没有搜索结果时的状态&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 评论区是否正常显示&lt;/li&gt;
&lt;li&gt;&lt;input disabled=&quot;&quot; type=&quot;checkbox&quot;&gt; 头部资源和尾部脚本是否正确加载&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只要你开始把验证范围从“首页能开”扩大到“各页面类型都跑一遍”，模板问题会少很多。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 模板开发最重要的，不是把页面写出来，而是把页面类型和职责拆清楚。&lt;/p&gt;
&lt;p&gt;你只要先把下面这套思路立住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公共头尾单独拆&lt;/li&gt;
&lt;li&gt;列表页从 &lt;code&gt;index.php&lt;/code&gt; 起&lt;/li&gt;
&lt;li&gt;详情页从 &lt;code&gt;single.php&lt;/code&gt; 起&lt;/li&gt;
&lt;li&gt;搜索页最好单独拆&lt;/li&gt;
&lt;li&gt;评论区尽量独立&lt;/li&gt;
&lt;li&gt;复用逻辑别在模板里到处复制&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面模板越写越多，结构也不容易失控。&lt;/p&gt;
&lt;p&gt;下一篇我们继续讲主题配置项，怎么从后台设置，一路走到前台输出。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:06:00 +0800</pubDate></item><item><title>从零认识 Z-BlogPHP 主题开发：先搭最小骨架，再谈首页效果</title><link>http://acmecontract.blog.lwenl.cn/?id=12</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-05.png&quot; alt=&quot;从零认识 Z-BlogPHP 主题开发：先搭最小骨架，再谈首页效果 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;前面几篇我们已经把环境、运行流程、文件职责讲清了。现在终于可以进入很多人最关心的部分：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Z-BlogPHP 主题到底怎么开始写？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;但这里我不打算一上来就讲复杂首页，也不打算直接把一堆模板文件摊给你。&lt;/p&gt;
&lt;p&gt;更好的起点是先回答这件事：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;一个“最小可用”的 Z-BlogPHP 主题，结构应该长什么样？&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;只要这层搞明白，后面你再加首页、分类页、文章页、设置页，都会有地方可落。&lt;/p&gt;
&lt;h2&gt;一、先建立一个正确预期：主题不是只有模板&lt;/h2&gt;
&lt;p&gt;很多新手第一次做主题，会把主题理解成：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;几个 HTML 页面&lt;/li&gt;
&lt;li&gt;一份 CSS&lt;/li&gt;
&lt;li&gt;一点头部和页脚&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这当然是主题的一部分，但不完整。&lt;/p&gt;
&lt;p&gt;一个真正能长期维护的 Z-BlogPHP 主题，至少要同时承接这几件事：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题元信息&lt;/li&gt;
&lt;li&gt;前台模板输出&lt;/li&gt;
&lt;li&gt;主题逻辑&lt;/li&gt;
&lt;li&gt;主题后台设置&lt;/li&gt;
&lt;li&gt;样式和脚本资源&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以你后面写主题时，思路一定不要停在“拼页面”。&lt;/p&gt;
&lt;p&gt;更准确一点，主题是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;前台外观 + 一部分展示逻辑 + 一部分主题级配置能力。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;二、最小可用主题结构，先看这一版&lt;/h2&gt;
&lt;p&gt;如果你要从零搭一个最小可用主题，建议至少准备到这个层级：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;zb_users/theme/&amp;lt;theme&amp;gt;/
├── theme.xml
├── include.php
├── main.php
├── template/
│   ├── header.php
│   ├── footer.php
│   ├── index.php
│   └── single.php
├── style/
│   └── style.css
├── script/
└── assets/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这是一个很实用的最小骨架。&lt;/p&gt;
&lt;p&gt;为什么说它够用？&lt;/p&gt;
&lt;p&gt;因为它已经覆盖了：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题声明&lt;/li&gt;
&lt;li&gt;主题逻辑入口&lt;/li&gt;
&lt;li&gt;后台设置入口&lt;/li&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;详情页&lt;/li&gt;
&lt;li&gt;公共头尾&lt;/li&gt;
&lt;li&gt;基本样式&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;对一个开发起点来说，这已经足够往上继续长。&lt;/p&gt;
&lt;h2&gt;三、&lt;code&gt;theme.xml&lt;/code&gt; 是主题的身份证&lt;/h2&gt;
&lt;p&gt;很多人刚开始做主题，最容易忽略这个文件。&lt;/p&gt;
&lt;p&gt;但从系统角度看，主题先得“被识别为一个主题”，后面才谈得上启用和管理。&lt;/p&gt;
&lt;p&gt;&lt;code&gt;theme.xml&lt;/code&gt; 主要负责这些信息：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题 ID&lt;/li&gt;
&lt;li&gt;主题名称&lt;/li&gt;
&lt;li&gt;描述&lt;/li&gt;
&lt;li&gt;作者&lt;/li&gt;
&lt;li&gt;后台入口路径&lt;/li&gt;
&lt;li&gt;逻辑入口文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你可以把它理解成：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;系统先读到这里，才知道这个目录里的东西是个主题。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;一个简化后的示意结构，大概像这样：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-xml&quot;&gt;&amp;lt;?xml version=&amp;quot;1.0&amp;quot; encoding=&amp;quot;utf-8&amp;quot;?&amp;gt;
&amp;lt;theme version=&amp;quot;php&amp;quot;&amp;gt;
  &amp;lt;id&amp;gt;MyTheme&amp;lt;/id&amp;gt;
  &amp;lt;name&amp;gt;My Theme&amp;lt;/name&amp;gt;
  &amp;lt;note&amp;gt;一个用于内容站开发的示例主题&amp;lt;/note&amp;gt;
  &amp;lt;path&amp;gt;main.php&amp;lt;/path&amp;gt;
  &amp;lt;include&amp;gt;include.php&amp;lt;/include&amp;gt;
  &amp;lt;level&amp;gt;1&amp;lt;/level&amp;gt;
  &amp;lt;author&amp;gt;
    &amp;lt;name&amp;gt;Your Name&amp;lt;/name&amp;gt;
  &amp;lt;/author&amp;gt;
&amp;lt;/theme&amp;gt;
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这里最重要的不是把所有字段背下来，而是知道：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题 ID 要稳定&lt;/li&gt;
&lt;li&gt;目录名最好和主题 ID 保持一致&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt; 和后台入口会在这里挂上&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;四、为什么我建议一开始就保留 &lt;code&gt;include.php&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;有些人做第一个主题时，会想：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先不写逻辑&lt;/li&gt;
&lt;li&gt;先只做模板&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt; 以后再说&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;理论上可以，但实践里不推荐。&lt;/p&gt;
&lt;p&gt;原因很简单：&lt;/p&gt;
&lt;p&gt;只要你的主题开始做下面任意一件事，&lt;code&gt;include.php&lt;/code&gt; 很快就会变得必要：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;注册主题逻辑&lt;/li&gt;
&lt;li&gt;放通用辅助函数&lt;/li&gt;
&lt;li&gt;读取主题配置&lt;/li&gt;
&lt;li&gt;条件加载资源&lt;/li&gt;
&lt;li&gt;做多模板复用逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以最稳的做法是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;即使第一版逻辑很少，也先把 &lt;code&gt;include.php&lt;/code&gt; 这个入口留好。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;后面才不会越写越散。&lt;/p&gt;
&lt;h2&gt;五、&lt;code&gt;main.php&lt;/code&gt; 为什么也建议尽早留出来&lt;/h2&gt;
&lt;p&gt;很多新手第一版主题还没开始做设置，就把 &lt;code&gt;main.php&lt;/code&gt; 省掉了。&lt;/p&gt;
&lt;p&gt;这也不是完全不行，但如果你想让主题具备基本维护能力，后台入口最好尽早留着。&lt;/p&gt;
&lt;p&gt;因为很快你就会遇到这类需求：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页主标题可配置&lt;/li&gt;
&lt;li&gt;默认缩略图可配置&lt;/li&gt;
&lt;li&gt;列表页摘要长度可配置&lt;/li&gt;
&lt;li&gt;页脚文案可配置&lt;/li&gt;
&lt;li&gt;某个模块开关可配置&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些都不适合硬编码写死。&lt;/p&gt;
&lt;p&gt;所以 &lt;code&gt;main.php&lt;/code&gt; 的意义不是“把后台做复杂”，而是给主题预留一个能进化的设置入口。&lt;/p&gt;
&lt;h2&gt;六、模板目录最少先准备哪些文件&lt;/h2&gt;
&lt;p&gt;如果是第一版主题，我建议先准备这四个：&lt;/p&gt;
&lt;h3&gt;1. &lt;code&gt;header.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文档头部&lt;/li&gt;
&lt;li&gt;全局 CSS&lt;/li&gt;
&lt;li&gt;站点头部结构&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{$header}&lt;/code&gt; 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;2. &lt;code&gt;footer.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公共页脚&lt;/li&gt;
&lt;li&gt;全局尾部脚本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{$footer}&lt;/code&gt; 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. &lt;code&gt;index.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页&lt;/li&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;常见归档页&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. &lt;code&gt;single.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章详情页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;只靠这四个文件，你就已经可以做出一个最小可用主题。&lt;/p&gt;
&lt;p&gt;后面再按需要补：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;page.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;search.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;404.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;侧栏或导航模板&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;七、最小模板组合应该怎么写&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 的模板开发，不是把所有页面写进一个大文件里。&lt;/p&gt;
&lt;p&gt;更常见的做法，是拆公共部分再组合。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{template:header}

&amp;lt;main class=&amp;quot;site-main&amp;quot;&amp;gt;
  {foreach $articles as $article}
    &amp;lt;article class=&amp;quot;post-card&amp;quot;&amp;gt;
      &amp;lt;h2&amp;gt;&amp;lt;a href=&amp;quot;{$article.Url}&amp;quot;&amp;gt;{$article.Title}&amp;lt;/a&amp;gt;&amp;lt;/h2&amp;gt;
      &amp;lt;p&amp;gt;{$article.Intro}&amp;lt;/p&amp;gt;
    &amp;lt;/article&amp;gt;
  {/foreach}
&amp;lt;/main&amp;gt;

{template:footer}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这段结构的重点不是样式，而是思路：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;头尾独立&lt;/li&gt;
&lt;li&gt;页面主体独立&lt;/li&gt;
&lt;li&gt;列表循环直接使用模板变量&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;详情页也类似：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-html&quot;&gt;{template:header}

&amp;lt;article class=&amp;quot;post-single&amp;quot;&amp;gt;
  &amp;lt;h1&amp;gt;{$article.Title}&amp;lt;/h1&amp;gt;
  &amp;lt;div class=&amp;quot;post-content&amp;quot;&amp;gt;{$article.Content}&amp;lt;/div&amp;gt;
&amp;lt;/article&amp;gt;

{template:footer}
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这就是“最小主题”的真实出发点。&lt;/p&gt;
&lt;h2&gt;八、样式和脚本目录为什么也别省&lt;/h2&gt;
&lt;p&gt;有些人图快，会把：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;CSS&lt;/li&gt;
&lt;li&gt;JS&lt;/li&gt;
&lt;li&gt;图片&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;全塞在一个地方。&lt;/p&gt;
&lt;p&gt;短期能跑，长期很乱。&lt;/p&gt;
&lt;p&gt;哪怕是最小主题，也建议先分清这三层：&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;style/&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;放主题主样式和拆分样式。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;script/&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;放主题自己的前端脚本。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;assets/&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;放图标、图片、字体、通用静态资源。&lt;/p&gt;
&lt;p&gt;这不是形式主义，而是为了以后你做：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;资源按需加载&lt;/li&gt;
&lt;li&gt;样式拆分&lt;/li&gt;
&lt;li&gt;多页面资源管理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;时不至于返工。&lt;/p&gt;
&lt;h2&gt;九、主题开发时，哪些逻辑一开始就别写太重&lt;/h2&gt;
&lt;p&gt;第一次做主题，最容易过度设计。&lt;/p&gt;
&lt;p&gt;下面这些东西，建议你第一版不要一上来就做太复杂：&lt;/p&gt;
&lt;h3&gt;1. 把所有页面类型一次写全&lt;/h3&gt;
&lt;p&gt;先让：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;详情页&lt;/li&gt;
&lt;li&gt;公共头尾&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;跑通，更重要。&lt;/p&gt;
&lt;h3&gt;2. 把所有派生逻辑塞模板里&lt;/h3&gt;
&lt;p&gt;如果缩略图、摘要、时间格式这些逻辑开始复杂，尽早回 &lt;code&gt;include.php&lt;/code&gt;。&lt;/p&gt;
&lt;h3&gt;3. 过早造很多抽象层&lt;/h3&gt;
&lt;p&gt;Z-BlogPHP 主题开发本来就偏直接。&lt;/p&gt;
&lt;p&gt;第一版结构清楚，比抽象漂亮更重要。&lt;/p&gt;
&lt;h3&gt;4. 一开始就做一堆主题设置&lt;/h3&gt;
&lt;p&gt;建议先把真正需要编辑的 2 到 3 个全局设置做好，其他等页面稳定再加。&lt;/p&gt;
&lt;h2&gt;十、一个更稳的主题起步顺序&lt;/h2&gt;
&lt;p&gt;如果你准备从零做一个主题，我建议按这个顺序：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先建好目录骨架&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;theme.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;留出 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;留出 &lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;header.php&lt;/code&gt; 和 &lt;code&gt;footer.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;写 &lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;接主样式&lt;/li&gt;
&lt;li&gt;再补搜索、评论、404、独立页面&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;这个顺序的好处是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;系统能先识别主题&lt;/li&gt;
&lt;li&gt;结构先站住&lt;/li&gt;
&lt;li&gt;列表和详情这两条主线先跑通&lt;/li&gt;
&lt;li&gt;后面再继续增量开发&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;十一、第一次做主题最常见的 5 个坑&lt;/h2&gt;
&lt;h3&gt;1. 只有模板，没有逻辑入口&lt;/h3&gt;
&lt;p&gt;后面一加配置和复用逻辑就开始乱。&lt;/p&gt;
&lt;h3&gt;2. 一开始就把 &lt;code&gt;index.php&lt;/code&gt; 写成大杂烩&lt;/h3&gt;
&lt;p&gt;更好的方式是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;先把结构跑通&lt;/li&gt;
&lt;li&gt;再拆公共片段&lt;/li&gt;
&lt;li&gt;再把复用逻辑抽回 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;3. &lt;code&gt;theme.xml&lt;/code&gt; 和目录名不稳定&lt;/h3&gt;
&lt;p&gt;后面维护和迁移都容易出问题。&lt;/p&gt;
&lt;h3&gt;4. 样式、脚本、图片混放&lt;/h3&gt;
&lt;p&gt;短期看不出问题，后面资源会越来越难管。&lt;/p&gt;
&lt;h3&gt;5. 主题职责和插件职责混在一起&lt;/h3&gt;
&lt;p&gt;前台外观是主题主战场。&lt;/p&gt;
&lt;p&gt;评论校验、后台扩展、通用流程接管，不要一股脑都塞进主题。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 主题开发的起点，不是“先做一个很好看的首页”，而是先搭一个职责清晰、能继续生长的最小骨架。&lt;/p&gt;
&lt;p&gt;你只要先把下面这套结构立住：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;theme.xml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/footer.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/single.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;style/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;script/&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;assets/&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面加页面、加配置、加逻辑，都会顺很多。&lt;/p&gt;
&lt;p&gt;下一篇我们继续往前走，专门讲模板开发实战：首页、列表页、文章页、搜索页，到底应该怎么拆。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:05:00 +0800</pubDate></item><item><title>学 Z-BlogPHP 开发，先建立这张文件职责表：别把代码写错层</title><link>http://acmecontract.blog.lwenl.cn/?id=11</link><description>&lt;p&gt;&lt;img src=&quot;http://acmecontract.blog.lwenl.cn/zb_users/upload/2026/05/zblog-dev-04.png&quot; alt=&quot;学 Z-BlogPHP 开发，先建立这张文件职责表：别把代码写错层 配图&quot;&gt;&lt;/p&gt;
&lt;p&gt;很多人学 Z-BlogPHP，前面环境也搭好了，运行流程也知道一点，但一真正开始改需求，还是会很乱。&lt;/p&gt;
&lt;p&gt;乱的根源通常不是不会写代码，而是不知道：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;这个需求该落主题还是插件&lt;/li&gt;
&lt;li&gt;该改模板还是改 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;该去后台设置页，还是直接做成文章字段&lt;/li&gt;
&lt;li&gt;该写在 &lt;code&gt;header.php&lt;/code&gt;，还是写在 &lt;code&gt;single.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;所以这一篇的目标很明确：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;先建立一张“文件职责表”，让你以后看到需求时，先能找到正确落点。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;这件事比你背多少函数都更重要。&lt;/p&gt;
&lt;h2&gt;一、先记住一个总原则：改最小、改对层&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 开发最容易犯的错误，不是完全不会写，而是“明明能改对地方，却偏偏改到了更重的一层”。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;本来改模板就够了，却写成插件&lt;/li&gt;
&lt;li&gt;本来改主题逻辑就够了，却改进核心&lt;/li&gt;
&lt;li&gt;本来应该做成全局配置，却做成每篇文章都要填&lt;/li&gt;
&lt;li&gt;本来只是后台表单保存，却硬塞到前台模板里&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;更稳的原则是：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;先找真正拥有这个行为的文件&lt;/li&gt;
&lt;li&gt;只改最小那一层&lt;/li&gt;
&lt;li&gt;能不跨层就不跨层&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;你后面会发现，很多维护成本，不是功能本身造成的，而是落点选错造成的。&lt;/p&gt;
&lt;h2&gt;二、主题开发里，最常见的几个文件分别干什么&lt;/h2&gt;
&lt;p&gt;先看主题目录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;zb_users/theme/&amp;lt;theme&amp;gt;/
├── theme.xml
├── include.php
├── main.php
├── template/
├── style/
├── script/
└── assets/
&lt;/code&gt;&lt;/pre&gt;
&lt;p&gt;这几个位置里，最常碰到的是前四个。&lt;/p&gt;
&lt;h3&gt;1. &lt;code&gt;theme.xml&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是主题元信息文件。&lt;/p&gt;
&lt;p&gt;它更像“主题身份证”，而不是业务逻辑文件。&lt;/p&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题 ID&lt;/li&gt;
&lt;li&gt;名称&lt;/li&gt;
&lt;li&gt;作者信息&lt;/li&gt;
&lt;li&gt;后台入口路径&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt; 入口声明&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候看它？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;想确认主题基本信息&lt;/li&gt;
&lt;li&gt;想确认后台设置入口&lt;/li&gt;
&lt;li&gt;想确认主题引用了哪个入口文件&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候不该优先改它？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前台布局问题&lt;/li&gt;
&lt;li&gt;页面逻辑问题&lt;/li&gt;
&lt;li&gt;配置保存问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些都不是它的主战场。&lt;/p&gt;
&lt;h3&gt;2. &lt;code&gt;include.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是主题逻辑层最重要的文件之一。&lt;/p&gt;
&lt;p&gt;它通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Hook 注册&lt;/li&gt;
&lt;li&gt;主题辅助函数&lt;/li&gt;
&lt;li&gt;配置默认值&lt;/li&gt;
&lt;li&gt;配置消费逻辑&lt;/li&gt;
&lt;li&gt;条件资源加载&lt;/li&gt;
&lt;li&gt;列表或详情页的派生数据处理&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候更适合改这里？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某段逻辑会被多个模板复用&lt;/li&gt;
&lt;li&gt;需要根据条件决定页面行为&lt;/li&gt;
&lt;li&gt;需要处理主题配置项&lt;/li&gt;
&lt;li&gt;需要做派生值而不是单纯排版&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果你发现某段代码在多个模板里复制粘贴，通常就是该回到 &lt;code&gt;include.php&lt;/code&gt; 的信号。&lt;/p&gt;
&lt;h3&gt;3. &lt;code&gt;main.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是主题后台设置页的主落点。&lt;/p&gt;
&lt;p&gt;它通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权限检查&lt;/li&gt;
&lt;li&gt;主题启用检查&lt;/li&gt;
&lt;li&gt;表单保存&lt;/li&gt;
&lt;li&gt;&lt;code&gt;CheckIsRefererValid()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;SaveConfig()&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;BuildTemplate()&lt;/code&gt; 或其他重建动作&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候更适合改这里？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;新增主题设置项&lt;/li&gt;
&lt;li&gt;保存全局选项&lt;/li&gt;
&lt;li&gt;做后台表单&lt;/li&gt;
&lt;li&gt;保存后触发模板或模块重建&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不该承担什么？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;前台页面结构&lt;/li&gt;
&lt;li&gt;文章详情页布局&lt;/li&gt;
&lt;li&gt;评论区展示&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这些都不是它的职责。&lt;/p&gt;
&lt;h3&gt;4. &lt;code&gt;template/*.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是前台输出层。&lt;/p&gt;
&lt;p&gt;它通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面结构&lt;/li&gt;
&lt;li&gt;模板拆分&lt;/li&gt;
&lt;li&gt;变量输出&lt;/li&gt;
&lt;li&gt;列表和详情页布局&lt;/li&gt;
&lt;li&gt;公共头部、页脚、侧栏、评论区组织&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候优先改这里？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;页面长相要变&lt;/li&gt;
&lt;li&gt;列表卡片结构要变&lt;/li&gt;
&lt;li&gt;详情页模块顺序要变&lt;/li&gt;
&lt;li&gt;搜索页、404 页、分类页展示要变&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;什么时候不要一上来就改模板？&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;明明是缩略图生成逻辑问题&lt;/li&gt;
&lt;li&gt;明明是配置保存问题&lt;/li&gt;
&lt;li&gt;明明是字段注入问题&lt;/li&gt;
&lt;li&gt;明明是评论校验或接口流程问题&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;那就应该回到逻辑层。&lt;/p&gt;
&lt;h2&gt;三、模板目录里，再拆一层职责&lt;/h2&gt;
&lt;p&gt;很多人知道要改模板，但还是会在模板里乱撞。&lt;/p&gt;
&lt;p&gt;更稳的做法，是先知道常见模板文件各自最像什么。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;header.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; 区域&lt;/li&gt;
&lt;li&gt;标题、描述、关键词&lt;/li&gt;
&lt;li&gt;全局 CSS、全局前置脚本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{$header}&lt;/code&gt; 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;你要改这些东西时，优先想它：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;title&lt;/li&gt;
&lt;li&gt;meta description&lt;/li&gt;
&lt;li&gt;favicon&lt;/li&gt;
&lt;li&gt;canonical&lt;/li&gt;
&lt;li&gt;站点级 head 脚本&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;footer.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公共页脚&lt;/li&gt;
&lt;li&gt;全局尾部脚本&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{$footer}&lt;/code&gt; 输出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;公共页脚结构&lt;/li&gt;
&lt;li&gt;回到顶部&lt;/li&gt;
&lt;li&gt;末尾脚本引入&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;index.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;首页&lt;/li&gt;
&lt;li&gt;列表页&lt;/li&gt;
&lt;li&gt;分类页&lt;/li&gt;
&lt;li&gt;标签页&lt;/li&gt;
&lt;li&gt;作者页&lt;/li&gt;
&lt;li&gt;日期归档&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;很多主题会在这里基于 &lt;code&gt;$type&lt;/code&gt; 再做分支判断。&lt;/p&gt;
&lt;p&gt;如果你要改的是：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;文章列表卡片&lt;/li&gt;
&lt;li&gt;分页&lt;/li&gt;
&lt;li&gt;列表空状态&lt;/li&gt;
&lt;li&gt;首页和分类页的结构差异&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它通常就是第一站。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;single.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责文章详情页。&lt;/p&gt;
&lt;p&gt;适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;标题区&lt;/li&gt;
&lt;li&gt;正文区&lt;/li&gt;
&lt;li&gt;作者信息&lt;/li&gt;
&lt;li&gt;相关推荐&lt;/li&gt;
&lt;li&gt;评论区位置&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;page.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;如果主题单独提供它，通常负责独立页面。&lt;/p&gt;
&lt;p&gt;适合放：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;关于页&lt;/li&gt;
&lt;li&gt;联系页&lt;/li&gt;
&lt;li&gt;服务页&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;这种不完全等同于普通文章详情的页面结构。&lt;/p&gt;
&lt;h3&gt;&lt;code&gt;search.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责搜索结果。&lt;/p&gt;
&lt;p&gt;如果没有，有些主题会回落到 &lt;code&gt;index.php&lt;/code&gt;。&lt;/p&gt;
&lt;p&gt;适合处理：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;搜索结果标题&lt;/li&gt;
&lt;li&gt;搜索为空时的提示&lt;/li&gt;
&lt;li&gt;搜索结果列表结构&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;&lt;code&gt;comments.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论列表&lt;/li&gt;
&lt;li&gt;回复层级&lt;/li&gt;
&lt;li&gt;评论表单&lt;/li&gt;
&lt;li&gt;验证码区域&lt;/li&gt;
&lt;li&gt;回复交互&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;评论问题一半在这里，一半不在这里。&lt;/p&gt;
&lt;p&gt;这一点后面讲评论专题时会再展开。&lt;/p&gt;
&lt;h2&gt;四、插件开发里，文件职责怎么分&lt;/h2&gt;
&lt;p&gt;再看插件目录：&lt;/p&gt;
&lt;pre&gt;&lt;code class=&quot;language-text&quot;&gt;zb_users/plugin/&amp;lt;plugin&amp;gt;/
├── plugin.xml
├── include.php
├── main.php
├── includes/
└── vendor/
&lt;/code&gt;&lt;/pre&gt;
&lt;h3&gt;1. &lt;code&gt;plugin.xml&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;和主题的 &lt;code&gt;theme.xml&lt;/code&gt; 很像，也是元信息层。&lt;/p&gt;
&lt;p&gt;负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件 ID&lt;/li&gt;
&lt;li&gt;插件名称&lt;/li&gt;
&lt;li&gt;作者&lt;/li&gt;
&lt;li&gt;版本&lt;/li&gt;
&lt;li&gt;后台入口&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;它不是具体逻辑实现层。&lt;/p&gt;
&lt;h3&gt;2. 插件 &lt;code&gt;include.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是插件行为真正开始挂接的地方。&lt;/p&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;RegisterPlugin(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Add_Filter_Plugin(...)&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;引入辅助文件&lt;/li&gt;
&lt;li&gt;早期初始化&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;当你想知道一个插件“到底从哪开始生效”，最先就该看这里。&lt;/p&gt;
&lt;h3&gt;3. 插件 &lt;code&gt;main.php&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这是后台设置和管理工具入口。&lt;/p&gt;
&lt;p&gt;通常负责：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;权限检查&lt;/li&gt;
&lt;li&gt;启用状态检查&lt;/li&gt;
&lt;li&gt;保存配置&lt;/li&gt;
&lt;li&gt;管理界面输出&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;和主题 &lt;code&gt;main.php&lt;/code&gt; 一样，它更偏后台表单和管理工具，不是前台渲染层。&lt;/p&gt;
&lt;h3&gt;4. &lt;code&gt;includes/&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;当插件逻辑开始变多时，常会把具体行为拆到这里。&lt;/p&gt;
&lt;p&gt;比如：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;评论处理&lt;/li&gt;
&lt;li&gt;接口调用&lt;/li&gt;
&lt;li&gt;规则判断&lt;/li&gt;
&lt;li&gt;辅助函数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;如果一个插件比较复杂，真正的业务实现往往就在这里。&lt;/p&gt;
&lt;h3&gt;5. &lt;code&gt;vendor/&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;这一般是第三方依赖。&lt;/p&gt;
&lt;p&gt;你需要知道它存在，但不要把自己的业务逻辑也乱塞进去。&lt;/p&gt;
&lt;h2&gt;五、什么需求该落主题，什么需求该落插件&lt;/h2&gt;
&lt;p&gt;这是开发中最值钱的一道判断题。&lt;/p&gt;
&lt;h3&gt;更适合放主题的需求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;首页结构改造&lt;/li&gt;
&lt;li&gt;列表页视觉调整&lt;/li&gt;
&lt;li&gt;文章页模块组织&lt;/li&gt;
&lt;li&gt;主题级配置项&lt;/li&gt;
&lt;li&gt;和当前主题强绑定的展示逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;更适合放插件的需求&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;评论反垃圾&lt;/li&gt;
&lt;li&gt;后台菜单扩展&lt;/li&gt;
&lt;li&gt;编辑页新增字段&lt;/li&gt;
&lt;li&gt;通用功能模块&lt;/li&gt;
&lt;li&gt;API 扩展&lt;/li&gt;
&lt;li&gt;路由扩展&lt;/li&gt;
&lt;li&gt;多主题可复用的逻辑&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;一句话概括：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;强绑定外观的，更像主题职责。&lt;br&gt;强绑定流程和复用的，更像插件职责。&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;六、什么需求该放 &lt;code&gt;Config&lt;/code&gt;，什么需求该放 &lt;code&gt;Metas&lt;/code&gt;&lt;/h2&gt;
&lt;p&gt;这也是高频分歧点。&lt;/p&gt;
&lt;h3&gt;放 &lt;code&gt;Config&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题默认缩略图&lt;/li&gt;
&lt;li&gt;全站 SEO 默认值&lt;/li&gt;
&lt;li&gt;首页文案&lt;/li&gt;
&lt;li&gt;站点级开关&lt;/li&gt;
&lt;li&gt;插件 API Key&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;对整个主题或插件都生效的全局设置。&lt;/strong&gt;&lt;/p&gt;
&lt;h3&gt;放 &lt;code&gt;Metas&lt;/code&gt;&lt;/h3&gt;
&lt;p&gt;适合：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;某篇文章的 SEO 标题&lt;/li&gt;
&lt;li&gt;某篇文章的封面图&lt;/li&gt;
&lt;li&gt;某个分类的描述&lt;/li&gt;
&lt;li&gt;某个标签的自定义模板参数&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;也就是：&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;挂在单个对象身上的字段。&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;如果你把这两类东西混着存，后面会非常难维护。&lt;/p&gt;
&lt;h2&gt;七、一份最实用的“需求落点速查表”&lt;/h2&gt;
&lt;p&gt;以后拿到需求，你可以先按这个方式判断：&lt;/p&gt;
&lt;h3&gt;改页面布局&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;template/index.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/single.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/page.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/search.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;改站点头部 meta&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;template/header.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;主题 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;新增主题设置项&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;给文章加自定义字段&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件或主题 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;编辑页相关 Hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;改评论提交流程&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;template/comments.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;评论相关插件&lt;/li&gt;
&lt;li&gt;评论 Hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;新增一个特殊 URL 页面&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件或主题 &lt;code&gt;include.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Filter_Plugin_Zbp_PreLoad&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;RegRoute(...)&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;做后台扩展&lt;/h3&gt;
&lt;p&gt;先看：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;插件 &lt;code&gt;main.php&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;后台菜单或编辑页 Hook&lt;/li&gt;
&lt;/ul&gt;
&lt;h2&gt;八、最常见的 5 种落点错误&lt;/h2&gt;
&lt;h3&gt;1. 把页面布局逻辑写进后台设置页&lt;/h3&gt;
&lt;p&gt;这通常会让代码越来越难读。&lt;/p&gt;
&lt;h3&gt;2. 把复用逻辑复制进多个模板&lt;/h3&gt;
&lt;p&gt;短期省事，长期维护最痛。&lt;/p&gt;
&lt;h3&gt;3. 把主题强绑定逻辑做成重插件&lt;/h3&gt;
&lt;p&gt;最后会出现：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;主题和插件互相缠住&lt;/li&gt;
&lt;li&gt;换主题就不成立&lt;/li&gt;
&lt;li&gt;职责边界很乱&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;4. 把单篇文章字段做成全局配置&lt;/h3&gt;
&lt;p&gt;后面内容编辑会很别扭。&lt;/p&gt;
&lt;h3&gt;5. 一有需求就先冲核心&lt;/h3&gt;
&lt;p&gt;这几乎总是过早的。&lt;/p&gt;
&lt;h2&gt;九、建立“先判断职责，再开始写”的习惯&lt;/h2&gt;
&lt;p&gt;我很建议你以后每次动手前，都先问自己这四句：&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;这到底是显示问题，还是流程问题&lt;/li&gt;
&lt;li&gt;这是单页面问题，还是全局问题&lt;/li&gt;
&lt;li&gt;这是主题职责，还是插件职责&lt;/li&gt;
&lt;li&gt;这是全局配置，还是对象字段&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;很多弯路，都是这四个问题没先问清楚。&lt;/p&gt;
&lt;h2&gt;结语&lt;/h2&gt;
&lt;p&gt;Z-BlogPHP 并不怕文件多，它真正怕的是你不分层。&lt;/p&gt;
&lt;p&gt;只要你先建立起这张职责表：&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;theme.xml&lt;/code&gt; 和 &lt;code&gt;plugin.xml&lt;/code&gt; 是元信息层&lt;/li&gt;
&lt;li&gt;&lt;code&gt;include.php&lt;/code&gt; 是逻辑和挂接层&lt;/li&gt;
&lt;li&gt;&lt;code&gt;main.php&lt;/code&gt; 是后台设置和管理层&lt;/li&gt;
&lt;li&gt;&lt;code&gt;template/*.php&lt;/code&gt; 是前台输出层&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Config&lt;/code&gt; 是全局设置&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Metas&lt;/code&gt; 是对象字段&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;后面无论你写主题、写插件、调评论、扩后台、做 SEO 二开，落点都会清楚很多。&lt;/p&gt;
&lt;p&gt;下一篇我们开始进入真正的主题开发，从一个主题最小可用结构，到底应该长什么样开始讲。&lt;/p&gt;</description><pubDate>Tue, 19 May 2026 10:04:00 +0800</pubDate></item></channel></rss>