hexo-theme-nblog 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,25 @@
1
+ name: Publish Package
2
+
3
+ on:
4
+ push:
5
+ tags:
6
+ - 'v*'
7
+
8
+ permissions:
9
+ id-token: write # Required for OIDC
10
+ contents: read
11
+
12
+ jobs:
13
+ publish:
14
+ runs-on: ubuntu-latest
15
+ steps:
16
+ - uses: actions/checkout@v4
17
+
18
+ - uses: actions/setup-node@v4
19
+ with:
20
+ node-version: '24'
21
+ registry-url: 'https://registry.npmjs.org'
22
+ - run: npm ci
23
+ - run: npm run build --if-present
24
+ - run: npm test
25
+ - run: npm publish
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Nitai
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,46 @@
1
+ # NBlog - 轻量化博客主题
2
+
3
+ 参考 Material Design 设计风格,轻量极简
4
+
5
+ ## Getting Started - 快速开始
6
+
7
+ Check your environment:
8
+
9
+ - Hexo: 6.0.0 ~ latest
10
+ - hexo-cli: 4.3.0 ~ latest
11
+ - node: 14.17.3 ~ latest LTS
12
+ - npm: 6.14.13 ~ latest
13
+
14
+ Edit your `_config.yml`:
15
+
16
+ ```yaml
17
+ theme: nblog
18
+ ```
19
+
20
+ Install NBlog in terminal:
21
+
22
+ ```bash
23
+ npm i hexo-theme-nblog
24
+ ```
25
+
26
+ > **不推荐使用其他方式安装主题**,这些方式无法获得版本更新提示,且可能导致配置文件冲突等问题
27
+
28
+ ## Usage
29
+
30
+ See docs: `https://blog.nitai.cc/posts/blog-docs`
31
+
32
+ ## Preview
33
+
34
+ [Nitai Blog](https://blog.nitai.cc/)
35
+
36
+ ## Feedback
37
+
38
+ Issues: `https://github.com/Nitai9h/nBlogHexo/issues/`
39
+
40
+ Discussions: `https://github.com/Nitai9h/nBlogHexo/discussions/`
41
+
42
+ ## License
43
+
44
+ MIT License
45
+
46
+ Copyright (c) 2026 Nitai
package/_config.yml ADDED
@@ -0,0 +1,77 @@
1
+ #! 注意! 为了更新 npm package 后你的数据不会丢失
2
+ #! 请将此文件复制到根目录并重命名为 `_config.nblog.yml` 并在此文件的基础上进行站点
3
+ default_license: CC BY-NC-SA 4.0
4
+
5
+ site_name: My Blog
6
+ author: Your Name
7
+ avatar: /images/avatar.png
8
+ bio: 这里是你的个人简介
9
+ social:
10
+ - platform: GitHub
11
+ url: https://github.com/yourusername
12
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="currentColor"><path d="M12 0c-6.626 0-12 5.373-12 12 0 5.302 3.438 9.8 8.207 11.387.599.111.793-.261.793-.577v-2.234c-3.338.726-4.033-1.416-4.033-1.416-.546-1.387-1.333-1.756-1.333-1.756-1.089-.745.083-.729.083-.729 1.205.084 1.839 1.237 1.839 1.237 1.07 1.834 2.807 1.304 3.492.997.107-.775.418-1.305.762-1.604-2.665-.305-5.467-1.334-5.467-5.931 0-1.311.469-2.381 1.236-3.221-.124-.303-.535-1.524.117-3.176 0 0 1.008-.322 3.301 1.23.957-.266 1.983-.399 3.003-.404 1.02.005 2.047.138 3.006.404 2.291-1.552 3.297-1.23 3.297-1.23.653 1.653.242 2.874.118 3.176.77.84 1.235 1.911 1.235 3.221 0 4.609-2.807 5.624-5.479 5.921.43.372.823 1.102.823 2.222v3.293c0 .319.192.694.801.576 4.765-1.589 8.199-6.086 8.199-11.386 0-6.627-5.373-12-12-12z"/></svg>'
13
+ - platform: Email
14
+ url: mailto:your@email.com
15
+ icon: '<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path><polyline points="22,6 12,13 2,6"></polyline></svg>'
16
+
17
+ nav_links:
18
+ - name: 首页
19
+ path: /
20
+ icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="m3 9 9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path><polyline points="9 22 9 12 15 12 15 22"></polyline></svg>'
21
+ - name: 分类
22
+ path: /categories/
23
+ icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path></svg>'
24
+ - name: 标签
25
+ path: /tags/
26
+ icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M20.59 13.41l-7.17 7.17a2 2 0 0 1-2.83 0L2 12V2h10l8.59 8.59a2 2 0 0 1 0 2.82z"></path><line x1="7" y1="7" x2="7.01" y2="7"></line></svg>'
27
+ - name: 归档
28
+ path: /archives/
29
+ icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect><line x1="16" y1="2" x2="16" y2="6"></line><line x1="8" y1="2" x2="8" y2="6"></line><line x1="3" y1="10" x2="21" y2="10"></line></svg>'
30
+ - name: 友链
31
+ path: /friends/
32
+ icon: '<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path><path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path></svg>'
33
+
34
+ friend_links:
35
+ simple:
36
+ - name: Cloudflare
37
+ url: https://cloudflare.com
38
+ avatar: https://www.cloudflare.com/img/logo-cloudflare-dark.svg
39
+ description: Security, Performance, Reliability
40
+ - name: Hexo
41
+ url: https://hexo.io
42
+ avatar: https://hexo.io/logo.svg
43
+ description: A fast, simple & powerful blog framework
44
+ # cover:
45
+ # - name: Cloudflare Blog
46
+ # url: https://cloudflare.com
47
+ # avatar: https://www.cloudflare.com/img/logo-cloudflare-dark.svg
48
+ # cover: https://images.unsplash.com/photo-1555066931-4365d14bab8c?w=600
49
+ # author: Cloudflare
50
+ # description: Security, Performance, Reliability for the modern web
51
+ # - name: Hexo Blog
52
+ # url: https://hexo.io
53
+ # avatar: https://hexo.io/logo.svg
54
+ # cover: https://images.unsplash.com/photo-1461749280684-dccba630e2f6?w=600
55
+ # author: Hexo
56
+ # description: A fast, simple & powerful blog framework powered by Node.js
57
+
58
+ footer_links:
59
+ - name: 隐私政策
60
+ path: /posts/privacy/
61
+ - name: 版权协议
62
+ path: /posts/copyright/
63
+
64
+ posts_per_page: 10
65
+
66
+ twikoo:
67
+ enable: false
68
+ envId: https://xxx
69
+
70
+ katex:
71
+ enable: true
72
+
73
+ pjax:
74
+ enable: true
75
+
76
+ canonical:
77
+ enable: true
@@ -0,0 +1,49 @@
1
+ <footer class="footer">
2
+ <div class="footer__container container">
3
+ <div class="footer__content">
4
+ <div class="footer__left">
5
+ <div class="footer__themeInfo">
6
+ <p>nBlog</p>
7
+ <span class="footer__version">
8
+ <%= theme_version() %>
9
+ </span>
10
+ </div>
11
+ <div class="footer__links">
12
+ <% (theme.footer_links || []).forEach((link, index)=> { %>
13
+ <a href="<%= url_for(link.path) %>">
14
+ <%= link.name %>
15
+ </a>
16
+ <% if (index < theme.footer_links.length - 1) { %><span class="footer__links-divider">|</span>
17
+ <% } %>
18
+ <% }) %>
19
+ </div>
20
+ </div>
21
+ <div class="footer__center">
22
+ <p class="footer__copyright">
23
+ Copyright
24
+ © <%= date(Date.now(), 'YYYY' ) %>
25
+ <span class="footer__author">
26
+ <%= theme.author || config.author %>
27
+ </span>. All rights reserved.
28
+ </p>
29
+ <div class="footer__busuanzi">
30
+ <span id="busuanzi_container_site_pv">本站总访问量 <span id="busuanzi_value_site_pv"></span> 次</span>
31
+ <span class="footer__busuanzi-divider">|</span>
32
+ <span id="busuanzi_container_site_uv">访客数 <span id="busuanzi_value_site_uv"></span> 人次</span>
33
+ </div>
34
+ </div>
35
+ <div class="footer__right">
36
+ <p style="height: 22px;">
37
+ <a href="<%= url_for('/sitemap.xml') %>" class="footer__sitemap">Sitemap</a>
38
+ <a href="<%= url_for('/rss.xml') %>" class="footer__rss">RSS 订阅</a>
39
+ </p>
40
+ <p class="footer__powered">
41
+ Powered by
42
+ <a href="https://hexo.io" target="_blank" rel="noopener">Hexo</a> &
43
+ <a href="https://github.com/Nitai9h/nBlogHexo" target="_blank" rel="noopener">nBlogHexo</a>
44
+ </p>
45
+ </div>
46
+ </div>
47
+ </div>
48
+ </footer>
49
+ <script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>
@@ -0,0 +1,49 @@
1
+ <header class="header" id="header">
2
+ <div class="header__container container">
3
+ <a href="<%= url_for('/') %>" class="header__logo">
4
+ <span class="header__logo-icon header__logo-icon--svg">
5
+ <svg viewBox="0 0 1033 1105" width="26" height="26">
6
+ <path d="m530.5 55c-3.6 0-7.7 0.6-9.3 1.4-1.5 0.8-3.6 2.4-4.7 3.6-2 2.2-2 3.6-2 76.4 0 57.5 0.2 74.8 1.2 77.3 0.8 1.9 2.7 4 4.6 5 3 1.7 11.4 1.8 144.7 1.4 102.6-0.3 143.1-0.1 147.3 0.8 3.3 0.6 7 2.1 8.7 3.6 2 1.7 3.5 4.4 4.7 8.2 1.5 5.3 1.6 19.4 0.9 174.3-0.5 135.3-0.4 169 0.7 171 0.7 1.4 2.6 3.2 4.2 4 2.6 1.4 13.2 1.7 79.5 2.2 69.5 0.5 76.9 0.4 80.9-1.1 2.4-0.9 5.2-2.8 6.3-4.4 1.7-2.6 1.8-11.7 1.8-259.4 0-243.4-0.1-256.9-1.7-259.2-1-1.4-3.3-3.1-5.1-3.8-2.6-1.1-42.9-1.3-216.7-1.3-146.1 0-236.1 0.1-226.5 0 9.6-0.1-15.9 0-19.5 0zm-487.6 461.9c-2 0.3-4.9 1.7-6.3 3.1-1.5 1.4-3.2 4.3-3.8 6.5-0.7 2.8-1 78.5-0.9 259.5l0.7 255.2c0.1 0.8 0.4 1.8 0.6 2 3.9 3.9 6 4.3 7.8 4.8 1.9 0.6 7.2 1 11.8 1 4.8 0 7.6 0.2 8.2 0.1 3.5-0.1 5.9 0.2 12.9 0.2 7 0 12.2-0.1 10.3 0-0.6 0 63-0.1 187.3-0.3 125-0.2 185.6 0 188.4 0.2 2.2 0.1 4.3 0.1 11.3 0 7 0 9.2-0.1 10.6 0 0.6 0.1 4.1-0.2 10-0.2 5.3 0 11.4-0.5 13.5-1 2.3-0.6 4.8-2.4 6.7-4.8l2.1-3.6c-0.5-144-0.6-145.8-1.6-149.4-0.6-2-3.6-4-5.5-4.8-3.2-1.5-15.3-1.6-140-0.7-75.1 0.6-139.4 0.7-143 0.3-3.6-0.4-8-1.4-9.7-2.3-1.8-1-4.2-2.9-5.4-4.5-1.1-1.5-2.5-4.5-3.2-6.7-0.8-2.7-1.1-16-1.2-41.5 0-20.6 0.1-97.1 0.3-170 0.2-124.8 0.1-132.7-1.5-136-1-1.9-3.2-4.2-4.8-5.1-2.7-1.5-10.6-1.7-77.5-2.2-41-0.3-76.1-0.2-78.1 0.2zm233.5-230.7c-3 0.5-5.8 1.6-7.2 3-1.5 1.6-2.5 4.3-3.2 8.8-0.6 3.8-1 48-1 106.5 0 98.3 0 100.1 2 105 1.3 3.3 3.1 5.7 5.3 7 3.1 1.9 5.1 1.9 115.2 1.7 64.9-0.2 113.6-0.7 115.8-1.3 2-0.5 4.8-1.9 6.1-3.2 1.2-1.2 2.7-3.8 3.2-5.7 0.6-2.1 0.9-46 0.8-107-0.1-56.9-0.5-104.6-0.9-106-0.4-1.4-1.7-3.6-2.9-4.9-1.1-1.3-3.2-2.8-4.6-3.4-1.7-0.8-35.9-1.1-113.1-1.1-60.8-0.1-112.7 0.2-115.5 0.6zm254.1 297.8c-5.3 0.3-9 1.1-10.8 2.2-1.5 1-3.3 2.8-4 4-0.9 1.8-1.3 25.3-1.5 105.8-0.2 56.9 0 106 0.4 109 0.5 4.3 0.8 7.2 3.4 9.9l4 2 231.7 0.4c5.6-3.5 6.8-7.4 7.3-9.3 0.6-2.1 0.9-44.5 0.7-109.5-0.2-99.1-0.3-106.3-1.9-108.8-1-1.5-3.3-3.3-5-4.1-2.8-1.3-19.9-1.5-109.8-1.8-58.6-0.2-110.1-0.1-114.5 0.2z"/>
7
+ </svg>
8
+ </span>
9
+ <span class="header__logo-text"><%= theme.site_name || config.title %></span>
10
+ </a>
11
+
12
+ <nav class="header__nav" id="nav">
13
+ <% for (var item of theme.nav_links) { %>
14
+ <a href="<%= url_for(item.path) %>" class="header__nav-item">
15
+ <span class="header__nav-icon"><%- item.icon %></span>
16
+ <span class="header__nav-text"><%= item.name %></span>
17
+ </a>
18
+ <% } %>
19
+ </nav>
20
+
21
+ <div class="header__actions">
22
+ <button class="header__search-btn material-button material-button--text" onclick="location.href='<%= url_for('/search/') %>'">
23
+ <svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
24
+ <circle cx="11" cy="11" r="8"></circle>
25
+ <path d="m21 21-4.35-4.35"></path>
26
+ </svg>
27
+ </button>
28
+
29
+ <button class="header__theme-btn material-button material-button--text" id="themeToggle">
30
+ <svg class="icon-sun" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
31
+ <circle cx="12" cy="12" r="5"></circle>
32
+ <path d="M12 1v2M12 21v2M4.22 4.22l1.42 1.42M18.36 18.36l1.42 1.42M1 12h2M21 12h2M4.22 19.78l1.42-1.42M18.36 5.64l1.42-1.42"></path>
33
+ </svg>
34
+ <svg class="icon-moon" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
35
+ <path d="M21 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 21 12.79z"></path>
36
+ </svg>
37
+ </button>
38
+
39
+ <button class="header__menu-btn material-button material-button--text" id="menuBtn">
40
+ <svg class="icon-menu" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
41
+ <path d="M3 12h18M3 6h18M3 18h18"></path>
42
+ </svg>
43
+ <svg class="icon-close" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
44
+ <path d="M18 6L6 18M6 6l12 12"></path>
45
+ </svg>
46
+ </button>
47
+ </div>
48
+ </div>
49
+ </header>
@@ -0,0 +1,77 @@
1
+ <%
2
+ let ogTitle = '';
3
+ let ogDescription = '';
4
+ let ogImage = '';
5
+ let ogUrl = '';
6
+ let ogType = 'website';
7
+ let ogSiteName = config.title;
8
+ let articlePublishedTime = '';
9
+ let articleModifiedTime = '';
10
+ let articleAuthor = config.author || '';
11
+ let articleSection = '';
12
+ let baseUrl = config.url.replace(/\/$/, '');
13
+
14
+ if (is_post()) {
15
+ ogTitle = page.title;
16
+ ogDescription = page.description || page.excerpt || strip_html(page.content).substring(0, 200).trim() + '...';
17
+ ogImage = page.cover || theme.avatar;
18
+ ogUrl = baseUrl + '/' + page.path.replace(/\/$/, '');
19
+ ogType = 'article';
20
+ articlePublishedTime = date(page.date, 'YYYY-MM-DDTHH:mm:ssZ');
21
+ articleModifiedTime = page.updated ? date(page.updated, 'YYYY-MM-DDTHH:mm:ssZ') : articlePublishedTime;
22
+ if (page.categories && page.categories.length > 0) {
23
+ articleSection = page.categories.toArray()[0].name;
24
+ }
25
+ } else if (is_category()) {
26
+ ogTitle = '分类: ' + page.category + ' | ' + config.title;
27
+ ogDescription = '查看分类 "' + page.category + '" 下的所有文章';
28
+ ogImage = theme.avatar;
29
+ ogUrl = baseUrl + '/' + page.path.replace(/\/$/, '');
30
+ } else if (is_tag()) {
31
+ ogTitle = '标签: ' + page.tag + ' | ' + config.title;
32
+ ogDescription = '查看标签 "' + page.tag + '" 下的所有文章';
33
+ ogImage = theme.avatar;
34
+ ogUrl = baseUrl + '/' + page.path.replace(/\/$/, '');
35
+ } else if (is_archive()) {
36
+ ogTitle = '归档 | ' + config.title;
37
+ ogDescription = '浏览所有文章归档';
38
+ ogImage = theme.avatar;
39
+ ogUrl = baseUrl + '/' + page.path.replace(/\/$/, '');
40
+ } else {
41
+ ogTitle = config.title;
42
+ ogDescription = config.description;
43
+ ogImage = theme.avatar;
44
+ ogUrl = baseUrl;
45
+ }
46
+ %>
47
+
48
+ <meta property="og:site_name" content="<%= ogSiteName %>">
49
+ <meta property="og:title" content="<%= ogTitle %>">
50
+ <meta property="og:description" content="<%= ogDescription %>">
51
+ <meta property="og:url" content="<%= ogUrl %>">
52
+ <meta property="og:image" content="<%= ogImage %>">
53
+ <meta property="og:type" content="<%= ogType %>">
54
+ <meta property="og:locale" content="<%= config.language || 'zh_CN' %>">
55
+
56
+ <% if (is_post()) { %>
57
+ <meta property="article:published_time" content="<%= articlePublishedTime %>">
58
+ <meta property="article:modified_time" content="<%= articleModifiedTime %>">
59
+ <meta property="article:author" content="<%= articleAuthor %>">
60
+ <% if (articleSection) { %>
61
+ <meta property="article:section" content="<%= articleSection %>">
62
+ <% } %>
63
+ <% if (page.tags && page.tags.length > 0) { %>
64
+ <% page.tags.toArray().forEach(function(tag) { %>
65
+ <meta property="article:tag" content="<%= tag.name %>">
66
+ <% }); %>
67
+ <% } %>
68
+ <% } %>
69
+
70
+ <meta name="twitter:card" content="summary_large_image">
71
+ <meta name="twitter:title" content="<%= ogTitle %>">
72
+ <meta name="twitter:description" content="<%= ogDescription %>">
73
+ <meta name="twitter:image" content="<%= ogImage %>">
74
+
75
+ <meta name="apple-mobile-web-app-title" content="<%= ogSiteName %>">
76
+ <meta name="application-name" content="<%= ogSiteName %>">
77
+ <meta name="theme-color" content="#4f46e5">
@@ -0,0 +1,44 @@
1
+ <% var license=page.license || theme.default_license || 'CC BY-NC-SA 4.0' ; var author=page.author || theme.author ||
2
+ config.author || '作者' ; var isOriginal=page.original !==false; var sourceUrl=page.source_url || '' ; var
3
+ licenseInfo={ 'CC BY-NC-SA 4.0' : { name: 'CC BY-NC-SA 4.0' ,
4
+ url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh' , desc: '署名-非商业性使用-相同方式共享 4.0 国际' } }; var
5
+ currentLicense=licenseInfo[license] || licenseInfo['CC BY-NC-SA 4.0']; %>
6
+ <div class="post-license animate-fade-in-up animate-delay-2">
7
+ <div class="post-license__header">
8
+ <span class="copyright-symbol">©</span>
9
+ <span>版权声明</span>
10
+ </div>
11
+ <div class="post-license__content">
12
+ <div class="post-license__row">
13
+ <div class="post-license__item">
14
+ <span class="post-license__label">本文作者:</span>
15
+ <span class="post-license__value">
16
+ <%= author %>
17
+ </span>
18
+ </div>
19
+ <div class="post-license__item">
20
+ <span class="post-license__label">文章类型:</span>
21
+ <span class="post-license__value">
22
+ <%= isOriginal ? '原创' : '转载' %>
23
+ </span>
24
+ </div>
25
+ </div>
26
+ <% if (!isOriginal && sourceUrl) { %>
27
+ <div class="post-license__item">
28
+ <span class="post-license__label">原文链接:</span>
29
+ <a href="<%= sourceUrl %>" class="post-license__link" target="_blank" rel="noopener">
30
+ <%= sourceUrl %>
31
+ </a>
32
+ </div>
33
+ <% } %>
34
+ <div class="post-license__notice">
35
+ <% if (isOriginal) { %>
36
+ 本文为作者原创文章,遵循 <a href="<%= currentLicense.url %>" target="_blank" rel="noopener">
37
+ <%= currentLicense.name %>
38
+ </a> 许可协议,转载请注明出处。
39
+ <% } else { %>
40
+ 本文仅供学习交流使用,版权归原作者所有,侵权请联系删除
41
+ <% } %>
42
+ </div>
43
+ </div>
44
+ </div>
@@ -0,0 +1,45 @@
1
+ <div class="archives-page container">
2
+ <div class="page-header animate-fade-in-up">
3
+ <h1 class="page-header__title">
4
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
5
+ <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
6
+ <line x1="16" y1="2" x2="16" y2="6"></line>
7
+ <line x1="8" y1="2" x2="8" y2="6"></line>
8
+ <line x1="3" y1="10" x2="21" y2="10"></line>
9
+ </svg>
10
+ 归档
11
+ </h1>
12
+ <p class="page-header__description">共 <%= site.posts.length %> 篇文章</p>
13
+ </div>
14
+
15
+ <div class="archives-list animate-fade-in-up animate-delay-1">
16
+ <%
17
+ var years = {};
18
+ site.posts.sort('-date').forEach(function(post) {
19
+ var year = date(post.date, 'YYYY');
20
+ if (!years[year]) years[year] = [];
21
+ years[year].push(post);
22
+ });
23
+ %>
24
+ <% Object.keys(years).sort().reverse().forEach(function(year) { %>
25
+ <section class="archive-year">
26
+ <h2 class="archive-year__title"><%= year %></h2>
27
+ <div class="archive-year__posts">
28
+ <% years[year].forEach(function(post) { %>
29
+ <article class="archive-post">
30
+ <time class="archive-post__date" datetime="<%= date(post.date, 'YYYY-MM-DD') %>">
31
+ <%= date(post.date, 'MM-DD') %>
32
+ </time>
33
+ <a href="<%= url_for(post.path) %>" class="archive-post__title"><%= post.title %></a>
34
+ <% if (post.categories && post.categories.length > 0) { %>
35
+ <a href="<%= url_for(post.categories.toArray()[0].path) %>" class="archive-post__category">
36
+ <%= post.categories.toArray()[0].name %>
37
+ </a>
38
+ <% } %>
39
+ </article>
40
+ <% }); %>
41
+ </div>
42
+ </section>
43
+ <% }); %>
44
+ </div>
45
+ </div>
@@ -0,0 +1,76 @@
1
+ <% if (page.posts && page.posts.length > 0) { %>
2
+ <div class="category-posts-page container">
3
+ <div class="page-header animate-fade-in-up">
4
+ <h1 class="page-header__title">
5
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
6
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
7
+ </svg>
8
+ 分类: <%= page.category %>
9
+ </h1>
10
+ <p class="page-header__description">共 <%= page.posts.length %> 篇文章</p>
11
+ <a href="<%= url_for('/categories/') %>" class="page-header__back">
12
+ <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
13
+ <polyline points="15 18 9 12 15 6"></polyline>
14
+ </svg>
15
+ 返回分类列表
16
+ </a>
17
+ </div>
18
+
19
+ <div class="posts-list animate-fade-in-up animate-delay-1">
20
+ <% page.posts.each(function(post) { %>
21
+ <article class="post-card material-card">
22
+ <a href="<%= url_for(post.path) %>" class="post-card__link">
23
+ <div class="post-card__cover">
24
+ <% if (post.cover) { %>
25
+ <img src="<%= post.cover %>" alt="<%= post.title %>" loading="lazy">
26
+ <% } else { %>
27
+ <div class="post-card__cover-placeholder"></div>
28
+ <% } %>
29
+ <div class="post-card__overlay"></div>
30
+ <div class="post-card__info">
31
+ <div class="post-card__meta">
32
+ <span class="post-card__date"><%= date(post.date, 'YYYY-MM-DD') %></span>
33
+ <% if (post.categories && post.categories.length > 0) { %>
34
+ <span class="post-card__category"><%= post.categories.toArray()[0].name %></span>
35
+ <% } %>
36
+ </div>
37
+ <h2 class="post-card__title"><%= post.title %></h2>
38
+ </div>
39
+ </div>
40
+ </a>
41
+ </article>
42
+ <% }); %>
43
+ </div>
44
+ </div>
45
+ <% } else { %>
46
+ <div class="categories-page container">
47
+ <div class="page-header animate-fade-in-up">
48
+ <h1 class="page-header__title">
49
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
50
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
51
+ </svg>
52
+ 分类
53
+ </h1>
54
+ <p class="page-header__description">共 <%= site.categories.length %> 个分类</p>
55
+ </div>
56
+
57
+ <div class="categories-grid animate-fade-in-up animate-delay-1">
58
+ <% site.categories.sort('name').forEach(function(category) { %>
59
+ <a href="<%= url_for(category.path) %>" class="category-card material-card">
60
+ <div class="category-card__icon">
61
+ <svg width="32" height="32" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
62
+ <path d="M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"></path>
63
+ </svg>
64
+ </div>
65
+ <div class="category-card__content">
66
+ <h3 class="category-card__name"><%= category.name %></h3>
67
+ <span class="category-card__count"><%= category.length %> 篇文章</span>
68
+ </div>
69
+ <svg class="category-card__arrow" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
70
+ <polyline points="9 18 15 12 9 6"></polyline>
71
+ </svg>
72
+ </a>
73
+ <% }); %>
74
+ </div>
75
+ </div>
76
+ <% } %>
@@ -0,0 +1,57 @@
1
+ <div class="friends-page container">
2
+ <div class="page-header animate-fade-in-up">
3
+ <h1 class="page-header__title">
4
+ <svg width="28" height="28" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
5
+ <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71"></path>
6
+ <path d="M14 11a5 5 0 0 0-7.54-.54l-3 3a5 5 0 0 0 7.07 7.07l1.71-1.71"></path>
7
+ </svg>
8
+ <%= page.title %>
9
+ </h1>
10
+ <% if (page.description) { %>
11
+ <p class="page-header__description"><%= page.description %></p>
12
+ <% } %>
13
+ </div>
14
+
15
+ <div class="page-content animate-fade-in-up animate-delay-1">
16
+ <% if (theme.friend_links && theme.friend_links.simple && theme.friend_links.simple.length > 0) { %>
17
+ <div class="friends-grid">
18
+ <% theme.friend_links.simple.forEach(function(friend) { %>
19
+ <a href="<%= friend.url %>" target="_blank" rel="noopener" class="friend-card material-card">
20
+ <div class="friend-card__avatar">
21
+ <img src="<%= friend.avatar %>" alt="<%= friend.name %>" loading="lazy">
22
+ </div>
23
+ <div class="friend-card__content">
24
+ <h3 class="friend-card__name"><%= friend.name %></h3>
25
+ <p class="friend-card__description"><%= friend.description %></p>
26
+ </div>
27
+ </a>
28
+ <% }); %>
29
+ </div>
30
+ <% } %>
31
+
32
+ <% if (theme.friend_links && theme.friend_links.cover && theme.friend_links.cover.length > 0) { %>
33
+ <div class="friends-grid" style="grid-template-columns: repeat(3, 1fr); <% if (theme.friend_links.simple && theme.friend_links.simple.length > 0) { %>margin-top: 24px;<% } %>">
34
+ <% theme.friend_links.cover.forEach(function(friend) { %>
35
+ <a href="<%= friend.url %>" target="_blank" rel="noopener" class="friend-card friend-card--cover material-card">
36
+ <div class="friend-card__cover">
37
+ <img src="<%= friend.cover %>" alt="<%= friend.name %>" loading="lazy">
38
+ </div>
39
+ <div class="friend-card__overlay"></div>
40
+ <div class="friend-card__content">
41
+ <div class="friend-card__avatar-wrapper">
42
+ <div class="friend-card__avatar">
43
+ <img src="<%= friend.avatar %>" alt="<%= friend.name %>" loading="lazy">
44
+ </div>
45
+ <span class="friend-card__author"><%= friend.author || friend.name %></span>
46
+ </div>
47
+ <h3 class="friend-card__name"><%= friend.name %></h3>
48
+ <p class="friend-card__description"><%= friend.description %></p>
49
+ </div>
50
+ </a>
51
+ <% }); %>
52
+ </div>
53
+ <% } %>
54
+
55
+ <%- page.content %>
56
+ </div>
57
+ </div>