主题移植小记:Typecho 按年输出文章归档

技术 发布于 2 周前

Typecho 按年输出归档页面这个功能,网上能检索到现成的代码,但对于移植主题复杂的 html 结构而言实现起来太过繁琐,以下是网上找到的代码,在此基础上进行修改太过烧脑,遂尝试使用更优雅的方式,html 结构更清晰,方便主题移植时候根据原始 html 结构进行适配。

  <?php
    Typecho_Widget::widget('Widget_Contents_Post_Recent', 'pageSize='.
    Typecho_Widget::widget('Widget_Stat')->publishedPostsNum)->to($archives);
    $date_y=0;$date_m=0;$output = '';$huan=0;
    while($archives->next()){
      $date_t = explode(",", date('Y,m,d', $archives->created));
      if($date_y > $date_t[0]){
        $date_m  = 0;
        $article_nums[] = $article_num;
        $output .= '</ul></li></ul>';
      }
      if($date_y != $date_t[0]){
        $date_y  = $date_t[0];$article_num=0;
        $article_flag[] = $tmp_flag = 'archives_'.$huan++;
        $output .= '<h2>'.$date_y.' <span>×'. $tmp_flag .'</span></h2><ul>';
      }
      $output .= '<li><time>'.$date_t[1].'.'.$date_t[2].'</time> <a href="'.$archives->permalink.'">'.$archives->title.'</a> <sup><a href="'.$archives->permalink.'#comment">'.$archives->commentsNum.'</a></sup></li>';
      $article_num++;
    }
    $article_nums[] = $article_num;
    $output .= '</ul></li></ul>';
    echo str_replace($article_flag, $article_nums, $output);
  ?>

首先需要把以下代码放入 functions.php 中,在 Cherry 主题中测试没什么 BUG。

// 文章归档
class AnnualArchive extends Typecho_Widget
{
    private $_groupedYears = [];

    public function execute()
    {
        $posts = $this->widget('Widget_Contents_Post_Recent', [
            'pageSize' => 9999,
            'status' => 'publish'
        ]);

        $this->_groupedYears = $this->processPosts($posts);
    }

    private function processPosts($posts)
    {
        $grouped = [];
        $posts->to($posts);
        
        while ($posts->next()) {
            $post = $posts->row;
            $created = $post['created'];
            $timestamp = ($created instanceof Typecho_Date) 
                        ? $created->time 
                        : (is_numeric($created) ? $created : 0);

            $year = date('Y', $timestamp);
            $monthDay = date('m-d', $timestamp);

            if (!isset($grouped[$year])) {
                $grouped[$year] = [
                    'count' => 0,
                    'posts' => [],
                    'year' => $year
                ];
            }

            $grouped[$year]['posts'][] = [
                'title' => $posts->title,
                'permalink' => $posts->permalink,
                'date' => $monthDay
            ];
            $grouped[$year]['count']++;
        }

        krsort($grouped);
        return $grouped;
    }

    public function getArchiveData()
    {
        return $this->_groupedYears;
    }
}

这一段代码放置到需要的地方,例如归档页面模板,html 结构根据需求来修改就好了。

<?php $archive = $this->widget('AnnualArchive'); $years = $archive->getArchiveData();?>
<?php foreach ($years as $yearData): ?>
<div class="mod-archive-name"><?php echo $yearData['year']; ?></div>
<ul class="mod-archive-list">
<?php foreach ($yearData['posts'] as $post): ?>
    <li>
        <time class="mod-archive-time text-nowrap me-4"><?php echo $post['date']; ?></time>
        <a href="<?php echo $post['permalink']; ?>" title="<?php echo $post['title']; ?>"><?php echo $post['title']; ?></a>
    </li>
    <?php endforeach; ?>
</ul>
<?php endforeach; ?>

评论(0)

发布评论

相关文章