Hexo主题优化:简化category和tag页面实现

优化背景

最近在维护个人Hexo博客时,发现主题中的category.ejstag.ejs文件实现较为复杂,代码冗余度较高。这两个文件包含了大量重复代码,只是在页面标题和描述上有所不同。

同时,我注意到官方的hexo-theme-landscape主题在实现这两个页面时非常简洁,每个文件只有一行代码。这引起了我的兴趣,决定参考其实现方式来优化自己的主题。

优化目标

  1. 简化代码结构:减少代码冗余,提高代码可读性
  2. 提高可维护性:将通用逻辑集中到一个模板中,后续修改只需更新一个文件
  3. 保持原有功能:确保优化后所有原有功能都能正常工作
  4. 遵循最佳实践:参考官方主题的实现方式,采用更合理的代码组织方式

优化方案

参考hexo-theme-landscape主题的实现方式,我采用了以下方案:

  1. 创建通用模板:在themes/sido-meet/layout/partial/目录下创建archive.ejs模板文件,包含所有列表页面的通用结构
  2. 修改category.ejs:使用<%- partial('partial/archive', { ... }) %>引用通用模板,并传递相应参数
  3. 修改tag.ejs:与category.ejs类似,使用通用模板并传递相应参数
  4. 清理冗余文件:删除不必要的文件,保持代码结构整洁

实现步骤

1. 创建通用模板

themes/sido-meet/layout/partial/目录下创建archive.ejs模板文件,包含以下内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
<div class="blog-container">
<div class="blog-header">
<h1 class="blog-title"><%= page_title %></h1>
<p class="blog-description"><%= page_description %></p>
</div>

<div class="blog-content">
<div class="posts-section">
<div class="section-header">
<h2 class="section-title">Posts</h2>
<div class="sort-controls">
<%- partial('partial/sort-button') %>
</div>
</div>

<div class="posts-list">
<% page.posts.each(function(post) { %>
<article class="post-card" data-date="<%= post.date.unix() %>">
<div class="post-card-header">
<span class="post-date"><%= post.date.format('YYYY-MM-DD HH:mm:ss') %></span>
</div>
<h3 class="post-card-title">
<a href="<%= url_for(post.path) %>"><%= post.title %></a>
</h3>
<% if (post.excerpt) { %>
<p class="post-card-excerpt"><%= post.excerpt.replace(/<[^>]*>/g, '').substring(0, 150) + '...' %></p>
<% } %>
<div class="post-card-footer">
<a href="<%= url_for(post.path) %>" class="read-more">Read More →</a>
</div>
</article>
<% }) %>
</div>
</div>

<div class="sidebar">
<div class="sidebar-widget">
<h3 class="widget-title">Categories</h3>
<div class="categories-list">
<% site.categories.each(function(category) { %>
<div class="category-item">
<a href="<%= url_for(category.path) %>"><%= category.name %></a>
<span class="category-count"><%= category.posts.length %></span>
</div>
<% }) %>
</div>
</div>

<div class="sidebar-widget">
<h3 class="widget-title">Recent Posts</h3>
<div class="recent-posts">
<% site.posts.sort('-date').limit(5).each(function(post) { %>
<div class="recent-post-item">
<a href="<%= url_for(post.path) %>"><%= post.title %></a>
<span class="recent-post-date"><%= post.date.format('YYYY-MM-DD HH:mm:ss') %></span>
</div>
<% }) %>
</div>
</div>
</div>
</div>
</div>

2. 修改category.ejs

themes/sido-meet/layout/category.ejs文件修改为:

1
2
3
4
5
6
<%- partial('partial/header') %>
<%- partial('partial/archive', {
page_title: 'Category: ' + page.category,
page_description: 'All posts in category "' + page.category + '"'
}) %>
<%- partial('partial/footer') %>

3. 修改tag.ejs

themes/sido-meet/layout/tag.ejs文件修改为:

1
2
3
4
5
6
<%- partial('partial/header') %>
<%- partial('partial/archive', {
page_title: 'Tag: ' + page.tag,
page_description: 'All posts tagged with "' + page.tag + '"'
}) %>
<%- partial('partial/footer') %>

4. 配置版本控制

修改.gitignore文件,添加规则只追踪themes/sido-meet主题:

1
2
3
4
# Themes
# Ignore all themes except sido-meet
themes/*
!themes/sido-meet/

优化成果

1. 代码简化

  • category.ejs:从64行减少到6行,减少了90.6%的代码
  • tag.ejs:从64行减少到6行,减少了90.6%的代码
  • 总代码量:减少了134行代码,提高了代码可读性

2. 可维护性提升

  • 集中管理:所有列表页面的通用逻辑都集中在archive.ejs模板中
  • 易于修改:后续修改只需更新archive.ejs文件,无需修改多个文件
  • 一致性:确保了category和tag页面的显示效果完全一致

3. 功能保持

虽然代码简化了,但所有原有功能都得到了保留:

  • 页面标题和描述
  • 文章列表显示
  • 侧边栏分类
  • 最近文章
  • 文章排序功能

4. 代码组织更合理

  • 遵循最佳实践:参考官方主题的实现方式
  • 命名规范:使用archive.ejs作为通用模板名称,与官方主题保持一致
  • 结构清晰:模板文件职责明确,代码组织更合理

技术细节

参数传递

在使用通用模板时,通过传递参数来实现动态内容:

1
2
3
4
<%- partial('partial/archive', { 
page_title: 'Category: ' + page.category,
page_description: 'All posts in category "' + page.category + '"'
}) %>

模板渲染

通用模板使用传递的参数来渲染页面内容:

1
2
<h1 class="blog-title"><%= page_title %></h1>
<p class="blog-description"><%= page_description %></p>

版本控制

通过修改.gitignore文件,确保只有sido-meet主题会被版本控制系统追踪,避免其他主题文件污染仓库。

结论

通过参考hexo-theme-landscape主题的实现方式,我成功优化了自己主题中的category和tag页面实现。这次优化不仅简化了代码结构,提高了可维护性,还保持了所有原有功能。

这种通过创建通用模板来实现代码复用的方式,是一种很好的实践,值得在其他类似场景中推广使用。它不仅可以减少代码冗余,还可以提高代码的一致性和可维护性。

通过这次优化,我对Hexo主题的代码组织方式有了更深入的理解,也为后续的主题维护和开发打下了更好的基础。