Z-Blog 主题里读自定义字段,Metas 老是取不到值

· zblog · 阅读 10
摘要

主题里想给文章加个「阅读时长」字段,后台填了,前台死活读不出来。我一开始以为是字段没存进去,翻数据库才发现数据好好躺在 metacms 表里。 问题在读取方式上。 先确认 Metas 到底挂在哪个对象上 Z-Blog 的自定义字段是跟着 P

主题里想给文章加个「阅读时长」字段,后台填了,前台死活读不出来。我一开始以为是字段没存进去,翻数据库才发现数据好好躺在 metacms 表里。

问题在读取方式上。

先确认 Metas 到底挂在哪个对象上

Z-Blog 的自定义字段是跟着 Post 走的,键名大小写敏感这件事其实还好,真正坑的是取值时机。模板里这样写:

{$article.Metas.readtime}

如果 $article 是从列表页循环出来的对象,是能拿到的。但如果是在 template/post-single.php 里通过 $zbp->GetPostByID() 之类自己又查了一遍,得到的对象可能没带 Metas——具体带不带,我没法给你打包票,不同版本有差异。

保险的写法是显式调 Metas->Get():

{/* post-single.php */}
{php}
    $readtime = $article->Metas->Get( 'readtime' );
{/php}
{ if $readtime }
    { $readtime } 分钟
{ /if }

注意 { 和变量之间加空格,不然有些编辑器的语法高亮会抽搐。功能上不加也行。

Metas 没注册的键,Get 返回空字符串

这点挺关键。Metas->Get() 对不存在的键不抛错,安安静静返回 ''。所以如果你后台其实没填过这个字段,你永远不知道是代码错了还是数据空了。

排查时先打印整个数组:

{php}
    var_dump( $article->Metas->GetData() );
{/php}

能看到键名列表就说明对象是对的,列表里没有你要的键就说明根本没写进去——那个就是保存逻辑的问题了,跟模板无关。

想让主题在后台有个输入框

手工去数据库插字段当然也行,但我一般给主题挂个钩子,在文章编辑页下面加个自定义表单。用的钩子是 Filter_Plugin_Admin_ArticleMng_SubMenu(这个是后台菜单位置的,加表单区更常用的是编辑页的扩展点,名字我记不太准,建议先 list_hooks 查一遍再动手)。

表单提交后顺手把值塞进 Metas:

$article->Metas->readtime = (int) $readtime;
$article->Save();

这里 Metas->xxx = ... 这种直接赋值是能用的,因为 Metas 类实现了魔术方法。但如果你写 $article->Metas['readtime'],我就不确定了,没试过数组访问方式。

最后一句提醒:改完主题文件记得清缓存,Z-Blog 会编译模板,不清的话你会对着旧版本代码调试半天。这事儿我上个月刚干过。