玩Z-Blog也快十年了,从早期的1.8版本一路手撕到现在的1.7、1.8,自以为对模板标签早就烂熟于心,结果上周帮一个朋友调试模板,硬是被一个看似简单的标签卡了两个小时——不是它多高级,而是我特么压根没想到还有这种写法,今天索性把这些年踩过的坑、流过的血,一股脑倒出来,你们看完能省下至少三个通宵的调试时间,还能少花几百块雇人擦屁股的钱。
先说说最常见的“列表为空”的坑,很多新手(包括当年的我)写文章列表时,习惯直接套用官方文档的示例:
{foreach $articles as $article}
<h2>{$article.Title}</h2>
{/foreach}
这代码在文章多的时候屁事没有,但一旦某个分类下没文章,或者你调用的标签返回了空数组,这玩意儿直接白屏——没错,foreach循环一个空数组在PHP里不会报错,可Z-Blog的模板引擎会直接炸出500错误,连个提示都不给,我当年就因为忘了给首页的“最新文章”加个else判断,整站挂了三天才发现,那心情比吃了苍蝇还恶心,正确的做法是:
{if $articles}
{foreach $articles as $article}
<h2>{$article.Title}</h2>
{/foreach}
{else}
<p>暂无文章,请稍后再来…</p>
{/if}
别嫌多,这五行代码能让你半夜不被运维的电话吵醒,而且注意!Z-Blog的{if}标签不支持直接判断数组长度,必须用{if $articles}这种“存在性判断”,否则又会踩第二个坑——你写{if count($articles)>0}?对不起,Z-Blog的模板引擎对原生PHP函数的支持极其有限,大多数场景下会直接报错,想用count?请老老实实把计数逻辑写到你的模板函数文件里,或者使用系统自带的{$zbp->Count}相关标签。

Z-Blog模板标签,这些坑我替你们踩过了,别再重复造轮子
接着说分类嵌套循环的噩梦,我见过最离谱的模板,一个朋友为了实现“左侧分类列表,点击展开该分类下的文章”,竟然套了四层foreach,结果页面加载了30秒,浏览器直接无响应,后来我给他改成用系统函数GetCategoryList配合GetArticleList,再结合模板标签的limit和order参数:
{foreach GetCategoryList(0, null, null, null) as $category}
<h3>{$category.Name}</h3>
{foreach GetArticleList($category.ID, 0, 10, null) as $article}
<li><a href="{$article.Url}">{$article.Title}</a></li>
{/foreach}
{/foreach}
注意GetCategoryList的第一个参数是父级分类ID,填0表示顶级分类;第二个参数是排序方式,一般留空按系统默认;第三、四个参数我基本不用,直接写null,而GetArticleList里的第二个参数是忽略的文章数,0表示从最新开始取,第三个参数是取多少条,第四个是条件过滤,这个写法虽然还会循环两次,但至少不会爆炸——前提是你的分类别超过50个,文章别超过1000篇,如果站点文章上万,建议直接在后台开启“文章缓存”插件,或者自己写个静态数组缓存,不然每次访问都全量查询数据库,服务器能哭给你看。
自定义字段调用这块,也是重灾区,Z-Blog的默认文章表里只有Title、Url、Content这些基础字段,你要是想像WordPress那样加个“副标题”“摘要来源”之类的自定义信息,就得用Meta字段,但很多人在模板里直接写{$article.Meta.subtitle},结果页面输出空白的——因为Z-Blog的Meta数据存储格式是序列化数组,直接点语法调不出来,正确的姿势是:
{$article.Metas.subtitle}
注意是Metas,带s!这个坑我当年在官方论坛里翻了三个小时才找到答案,更隐蔽的是,如果某个文章的Meta字段里压根没存这个key,你这么调用就会输出一个PHP Notice错误,虽然页面能显示,但后台日志会塞满警告,建议在调用前加个判断:
{if isset($article.Metas.subtitle)}
<p class="subtitle">{$article.Metas.subtitle}</p>
{/if}
或者更省事的方法是直接装一个“自定义字段增强”插件,它能自动给每个文章页注入未定义的字段默认值,顺便解决空值错误,这个插件在Z-Blog官方应用中心就能下载,免费,不到10KB,谁用谁知道。
说到插件,再推荐几个必装的,第一个是“Template Helper”模板助手,它能让你在后台直接预览和调试模板标签的输出,比如你想知道当前页面的{$article}对象到底有哪些属性,不用翻代码,直接在插件界面里敲{$article|@print_r}就能看到完整数组,这玩意儿对我这种懒得记文档的人来说,简直是救命稻草,第二个是“UEditor”富文本编辑器,别用系统自带的那个老掉牙编辑器了,排版功能弱得像2005年的产品,UEditor至少能让你可视化地插入表格、代码块,还能调整图片对齐——别问我为什么推荐这个,因为我在模板里写文章展示样式时,被自带编辑器输出的垃圾HTML坑过无数次,第三个是“LayDate”日期插件,Z-Blog默认的日期格式只有年月日,我用它来在文章底部显示“上次更新时间”或者“阅读时长”,前台调用就写{$article.Time('Y年m月d日')},但LayDate可以让你直接用{php} echo timeFormat($article.PostTime, '相对时间'); {/php}这种骚操作,实现“3分钟前”“昨天”这种人性化显示。
长期维护的建议也得说几句,第一,永远不要直接在系统默认模板上修改,比如Z-Blog自带的“default”主题,你要是改了它,下次系统一更新,你的改动全没了,正确做法是复制一份,改文件夹名和主题名,然后把它当作自己的主题来迭代,第二,模板里注释要写清楚,别偷懒不写,我见过一个模板,二十多个文件,一个注释都没有,离职的员工留下的,后来维护的人根本不知道哪个标签对应哪个功能块,最后只能全删了重写,建议每个循环、每个变量都加一行中文注释:{* 这里是首页最新文章列表,最多显示10篇 *},第三,每半年检查一次官方更新日志,尤其注意模板标签的语法变化,Z-Blog从1.6到1.7时,废弃了{php}标签的简写方式,改用{PHP}(大写),很多老模板直接废掉,你要是没关注,升级后整个站点白屏,到时候连哭都找不到地方。
送一句肺腑之言:能用插件解决的功能,别自己写模板标签,Z-Blog的模板标签是为快速建站设计的,不是给你折腾复杂业务的,你要是想在文章列表里搞个“按点赞数排序”,直接装“点赞排行插件”;想要“随机文章”,用“随机文章插件”;想要“相关文章”,也有现成的,自己写?一个没考虑缓存,二没考虑数据库压力,三没考虑SEO重复内容,大概率上线三天就被用户骂卡顿,别问我为什么知道,因为我以前也觉得自己能写——然后被服务器资源耗尽搞崩溃了三次,最后乖乖装了插件,世界清净了。
模板标签这东西,说白了就是个脚手架,能用它快速搭出漂亮的页面是本事,但别想着用它来盖摩天大楼,该上插件就上插件,该上静态缓存就上静态缓存,省下的时间,陪你妈吃顿饭,或者给对象买个包,不比秃头改标签香多了?
发表评论