Hexo stellar 主题有段时间大改样式,当时没时间更新主题。感觉现在主题比较稳定了,终于找到时间把主题更新一下。由于stellar经过作者大改,我之前写的很多自定义样式都失效了。所以折腾了一上午,重新美化了一下。希望自己以后坚持每周都写一篇博客吧🐦。
博客界面
目前的博客样式
之前的历史快照
目前我是怎么发Hexo博客的
现在我基本是使用「思源笔记」来管理笔记和写博客,这是一个管理和编辑体验很好的双链笔记软件。思源笔记有一个「发布工具」插件,可以很便捷的把思源笔记里的文章上传到各个平台,非常省心,再结合思源笔记的数据库功能可以很方便的管理发布的文章。
代码更改记录
Markdown图片title标题失效
Markdown 的完整图片语法是 ![anchor text](img_src "title")
,一些笔记软件像语雀、思源笔记目前都是支持解析title作为图片标题的,一些hexo主题如butterfly应该也是支持的(也是我提的建议)。
stellar之前是接受了我的pull request,可以解析Markdown的图片title语法作为图片标题,
但现在直接把解析Markdown标题的删掉了(见issue讨论,代码改动)。
作为基本只用Markdown语法写博客的人来说,实在太不友好了,所以又把删掉的代码给加了回来。
并且改进了下 themes\stellar\scripts\filters\index.js
,减少误替换的情况发生。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| 'use strict';
hexo.extend.filter.register('after_render:html', require('./lib/img_lazyload').processSite); hexo.extend.filter.register('after_render:html', require('./lib/img_onerror').processSite);
function change_image(data) { if (this.theme.config.tag_plugins.image.parse_markdown) { data.content = data.content.replace(/\u200B/g, '');
data.content = data.content.replace( /^(?:\s*)!\[(.*?)\]\((.*?)\s*(?:"(.*?)")?\)/gm, '{% image $2 $3 %}' ); } return data; }
hexo.extend.filter.register('before_post_render', change_image, 9);
|
这样在主页就知道自己文章有多少分类了
在 /themes/stellar/layout/_partial/widgets/
下新建 categories.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
| <% function layoutCategoriesDiv() { var el='' ; if (site.categories===undefined || site.categories.length===0) { return el; } var opts=Object.assign({}, item); delete opts['title']; delete opts['layout']; opts.class='category ' ; el+=`<widget class="widget-wrapper${scrollreveal(' ')} categories-widget">`;
if (item.title) { el += '<div class="widget-header categories-header dis-select">'; el += '<span class="name">' + item.title + '</span>'; el += '</div>'; }
el += '<div class="widget-body">'; site.categories.each(function(category) { el += `<div class="${opts.class}">`; el += `<svg class="category-icon" xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.5" stroke-linecap="round"> <path d="M18 10h-5" opacity=".5" /> <path d="M10 3h6.5c.464 0 .697 0 .892.026a3 3 0 0 1 2.582 2.582c.026.195.026.428.026.892" opacity=".5" /> <path d="M2 6.95c0-.883 0-1.324.07-1.692A4 4 0 0 1 5.257 2.07C5.626 2 6.068 2 6.95 2c.386 0 .58 0 .766.017a4 4 0 0 1 2.18.904c.144.119.28.255.554.529L11 4c.816.816 1.224 1.224 1.712 1.495a4 4 0 0 0 .848.352C14.098 6 14.675 6 15.828 6h.374c2.632 0 3.949 0 4.804.77c.079.07.154.145.224.224c.77.855.77 2.172.77 4.804V14c0 3.771 0 5.657-1.172 6.828C19.657 22 17.771 22 14 22h-4c-3.771 0-5.657 0-6.828-1.172C2 19.657 2 17.771 2 14z" /> </svg>`; el += `<a href="${url_for(category.path)}">${category.name} (${category.length})</a>`; el += `</div>`; }); el += '</div>'; el += '</widget>'; return el; } %> <%- layoutCategoriesDiv() %>
|
在 themes/stellar/source/css/_layout/widgets/
下新建 categories.styl
文件,填入以下内容:
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
| // categories widget 样式 .widget-wrapper.categories-widget .widget-body { border-radius: $border-card; padding: 12px 20px; background: var(--alpha50); // 这里设置背景 box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1); // 添加阴影效果 }
// 每个分类的样式 .category line-height: 1.5 margin: 8px 0 display: flex // 使用flex布局来确保图标和文本在同一行 align-items: center // 垂直居中对齐
.category-icon width: 16px height: 16px vertical-align: middle margin-right: 8px
.category a display: inline-block // 链接以行内块方式显示 word-break: break-word color: var(--text-p2) font-family: system-ui font-weight: 300 font-size: 16px text-decoration: none &:hover color: $color-hover text-decoration: underline
// Variables $color-hover = #0366d6
|
参考:Stellar 主题中添加分类索引 Widget - 宇宙尽头的餐馆
随机文章按钮
创建 themes/stellar/scripts/helpers/random.js
,增加以下代码:
1 2 3 4 5 6 7 8
| hexo.extend.filter.register('after_render:html', function (data) { const posts = [] hexo.locals.get('posts').map(function (post) { if (post.random !== false) posts.push(post.path) }) data += `<script>var posts=${JSON.stringify(posts)};function toRandomPost(){ var randomPath = posts[Math.floor(Math.random()*posts.length)]; var encodedPath = encodeURIComponent(randomPath); window.open('/' + encodedPath, "_self"); };</script>` return data })
|
参考:Hexo Stellar 主题装修笔记 - 宇宙尽头的餐馆:随机文章按钮
备注:文章路径需要用encodeURIComponent
来编码,否则如果文章路径里有连字符,没有在前面加上域名地址,导致打开失败。
增强标签显示
现在相比于分类我可能会更喜欢用标签,因为一篇文章可以打多个标签。我在思源笔记里管理笔记也是用管理链接的方式而弃用了文档树分类,所以标签更符合我管理笔记的习惯。stellar默认在文章列表只显示分类,对我来说就有点难受了。
主页文章列表添加标签
修改themes/stellar/layout/_partial/main/post_list/post_card.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
| if (post.categories && post.categories.length > 0) { if (post.layout === 'post' && post.categories && post.categories.length > 0) { var cats = []; if (post.categories) { post.categories.forEach((cat, i) => { cats.push(cat.name); }); } if (cats.length > 0) { let cat = cats.shift(); el += '<span class="cap breadcrumb"' + category_color(cat) + '>'; el += icon('default:category') el += `<span>${cat}</span>` el += '</span>'; } } } if (post.sticky) { el += `<span class="pin">${icon('default:pin')}</span>` } el += '</div>';
el += '<div style="margin: 4px 0px;">'; if (post.tags && post.tags.length > 0) { el += '<span class="cap tags">';
el += post.tags.map(tag => `<span style="background-color: var(--tag-bg-color); padding: 0px 6px; margin: 0px 5px 0px 0px;border-radius: 5px; color: var(--tag-text-color); line-height: 1.5;">#<span>${tag.name}</span></span>`).join('');
el += '</span>'; }
el += '</div>'; el += '</article>'; return el;
|
自定义样式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| :root { --tag-bg-color: #F2EEFD; --tag-text-color: #835EEC; } @media (prefers-color-scheme: dark) { :root { --tag-bg-color: #282433; --tag-text-color: #A28BF2; } }
#post-meta { font-size: 12px; color: var(--text-p4); }
|
在文章页面添加标签显示
在 layout/_partial/main/navbar/article_banner.ejs
文件中,找到
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| el += `<div class="flex-row" id="breadcrumb">` el += `<a class="cap breadcrumb" href="${url_for(config.root)}">${__("btn.home")}</a>` if (theme.wiki.tree[page.wiki]) { el += partial('breadcrumb/wiki') } else if (page.layout == 'post') { el += partial('breadcrumb/blog') } else { el += partial('breadcrumb/page') } el += `</div>`
|
并在后面添加:
1 2 3 4 5 6 7 8 9 10 11 12 13
| if (page.layout == "post" && page.tags && page.tags.length > 0) { el += '<div id="tag">'; el += ' <span> 标签:</span>'; el += list_categories(page.tags, { class: "cap breadcrumb", show_count: false, separator: ' ', style: "none" }); el += ' </div>'; }
|
参考:Hexo Stellar 主题装修笔记 - 宇宙尽头的餐馆:在文章页面添加标签显示
自定义css
文章内更新日期始终显示
1 2 3 4
| .bread-nav div#post-meta span.updated { visibility: visible !important; }
|
自定义滚动条样式
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
|
::-webkit-scrollbar { width: 8px; height: 8px; }
::-webkit-scrollbar-track { background-color: rgba(200, 155, 155, 0); border-radius: 2em; }
::-webkit-scrollbar-thumb { background-color: #c3c0c1 !important;
border-radius: 2em; }
::-webkit-scrollbar-corner { background-color: transparent; }
[data-theme="dark"] ::-webkit-scrollbar-thumb { background-color: #1f1f1f !important; }
|
限制代码块的最大高度
1 2 3 4
| .md-text .highlight { max-height: 800px; overflow: auto; }
|
链接样式优化
1 2 3 4 5 6 7 8 9 10 11 12
|
li:not([class]) a:not([class]), p:not([class]) a:not([class]), table a:not([class]) { padding-bottom: 3px; padding-right: 1px; margin-right: 2px; color: var(--theme-link); background: linear-gradient(0, var(--theme-link), var(--theme-link)) no-repeat center bottom / 100% 2px; }
|
参考:Hexo Stellar 主题装修笔记 - 宇宙尽头的餐馆:超链接样式调整
添加最新评论组件
参考:Stellar展示最新评论 - 星日语 (weekdaycare.cn)
vercel app准备
-
部署 repo 至 Vercel:Achuan-2/recent-comment (github.com)
-
需要在vercel中设置环境变量
name |
description |
LIMIT |
获取数量 |
GITHUB_REPO_OWNER |
Github用户名 |
GITHUB_REPO_NAME |
仓库名 |
GITHUB_CATEGORY_ID |
Discussions分类名称 |
GITHUB_TOKEN |
Github Access Token |
-
配置完成后请redeploy!
-
查看是否能正确输出最新评论的json数据
stellar主题修改
-
在 theme/source/js/services/
下新建 giscus_new.js
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
| utils.jq(() => { $(function () { const els = document.getElementsByClassName('ds-giscus'); for (var i = 0; i < els.length; i++) { const el = els[i]; const api = el.getAttribute('api'); if (api == null) { continue; } const default_avatar = def.avatar; utils.request(el, api, function (data) { const limit = el.getAttribute('limit'); data.forEach((item, i) => { if (limit && i >= limit) { return; } comment = item.body.length > 50 ? item.body.substring(0, 50) + '...' : item.body; var cell = '<div class="timenode" index="' + i + '">'; cell += '<div class="header">'; cell += '<div class="user-info">'; cell += '<img src=" + (item.author.avatarUrl || default_avatar) + " onerror="javascript:this.src=\\" + default_avatar + "\\";">'; cell += '<span>' + item.author.login + '</span>'; cell += '</div>'; cell += '<span>' + new Date(item.createdAt).toLocaleString() + '</span>'; cell += '</div>'; cell += '<a class="body" href="' + item.url + '" target="_blank" rel="external nofollow noopener noreferrer">'; cell += comment; cell += '</a>'; cell += '</div>'; $(el).append(cell); }); }); } }); });
|
-
_config.stellar.yml
主题配置中引入
1 2 3 4 5
| data_services: ... giscus: js: /js/services/giscus_new.js
|
-
在 _data/widgets.yml
中创建小组件,并在_config.stellar.yml
中选择在哪里展示
1 2 3 4 5 6 7
| new_comment: layout: timeline title: 最新评论 api: https://xxx.vercel.app type: giscus limit: 16
|
成果展示
Fix 使用搜索功能搜到的部分文章无法打开
我目前使用思源笔记这个笔记软件的「发布工具」插件把笔记发布到hexo
发布工具支持在yaml里放永久链接
由于永久链接是/post/id.html
形式,而使用local search搜索的时候,这些文档则会打开为https://post/id.html
,导致失败
所以需要对data.path进行检测,如果以’//'开头,则path字符串只取第二位到最后一位,使其能正常打开
在themes\stellar\source\js\search\local-search.js
进行修改
1 2
| - var dataUrl = data.path; + var dataUrl = data.path.startsWith('//') ? data.path.slice(1) : data.path;
|
已提交Pull request:https://github.com/xaoxuu/hexo-theme-stellar/pull/450