如果界面设计允许或有多个层级,使用 Blues Music 也完全没有问题,表意更清晰

如果界面设计允许或有多个层级,使用 Blues Music 也完全没有问题,表意更清晰 封面

这段代码可以大幅精简和优化。主要问题:

  1. music 别名单独处理的逻辑过于特定化
  2. 代码结构重复
  3. 逻辑不够清晰
  4. 数据库查询可优化

以下是优化后的版本:

<?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>

主要优化点:

  1. 移除硬编码的 music 逻辑:改为通用方式,通过 ?from=分类slug 参数动态指定
  2. 代码结构优化

    • 更清晰的逻辑分离
    • 使用 $currentType$currentSlug 提高可读性
    • 减少重复的数据库查询
  3. 安全增强:添加 htmlspecialchars() 函数防止XSS
  4. 性能优化

    • 减少不必要的变量声明
    • 更简洁的条件判断
    • 使用 === 进行严格比较
  5. 功能改进

    • 使用 slug 而非 name 进行比较,更准确
    • 在标签页面可通过 ?from=分类slug 参数显示指定分类的子分类

使用方法

  • 在分类页面:自动显示同级或子分类
  • 在标签页面:如果要显示特定分类的子分类,可以使用 ?from=分类slug 参数
  • 所有页面都会显示当前文章列表中的标签

添加新评论