handsome的主题支持设置指定分类在首页显示隐藏,但是有一个问题就是我一个文章同时设置了分类A、分类B,其中分类A不显示,分类B显示,结果首页还是显示了,其实我想只要有这个分类就不要显示。比如胡东东博客的折腾分类,内容很杂,但是不希望在首页显示。
排查之后这个功能并不是在主题,而是在配套的handsome插件功能里,所以需要修改usr/plugins/Handsome/Plugin.php文件。
原因
原因是查询语法的问题,文章如果同时包含“隐藏分类A”和“可见分类B”,它在关系表中有两条记录(mid=A 和 mid=B)。 当前查询对每个隐藏分类ID都加了一个 mid != 该ID 的条件(多个条件之间是 AND 关系),这会导致:
- 对于 mid=A 的记录,它不满足 mid != A,所以被过滤掉;
- 但对于 mid=B 的记录,它满足 mid != A,于是被保留下来。
加上最后用了 GROUP BY cid,只要有一条记录被保留,这篇文章就会出现在结果集中——所以它仍然显示在首页。
修改
typecho的1.2版本Sql解析不支持NOT IN的解析,所以需要修改内核文件var/Typecho/Db/Query.php,支持一下NOT字段
//原内容
//private const KEYWORDS = '*PRIMARY|AND|OR|LIKE|ILIKE|BINARY|BY|DISTINCT|AS|IN|IS|NULL';
//增加NOT
private const KEYWORDS = '*PRIMARY|AND|OR|LIKE|ILIKE|BINARY|BY|DISTINCT|AS|IN|NOT|IS|NULL';之后修改usr/plugins/Handsome/Plugin.php文件的CateFilter功能,第1127行首页不显示分类隐藏的内容的代码,替换为
//首页不显示分类隐藏的内容
$CateIds = Typecho_Widget::widget('Widget_Options')->plugin('Handsome')->CateId;
if (!$CateIds) return $select;
// 1. 清理和格式化分类 ID 数组
$CateIds = explode(',', $CateIds);
$CateIds = array_map('intval', $CateIds);
$CateIds = array_filter($CateIds);
$CateIds = array_unique($CateIds);
if (empty($CateIds)) return $select;
// 2. 利用底层最轻量的单独查询,把这几个隐藏分类下的所有文章 cid 先捞出来
$db = Typecho_Db::get();
$rows = $db->fetchAll($db->select('cid')
->from('table.relationships')
->where('mid IN ?', $CateIds));
// 3. 提取出单纯的一维数字数组 [12, 15, 23 ...]
$hideCids = array_column($rows, 'cid');
// 4. 过滤
if (!empty($hideCids)) {
$select = $select->where('table.contents.cid NOT IN ?', $hideCids);
}
return $select;版权属于:胡东东博客 - hudd.cn
本文链接:https://blog.hudd.cn/1425.html
本文采用知识共享署名4.0 国际许可协议进行许可。转载或大段使用必须添加本文链接,否则您将构成侵权!
微信公众号: 东哥探索笔记
