隐藏加密文章
有时候一些文章不想公开让大家访问,所以设置了密码。但是 Typecho 的加密文章仍然会显示在主页上,最近文章中。并把标题替换为此内容被密码保护
。所以我想把加密文章直接隐藏掉,这样主页会显得清爽。
之前一直是通过修改主题模板来隐藏加密文章。但是在实现方法上用的最简单的方法,就是在主题模板获取到文章的时候判断每篇文章是否是加密的,如果是则隐藏此文章。
但是这样会有几个问题:
- 首页模板获取到的的文章数量是恒定的,比如 10 篇,如果其中 9 篇都是加密文章,这时候你查看首页时,会发现,整个首页就只有 1 篇文章,非常影响阅读体验。当时为了解决这个问题,我只能把首页显示文章的数量调高。
- 加密文章下的评论依旧会被显示出来,并且显示为
内容被隐藏
。 - 加密文章虽然在主页隐藏了,但是依旧可以直接通过网址访问到。存在密码被暴力破解的风险(虽然我觉得没人会闲着没事来破解这个密码)
所以我想着去写一个 Typecho 的插件来隐藏文章,同时解决以上的问题。
我首先去查看了 Typecho 的 文档,但是看完之后的我还是一知半解。
后来我看到了 老高的typecho插件编写教程,文章详细的介绍了插件的机制,我大概知道该怎么下手去写一个插件。
既然知道该怎么下手,便去建立了一个新的仓库来存放代码,并给插件取了一个直白的名字 Filter
。
首先尝试过滤加密的文章,我发现首页或者其他页面的文章都是通过 Widget_Archive
来获取数据,所以准备从这里下手。
我发现 Widget_Archive
中有一个 handleInit
接口可以用来过滤文章。
使用如下的函数即可过滤掉加密的文章。这样从数据库获取的文章便全是未加密的。
public static function archiveFilter($obj, $select)
{
# 获取用户
$user = Typecho_Widget::widget('Widget_User');
# 当用户权限低于编辑时,过滤掉加密文章
if (!$user->pass('editor', true)) {
// 过滤加密文章
$select = $select->where('table.contents.password is null');
}
return $select;
}
接下来的我尝试着去过滤掉最近回复处加密文章下的回复,我找了半天没找到合适的插件接口。我先尝试着给加密的回复添加一个 show
的属性,然后过滤掉这个属性值为 false
的回复。
但是这样就会遇到和之前一样的问题,那就是如果 10 个回复中,9 个都是加密的,就只能显示出 1 个,体验很不好。
最后我发现可以自定义 Widget
,便在插件中实现了修改版的 Widget_Comments_Recent
和 Widget_Contents_Post_Recent
。通过在主题模板中调用自己实现的 Widget
,这样就解决了之前遇到的问题。
因为使用这种方法来过滤加密的文章,同时也解决了之前我遇到的 在某些情况下错误的添加了 noindex 的问题。算是一举多得了。
插件地址:typecho-filter