这段代码可以大幅精简和优化。主要问题:
- 为
music别名单独处理的逻辑过于特定化 - 代码结构重复
- 逻辑不够清晰
- 数据库查询可优化
以下是优化后的版本:
<?php
/**
* 子分类和标签显示组件
* 调用方式:<?php $this->need('subcategories.php'); ?>
*/
if (!defined('__TYPECHO_ROOT_DIR__')) exit;
// 只在分类或标签页面显示
if (!$this->is('category') && !$this->is('tag')) {
return;
}
$db = Typecho_Db::get();
$currentSlug = $this->getArchiveSlug();
$currentType = $this->getArchiveType();
$displayCategories = [];
$sectionName = '';
// 获取显示的分类
if ($currentType === 'category') {
// 分类页面逻辑
$currentCat = $db->fetchRow($db->select('mid, parent, name')
->from('table.metas')
->where('slug = ?', $currentSlug)
->where('type = ?', 'category'));
if ($currentCat) {
$currentCatId = $currentCat['mid'];
$parentId = $currentCat['parent'];
if ($parentId > 0) {
// 当前是子分类,显示同级分类
$displayCategories = $db->fetchAll($db->select()
->from('table.metas')
->where('parent = ?', $parentId)
->where('type = ?', 'category'));
// 获取父分类名称
$parentCat = $db->fetchRow($db->select('name')
->from('table.metas')
->where('mid = ?', $parentId));
$sectionName = $parentCat ? $parentCat['name'] : '同级分类';
} else {
// 当前是父分类,显示子分类
$displayCategories = $db->fetchAll($db->select()
->from('table.metas')
->where('parent = ?', $currentCatId)
->where('type = ?', 'category'));
$sectionName = $currentCat['name'];
}
}
} elseif ($currentType === 'tag') {
// 标签页面逻辑 - 可选显示相关分类
// 这里可以保留通用逻辑,但不应为特定分类硬编码
// 如果需要,可以通过参数传递分类slug
$fromCategory = $this->request->get('from');
if ($fromCategory) {
// 通用逻辑:根据from参数显示指定分类的子分类
$parentCat = $db->fetchRow($db->select('mid, name')
->from('table.metas')
->where('slug = ?', $fromCategory)
->where('type = ?', 'category'));
if ($parentCat) {
$displayCategories = $db->fetchAll($db->select()
->from('table.metas')
->where('parent = ?', $parentCat['mid'])
->where('type = ?', 'category'));
$sectionName = $parentCat['name'];
}
}
}
// 显示子分类导航
if (!empty($displayCategories)): ?>
<div class="simple-subcats">
<span class="label"><?php echo htmlspecialchars($sectionName); ?></span>
<?php foreach ($displayCategories as $subCat):
$permalink = Typecho_Common::url('category/' . $subCat['slug'], $this->options->index);
$isCurrent = ($subCat['slug'] === $currentSlug) ? 'current' : '';
?>
<a href="<?php echo $permalink; ?>" class="<?php echo $isCurrent; ?>">
<?php echo htmlspecialchars($subCat['name']); ?>
<span class="count">(<?php echo $subCat['count']; ?>)</span>
</a>
<?php endforeach; ?>
</div>
<?php endif; ?>
<!-- 显示当前页面下的所有标签 -->
<div class="simple-tag">
<?php
// 获取当前页面文章的所有标签
$tagList = [];
if ($this->have()) {
// 一次性获取所有文章的标签
while ($this->next()) {
$tags = $this->tags;
if (!empty($tags)) {
foreach ($tags as $tag) {
$tagSlug = $tag['slug'];
if (!isset($tagList[$tagSlug])) {
$tagList[$tagSlug] = [
'name' => $tag['name'],
'count' => 1
];
} else {
$tagList[$tagSlug]['count']++;
}
}
}
}
$this->rewind();
}
// 显示标签
if (!empty($tagList)):
// 按使用次数降序排序
uasort($tagList, function($a, $b) {
return $b['count'] - $a['count'];
});
$currentTagSlug = $currentType === 'tag' ? $currentSlug : '';
foreach ($tagList as $slug => $tagInfo):
$tagUrl = Typecho_Common::url('tag/' . $slug, $this->options->index);
$isCurrent = ($currentType === 'tag' && $slug === $currentTagSlug) ? 'current' : '';
?>
<a href="<?php echo $tagUrl; ?>" class="simple-link <?php echo $isCurrent; ?>">
<?php echo htmlspecialchars($tagInfo['name']); ?>
<span class="count">(<?php echo $tagInfo['count']; ?>)</span>
</a>
<?php endforeach;
endif;
?>
</div>主要优化点:
- 移除硬编码的
music逻辑:改为通用方式,通过?from=分类slug参数动态指定 代码结构优化:
- 更清晰的逻辑分离
- 使用
$currentType和$currentSlug提高可读性 - 减少重复的数据库查询
- 安全增强:添加
htmlspecialchars()函数防止XSS 性能优化:
- 减少不必要的变量声明
- 更简洁的条件判断
- 使用
===进行严格比较
功能改进:
- 使用
slug而非name进行比较,更准确 - 在标签页面可通过
?from=分类slug参数显示指定分类的子分类
- 使用
使用方法:
- 在分类页面:自动显示同级或子分类
- 在标签页面:如果要显示特定分类的子分类,可以使用
?from=分类slug参数 - 所有页面都会显示当前文章列表中的标签