本博客归纳总结了Hexo+stellar的使用教程,作平时编写、维护博客之用。

使用前注意事项

  • 查阅本文的前提是,你已经依照教程搭建好了hexo博客站,其themes/目录下已导入stellar主题。

  • 本文的路径格式:除非特殊说明,以/开头的,就是./public/下的相对路径。其他的就是博客工程项目的工作目录./下的路径。

  • Hexo框架stellar主题有新版本时,本文也可考虑更新,方法见配主题

  • Tag Plugins(标签插件)说明

    • Hexos说,markdown语法不能包裹标签插件。但是我测试,是可以的。
      如:有色的链接

    • 反过来,有的标签插件能包裹markdown语法,有的却不能正确渲染。
      行内的标签插件在生成绿字的标签插件中加[一个链接](https://images.weserv.nl/?url=assets.taddream.site)就无法生效

      应对方法:可考虑直接写入HTML代码,如:<a href="http://example.com/">一个链接</a>

    • 所有的标签插件的语法中: 用空格分隔多个参数(当需要真正的空格,请使用&nbsp;代替);用方括号表示可选参数;用冒号分隔键值对参数(无空格)。

主题更新历史

Hexo框架

常用命令

参考

  • 写作
    • hexo new post "title1": 会在/source/_posts下创建title1.md;
    • hexo new page title2 -p dir1/dir2/filename: 会在/source/下创建title2.md;

基础配置

参考
主题相关的配置的优先级从高到低:

  • post文章中的font-matter
  • 有stellar主题时,wiki/topic类文章中的source/_data/[wiki,topic]/[project_name].yml
  • _config.yml的theme_config键
  • _config.[theme].yml
  • themes/[theme_name]/_config.yml

文章里:front-matter配置

这里的配置直接定义文章所属页面的装修风格,在所有配置文件中优先级最高。常用的配置模板详见这里raw代码
这里只介绍部分配置:

  • layout: 指定文章的布局类型。post类型和其他自定义类型,存入source/_posts; page类型,存入source/
  • comments:是否可用bool(TODO)
  • categories: Hexo不支持多个同级分类,解决办法

文章里: 标签插件

标签插件(Tag Plugins)不应该被包裹在 Markdown 语法中。

引用块 blockquote

{% blockquote [author[, source]] [link] [source_link_title] %}
content
{% endblockquote %}

Every interaction is both precious and an opportunity to delight.

更简单的引用块,> content

代码块 codeblock或code

{% codeblock [title] [lang:language] [url] [link text] [additional options:value] %}
code snippet
{% endcodeblock %}
其中,额外选项有:line_number:true ; line_threshold:0 ; highlight:true ; first_line:1 ; mark:1,4-7,10。
用in更优雅python小技巧
1
2
3
4
num = 1
if num in(1,3,5):
type = '奇数'
print(type)

更简单的代码块,用反引号:``` [language] [title] [url] [link text] code snippet ```

自己的代码资源嵌入 include_code

{% include_code [title] [lang:language] [from:line] [to:line] path/to/file %}

这里path/to/file的根目录是source/downloads/code

tag-embed式代码、视频嵌入

需要事先安装hexo-tag-embed插件:npm i hexo-tag-embed

  • Gist的代码块嵌入:{% gist gist_id [filename] %}
  • jsfiddle的前端代码块嵌入:{% jsfiddle shorttag [tabs] [skin] [width] [height] %}
  • vimeo视频嵌入:{% vimeo video_id [width] [height] %}
  • YouTube视频嵌入:{% youtube video_id [type] [cookie] %}

避免渲染的块 raw

语法:{\% raw %}content{% endraw \%}(使用时把\去掉)
content可以是任何内容,包括标签插件、markdown语法等。
实现效果为:

{% mark 在绿字中加一个[链接](https://images.weserv.nl/?url=assets.taddream.site/build_site_images/备选头像2.png) color:green %}

更好用的视频嵌入 iframe

  • iframe标签,美观度一般:{% iframe url [width] [height] %}

  • 直接上HTML代码:更复杂、更定制化的视频嵌入: <iframe src="//player.bilibili.com/player.html?aid=566104739&bvid=BV1Tv4y1r7ZG&cid=985684333&page=1&autoplay=0" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" class="bilibili-video" style="width:100%;min-height:315px"> </iframe>

图片嵌入 img

{% img [class names] /path/to/image [width] [height] '"title text" "alt text"' %}

我的评价:markdown格式更简洁:![](url),或者stellar的更好。

{% link text url [external] [title] %}

我的评价:不如stellar的。

assets目录下的资源嵌入

站内图片、文件的更定制化的、路径简单化的嵌入方式,但我就只用markdown。

引用自己post目录下的文章 post_link

{% post_path filename %}{% post_link filename [title] [escape] %}(title默认是filename;escape默认要转义,即true)
如:debug手册

优点:在使用此标签时可以忽略文章文件所在的路径或者文章的永久链接信息、如语言、日期。
我的评价:不如markdown语法方便,[标题](/post/文件名)

功能扩展

  • 想自定义小功能:编写JS脚本,放进/scripts/下即可;
  • 想探索更多功能:插件商店

stellar主题

不同于hexo框架只有一种文章类型(即/post/下的普通博客文章),stellar主题增加了两种:

  • topic类–专栏文章
    也就是把/post/下同一话题的文章形成一个集合,这比起hexo自带的‘博客文章的tag分类’功能,要更直观易读一些,因为topic类的风格相当于一个简化版的 wiki 系统。
    而本质上,专栏文章也都是处于/post/下的普通文章。
  • wiki类–项目文章
    这就是我们熟知的wiki技术文档了,多篇文章组合成一个wiki项目。
    项目文章处于/wiki/下的每个项目中。

基础配置

所有配置直接见配置文件_config.yml_config.stellar.yml和主题子模块中的_config.yml,里面有详细备注和解释。下面只介绍部分配置。

配置默认布局(站点主结构树)

位于_config.stellar.yml中的site_tree
其中有两种页面类型:列表类页面、内容类页面;三种文章类型:普通文章、专栏文章、项目文章。

网站风格配置

位于_config.stellar.yml中的style
可配置主题色、字体、背景图片等。

  • 若想引入外部字体,步骤如下
    step1 获取在线字体嵌入代码

    进入字体库如Google FontsGoogle Fonts CNAdobe Fonts等。
    在里面获取你想要的嵌入代码,如<link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC&display=swap" rel="stylesheet">

    step2 引入字体
    _config.stellar.yml
    inject: 
    head:
    # 这里引入了"Noto Serif SC"字体
    - <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC&display=swap" rel="stylesheet">
    style:
    font-family:
    # 使用该字体,放在前面的优先级更高。
    body: '"Noto Serif SC", "Microsoft Yahei",..., sans-serif'

文章头:front-matter配置

直接见scaffolds/post.md,里面有详细备注和解释。

文章里:标签插件 Tag Plugins

不同于hexo框架里的标签插件, stellar的作者自定义了许多有特色的插件。文档如下;源码路径在themes/stellar/scripts/tags/index.js

表达类标签

01-emoji(行内)

已配置的库有:qq(default), twemoji, aru, tieba, blobcat

  • 语法和示例:
    {% emoji [source] name [height:1.75em] %}
    {% emoji 爱你 %}
    {% emoji blobcat ablobcatrainbow %}
    {% emoji blobcat ablobcatrainbow height:4em %}
    {% emoji blobcat ablobcatattentionreverse %}
    {% emoji tieba 滑稽 %}
  • 效果:
02- mark 文本颜色标记(行内)
  • 语法和示例:
    {% mark 默认 %} 
    {% mark 红 color:red %}
    {% mark 橙 color:orange %}
    {% mark 黄 color:yellow %}
    {% mark 绿 color:green %}
    {% mark 青 color:cyan %}
    {% mark 蓝 color:blue %}
    {% mark 紫 color:purple %}
    {% mark 浅 color:light %}
    {% mark 深 color:dark %}
    {% mark 警告 color:warning %}
    {% mark 错误 color:error %}
  • 效果:默认 绿 警告 错误
03- hashtag 标签(行内)

类似mark标签,但其文本是自定义的,还可带链接

04- image 图片标签
  • 语法:{% image src [description] [download:bool/string] [width:px] [padding:px] [bg:hex] [fancybox:true] %}
    ## 谨记,键值对间不要有空格
    src: 图片地址
    description: 图片描述
    download:href # 下载地址,设置此值后鼠标放在图片上会显示下载地址,如果下载地址为图片地址,可以设置为 true
    width:200px # 图片宽度
    padding:16px # 图片四周填充宽度
    bg:'#ffffff' # 图片区域背景颜色,16进制; 或用`white`等;或用动态配色`var(--card)`
    fancybox:true # 可点击放大图片。另外也可在config.tag_plugins.image.fancybox中设置全局默认值。
  • 效果:
    来自unsplash的大海图集
    来自unsplash的大海图集
    \{% image https://source.unsplash.com/320x640/?forest 来自unsplash 的森林图集 padding:16px bg:var(--card) %\}
    \{% image https://source.unsplash.com/320x640/?forest 来自unsplash 的森林图集 padding:16px bg:var(--card) %\}
05- quot 引用(标题式的)

跟Hexo中的quote不是一个东西。
其作用是居中醒目表示。其中el参数可使其变为居中的标题。
icon参数的值的定义,是在config系列文件的tag_plugins.quot中设置的。

  • 语法:{% quot 内容 [icon:default/hashtag] [el:h2] [prefix:] %}
  • 效果:

    Stellar 是最好用的主题

    热门话题

    这是一个 icons.yml 配置的示例

    这是一个 url 的示例

06- poetry 诗词
  • 语法:
    {% poetry 游山西村 author:陆游 footer:诗词节选 %}
    莫笑农家腊酒浑,丰年留客足鸡豚。
    **山重水复疑无路,柳暗花明又一村。**
    {% endpoetry %}
  • 效果:
    游山西村
    陆游

    莫笑农家腊酒浑,丰年留客足鸡豚。
    山重水复疑无路,柳暗花明又一村。

07- note 备注块
  • 语法:{% note [title] content [color:red/amber/orange/yellow/green/cyan/blue/purple/light/dark/warning/error] %}

    如果标题中需要显示空格,请使用&nbsp;代替

  • 效果:
    这 是标题

    这是正文 哈哈。

    这是正文哈哈。

09- mermaid 图表

学习研究 https://mermaid.js.org/intro/
安装插件:npm install --save hexo-filter-mermaid-diagrams

  • 示例:
    #```mermaid
    graph LR
    A(Section A) -->|option 1| B(Section A)
    B -->|option 2| C(Section C)
    #```
  • 效果:
    graph LR
    A(Section A) -->|option 1| B(Section A)
    B -->|option 2| C(Section C)
10- copy 复制行
  • 语法:
    • 过时了:{% copy [width:max/...] [git:ssh/gh/https] 内容 %}
    • v1.23.0:{% copy [git:ssh/gh/https] 内容 [prefix:任意字符串] %}

      当有git参数时,内容只需输入域名+仓库名

  • 效果:
    $
    https
11- radio 单选框
  • 语法:{% radio [checked:true/false] [color:red/orange/yellow/green/cyan/blue/purple] 框后的文字 %}
  • 效果:
    没有勾选的单选框
    已勾选的单选框
12- checkbox 复选
  • 语法:{% checkbox [symbol:plus/minus/times] [color:red/orange/yellow/green/cyan/blue/purple] [checked:true/false] 框后的文字 %}
  • 效果:
    你看,这是绿色文字
13- navbar 导航栏(文章内的)
  • 语法:{% navbar active:/path [按钮名]() ... %}

    active 参数用于指定高亮

  • 效果:
14- frame 设备框架(不咋懂,不常用)
  • 语法:{% frame iphone11 img:/assets/wiki/prohud/toast/demo-loading.png video:/assets/wiki/prohud/toast/demo-loading.mp4 focus:top %}
  • 效果:
15- 文本修饰标签集(行内)
  • {% psw 密码 %} : 这是 密码 标签
  • {% u 下划线 %} : 这是 下划线 标签
  • {% emp 着重号 %} : 这是 着重号 标签
  • {% wavy 波浪线 %} : 这是 波浪线 标签
  • {% del 删除线 %} : 这是 删除线 标签
  • {% sup 上角标 color:red %} : 这是 上角标 标签
  • {% sub 下角标 %} : 这是 下角标 标签
  • {% kbd 键盘样式 %} : 这是 键盘样式 标签,试一试: + D
16- 目标管理(Objectives and Key Results)

形象展示一个目标下多个关键点的进度。

O1
2024年的小目标:完成 Volantis 6.0 并发布上线

来自2025年的复盘:已《基本》实现目标

正常 44%
KR1
重构 tag-plugins 和 wiki 系统
  • KR 进度为 100% 时,标签默认显示为 已完成
  • KR 未设置进度时,默认为 0%
  • O 未设置进度时,则显示所有 KR 进度平均值
已完成 100%
KR2
完成主要页面设计稿

您可以在 _config.yml 文件中修改标签的颜色和文案

您可以在 _config.yml 文件中增加任意的标签配置

延期 90%
KR3

完成前置准备工作(如果你知道答案,请在留言区帮帮我!🥹)

在咸水和海滩之间找一亩地
求出圆周率后15位
找出宇宙的终极逻辑
去地狱里走两步
未完成 -12%
KR-4

开发、测试和发布

站点头像
站点头像
风险 0%
{% okr o1 %}

2024年的小目标:完成 Volantis 6.0 并发布上线
来自2025年的复盘:已《基本》实现目标 {% emoji tieba 滑稽 %}

<!-- okr kr1 percent:1 -->
重构 tag-plugins 和 wiki 系统
- 当 {% mark KR %} 进度为 100% 时,标签默认显示为 {% mark color:green 已完成 %}
- 当 {% mark KR %} 未设置进度时,默认为 {% mark 0% %}
- 当 {% mark O %} 未设置进度时,则显示所有 {% mark KR %} 进度平均值

<!-- okr kr2 percent:0.9 status:off_track -->
完成主要页面设计稿
{% tabs align:left %}
<!-- tab 小提示1 -->
您可以在 _config.yml 文件中修改标签的颜色和文案
<!-- tab 小提示2 -->
您可以在 _config.yml 文件中增加任意的标签配置
{% endtabs %}

<!-- okr kr3 percent:-0.12 status:unfinished -->
完成前置准备工作(如果你知道答案,请在留言区帮帮我!🥹)
{% checkbox 在咸水和海滩之间找一亩地 %}
{% checkbox 求出圆周率后15位 %}
{% checkbox 找出宇宙的终极逻辑 %}
{% checkbox 去地狱里走两步 %}

<!-- okr kr-4 status:at_risk -->
开发、测试和发布
{% image /assets/wiki/stellar/icon.svg height:64px 支持嵌套插入图片等其它简单组件 %}

{% endokr %}

17-icon 图标标签(行内)

支持在任意位置插入图标。可以是外链图标,也可以在source/_data/icons.yml中提前配置好。

  • 在主题配置中设置默认颜色: 去tag_plugins -> icon -> default_color中设置。
  • 语法:{% icon [color:red] %}
    {% icon solar:planet-bold-duotone color:green %}  # 使用icons.yml中的图标
    {% icon https://api.iconify.design/fluent-emoji-flat/alarm-clock.svg %} # 使用外链图标
  • 效果:;
18- button 按钮(行内)
  • 语法:{% button text url [icon:key/src] [color:color] [size:xs] %}
    参数解释:
    text: 探索 # 按钮上的文字
    url: # 跳转链接
    color: orange # theme, accent, red, orange, yellow, green, cyan, blue, purple
    icon: solar:planet-bold-duotone # 显示图标,支持 icon.yml 中的文件名和外链图标
    size: xs # 按钮尺寸,目前只有两种尺寸:默认是普通大小, xs 是最小号
  • 效果:探索({% button 探索 https://xaoxuu.com/wiki/stellar/ icon:solar:planet-bold-duotone color:green size:xs %})
19- audio 音频标签

支持音乐外链以及网易云音乐,网易云支持设置 type 以及 autoplay 参数。

  • 语法:{% audio type:2 netease:1856385686 autoplay:0 %}{% audio %}
    type: 2 # 2(default): 歌曲模式; 0: 歌单模式 
    netease: 1856385686 # 网易云音乐的歌曲ID,具体 id 在网易云网页版的网址链接中寻找
    autoplay: 0 # 是否自动播放,0(default): 手动播放, 1: 自动播放
  • 效果:
20- video 视频标签

支持bilibili(支持自动播放)和视频外链,可设置最大宽度。
另可参考更复杂但更定制化的HTML-iframe方法

目前 bilibili 的 iframe 标签不能放进 grid 容器里,原因未知。

  • 语法:{% video bilibili:BV1GP4y1d729 width:100% autoplay:0 %}{% video %}
    bilibili: BV1GP4y1d729 # B站视频的 BV 号
    width: 100% # 视频宽度,默认是 100%
    autoplay: 0 # 是否自动播放,0(default): 手动播放, 1: 自动播放
  • 效果:

数据集合类标签(5个)

timeline 时间线
静态时间线

场景1– 制作教程/日程

写法

{% timeline %}
<!-- node 第一步:打开 GitHub -->
打开 [Stellar](https://github.com/xaoxuu/hexo-theme-stellar/) 的 GitHub 页面。
<!-- node 第二步:点击 Star -->
如果发现右上角的 Star 还没点亮,就点亮它!
{% endtimeline %}

效果

第一步:打开 GitHub

打开 Stellar 的 GitHub 页面。

第二步:点击 Star

如果发现右上角的 Star 还没点亮,就点亮它!

动态时间线
  • 场景2:显示某人GitHub Issues的动态说说

    写法

    {% timeline api:https://api.github.com/repos/JamesRay0713/blog-comments/issues?direction=asc&per_page=3 %}{% endtimeline %}

    效果

  • 场景3:显示友链朋友圈(极简版)
    友链朋友圈, 就是汇聚了你的所有友链最新发布的文章列表。
    实现该场景的前提是,已经爬取好了文章列表data.json(爬取方法参考)。

    写法

    {% timeline type:fcircle api:https://raw.githubusercontent.com/JamesRay0713/blog-friends-circle/main/data.json %}{% endtimeline %}

    效果

  • 场景4:爬取微博动态 TODO

    1. fork 爬虫仓库 ,修改自己的仓库名
    2. 修改 .github/workflows/main.yml 中的微博ID为你想爬取的ID,修改完后每天会自动爬取你的微博,存储为 json 文件,输出文件在 output 分支
    3. {% timeline limit:20 type:weibo api:你的json文件地址 %}{% endtimeline %}
静态+动态

写法

{% timeline reversed:true api:https://api.github.com/repos/xaoxuu/blog-timeline/issues?per_page=2 %}
<!-- node 这条内容为静态数据 -->
这条内容为静态数据,静态数据在 `deploy` 时就已经确定了。
{% endtimeline %}

效果

这条内容为静态数据

这条内容为静态数据,静态数据在 deploy 时就已经确定了。

对时间线内容做筛选 TODO

筛选方式:可在tag-plugin中增加属性(如user:xaoxuu),也可在api中增加参数(如?labels=todo&per_page=3
更多用法详见

  • 示例:
    {% folders %}
    <!-- folder 只显示某个人的数据 -->
    {% timeline user:xaoxuu api:https://api.github.com/repos/volantis-x/hexo-theme-volantis/issues %}{% endtimeline %}
    <!-- folder 筛选最近3条todo -->
    {% timeline api:https://api.github.com/repos/xaoxuu/hexo-theme-stellar/issues?labels=todo&per_page=3 %}{% endtimeline %}
    <!-- folder 筛选评论最多的3条建议 -->
    {% timeline api:https://api.github.com/repos/volantis-x/hexo-theme-volantis/issues?labels=feature-request&per_page=3&sort=comments %}{% endtimeline %}
    {% endfolders %}
  • 效果:
    只显示某个人的数据
    筛选最近3条todo
    筛选评论最多的3条建议
friends 友链

友链的语法是{% friends {url或友链组名} %}。它其实跟sites标签插件的功能师出同门。
有两种生成友链的方法:

  • 静态友链:即自己手动地把一些网站信息放到你的友链组中,从而被friends标签插件使用。
  • 动态友链:即让那些’想把自己的网站加入到你的友链中’的朋友主动地在指定仓库添加网站信息,再自动生成json文件,该文件的url可被friends标签插件使用。
静态友链

先在source/_data/links/下新建一个自定义的友链组文件(e.g. <custom_group_name>.yml),里面存放属于某一个组别的友链,格式如下:

source/_data/links/custom_group_name.yml
- title: 某某某
url: https://
cover:
icon:
description:
- ...

之后你可以在任何位置插入该友链组。

动态友链
step1: 准备一个友链专用仓库

xaoxuu/issues-json-generator仓库fork过来。这个仓库的原理是:在issue区配置有issue模板,当有伙伴按照模板提交了自己网站的信息后,该仓库的action会运行以抓取issue的信息并转为json格式,输出到output分支的v2/data.json文件,这个文件就是友链的数据源。

step2: 修改仓库的`config.yml`

最重要的就是把下面的repo换成自己的。

issues:
repo: xaoxuu/friends # 仓库持有者/仓库名(改成自己的存放友链的仓库,比如我的就是`JamesRay0713/blog-friends-link`)
label: active # 筛选具有 active 标签的 issue ,取消此项则会提取所有 open 状态的 issue
sort: # updated-desc # 排序,按最近更新,取消此项则按创建时间排序
step3: 做一个添加友链的测试

JamesRay0713/blog-friends-link的issue按照模板提交一个网站信息。不出意外的话,等待一分钟,这个仓库就会自动新增output分支并生成v2/data.json文件。

step4: 使用动态友链

写法

大佬的: {% friends api:https://raw.github.xaox.cc/xaoxuu/friends/output/v2/data.json %}
我的: {% friends api:https://raw.githubusercontent.com/JamesRay0713/blog-friends-link/output/v2/data.json %}

效果
我的:

sites 网站卡片

实现方法和friends标签插件类似,也支持静态数据和动态数据。动态的类似动态友链; 静态的是先新建source/_data/links/组名.yml格式如下:

- title: 标题
url: https://
cover:
icon:
description:

然后在任意位置使用

{% sites sites-group-开源大佬 %}

即可得到如下效果:

md 渲染外部 markdown 文件

语法:

{% folding %}
{% md https://raw.github.xaox.cc/xaoxuu/hexo-theme-stellar/main/README.md %}
{% endfolding %}

效果:

ghcard 卡片
  • 示例:{% ghcard 用户名 %}{% ghcard 用户名/仓库名 theme:dark %}
  • 效果:

更多API参考官方文档

toc 文档目录树

实现了把一个wiki文档的目录放到任何一个地方。
相关配置:source/_data/widgets.yml中也有toc组件,这个组件可用于source/_config.stellar.yml中的sidebar,或用于文章的front matter。

容器类标签(11个)

box 普通块、代码块容器
  • 语法:{% box [title] [color:color] [child:codeblock/tabs] %}内容{% endbox %}

  • 效果1:child参数为空, 则和note功能类似

    注:stellar的note标签插件,就是基于box的。

    写法

    {% box Stellar v1.12.0 color:warning %}
    因为原 noteblock 标签在升级到 hexo 6.0 之后跟官方库冲突了 。。。
    {% endbox %}

    效果

    Stellar v1.12.0

    因为原 noteblock 标签在升级到 hexo 6.0 之后跟官方库冲突了 。。。

  • 效果2:child参数为codeblock——和Hexo的code功能重复

    注:优劣对比,stellar的box更美观;但hexo的code配置参数更多。

    写法

    {% box /path/to/code child:codeblock color:green %}
    \`\`\`swift
    func test() {
    // ...
    }
    \`\`\`
    {% endbox %}

    效果

    /path/to/code
    func test() {
    // ...
    }
  • 效果3:child参数为tabs——里面就可以嵌套一个tabs标签插件

    个人电脑作为办公设备时,我们该如何保护隐私?
    个人电脑作为办公设备时,我们该如何保护隐私?
    公司一般都会强制安装安防软件,这些软件要求开机自启动,要求有屏幕录制权限、完全的磁盘访问权限包括相册图库。因此如果使用自己的 MacBook 作为办公设备,必须要把生活区和工作区完全独立开,安装在两个磁盘分区,并且对磁盘分区进行加密。
folding 折叠容器
语法
{% folding title codeblock:true open:false color:green %}
content...
{% endfolding %}
参数解释
title: string/empty   # 标题
codeblock: true/false # 或者用`child:codeblock/...`,表示是否是代码块
open: true/false # 默认折叠(false)
color: red/orange/yellow/green/cyan/blue/purple/light/dark
  • 效果1– 彩色可折叠代码块:

    默认打开的代码折叠框
    func test() {
    // ...
    }
  • 效果2– 嵌套折叠容器

    警告1

    警告2

    警告3

    ok

folders 多个折叠容器聚合

写法

{% folders %}
<!-- folder 题目1 -->
这是答案1
<!-- folder 题目2 -->
这是答案2
<!-- folder 题目3 -->
这是答案3
{% endfolders %}

效果

题目1

这是答案1

题目2

这是答案2

题目3

这是答案3

tabs 分栏容器

写法

{% tabs active:2 align:center %}
<!-- tab 图片 -->
{% image https://images.weserv.nl/?url=assets.taddream.site/build_site_images/网站图标2.png width:300px %}
<!-- tab 代码块 -->
#```swift
let x = 123
print("hello world")
#```
<!-- tab 表格 -->
| a | b | c |
| --- | --- | --- |
| 11 | 22 | 33 |
| 44 | 55 | 66 |
{% endtabs %}

效果

let x = 123
print("hello world")
abc
112233
445566
grid 网格分区容器

1.24.0 版本后获得重构,支持固定列数、动态列数、设置间距和圆角。

语法
{% grid [w:240px] [c:2] [bg:box/card] [gap:32px] [br:4px] %}
<!-- cell -->
内容
<!-- cell -->
内容
{% endgrid %}
参数解释
w: 240px      # 网格宽度,默认是240像素
c: 2 # 网格列数,不指定时会按照`w`的宽度自动计算
bg: box/card # 背景样式,不指定时无样式
gap: 16px # 网格间距,默认是 16px
br: 4px # 圆角半径`border-radius`,默认是4px

示例,一个简单的动态网格:

Unsplash Photo
The Galactic Center is the rotational center of the Milky Way galaxy. Its central massive object is a supermassive black hole of about 4 million solar masses, which is called Sagittarius A*.

Ōwhiro Bay, Wellington, New Zealand
Published on May 31, 2022
SONY, ILCE-6000
Free to use under the Unsplash License

图片引入格式只支持md语法。

语法
{% gallery [layout:grid/flow] [ratio:origin/square] [size:s/m/l/xl/mix] %}
![@author]({url})
...
{% endgallery %}
参数解释
layout: grid/flow  # 网格布局/流式布局
ratio: origin/square # 图片比例,原始比例/方形比例
size: s/m/l/xl/mix # 图片尺寸,小/中/大/超大/混合

以上这些参数也可以前往theme-config文件中的tag_plugins.gallery配置默认值。

示例:

albums 专辑容器

用于陈列音乐专辑。是gallery的超集,支持点击跳转
使用该容器前,需在source/_data/links/<组名>.yml中录入音乐列表。

source/_data/links/<组名>.yml的格式
- title: Hans Zimmer
url: https://www.douban.com/personage/27260154/
avatar: https://xaoxuu.com/assets/avatar/hans-zimmer-profile.jpg # 键名用icon也行
- ...
语法(参数含义作者暂未告知)
{% albums 组名 [repo:owner/repo] [api:http] [size:s/m/l/xl/mix] %}

效果:

posters 海报容器

用于陈列电影、音乐、游戏等海报。是gallery的超集,支持点击跳转
使用该容器前,需在source/_data/links/<组名>.yml中录入海报列表,其格式和albums一样。

语法:{% posters 组名 %}
效果:

将取代about容器

  • 用法1:独立页面的顶部横幅,内部可以套一个导航栏。

    {% banner 标题 bg:背景图片路径 %}
    {% navbar active:/wiki/ [文章](/post/) [项目](/wiki/) %}
    {% endbanner %}
  • 用法2:个人资料页的横幅,可以加一个头像

    {% banner 某某 这是个人简介 avatar:/path.png bg:/path.jpg %}
    {% endbanner %}
  • 用法3:对link链接卡片的美化

    {% banner 标题 摘要。 bg:路径或url link:路径或url %}
    {% endbanner %}
about 关于块容器

略,将废弃

swiper 轮播容器
语法:(url的插入有两种格式:md或tag-plugin)
{% swiper [effect:cards/coverflow] [width:min/max] %}
![](url)
{% image url width:300px %}
...
{% endswiper %}

效果:

文章尾:评论区插件

stellar作者提供了多种插件,我这里只介绍giscus,它是由 GitHub Discussions 驱动的评论系统。

  • 主题配置文件中的配置方法:
    _config.stellar.yml
    comments:
    service: giscus
    # 教程见`https://zhuanlan.zhihu.com/p/603658639`:总结就是进入https://giscus.app/zh-CN 进行各种配置,最后得到一个<script>元素,其内部的各种属性就用来填充在下面。
    giscus:
    src: https://giscus.app/client.js # 当使用自建的 giscus 服务后,这里要相应更改。具体使用方法,等有需要再学 TODO
    data-repo: xxx/xxx # [在此输入仓库]
    data-repo-id: # [在此输入仓库 ID]
    data-category: # [在此输入分类名]
    data-category-id:
    data-mapping: pathname # 按文章的路径映射评论区。还可以是其他方式,如number
    data-strict: 0
    data-reactions-enabled: 1
    data-emit-metadata: 0
    data-input-position: top # top, bottom
    data-theme: preferred_color_scheme
    data-lang: zh-CN
    data-loading: lazy
    crossorigin: anonymous
  • 也可以在front matter中设定评论区(优先级最高),如:
    source/_posts/title.md
    title: xxx
    giscus:
    data-repo: JamesRay0713/blog-comments
    data-mapping: number
    data-term: 226 # 一个数字映射一个评论区,不同文章下设定相同数字,则它们共享一个评论区。

文章侧:小组件

作者实现了9个组件布局模板,我们也可依此自定义更多小组件。

组件的定义与使用

  • 如何自定义
    依托现有模板,在source/_data/widgets.yml中定义你自己的组件。这个文件中有全面的组件配置
    另外themes/stellar/_data/widgets.yml是主题作者预设好的一些自定义组件,供参考。

    _data/widgets.yml的自定义格式
    '我的小组件1':
    layout: 小组件布局模板
    ...(其它属性)
  • 如何使用
    在以下三个位置调用自定义的/模板的组件名即可

    • 主题配置: 在_config_stellar.ymlthemes/stellar/_config.yml配置
      site_tree:
      <页面类型>:
      leftbar: welcome, recent # 左侧组件
      rightbar: # 右侧组件
    • 项目配置: 在一个wiki项目的配置文件中(e.g. source/_data/wiki/my-notes.yml)写入leftbar: ['组件1', '组件2']
    • 页面: 任意一篇文章中的front-matter中写入leftbar: ['组件1', '组件2']

    注:这三个位置的优先级是:页面 > 项目 > 主题配置

  • 显示效果
    正如你在这个页面看到的一样,页面左侧的小组件有recent(最近文章),右侧的小组件有toc(本文目录树)。

组件更灵活的应用

继承(覆盖)组件

场景:在一个文章中,需要对一个现有组件的配置作临时修改,如‘timeline中的api’。

在source/_posts/xxx.md的front-matter中或source/_data/wiki/proj1.yml中写入:
---
leftbar:
- 组件名1
- override: 组件名2
api: https://xxx
---
匿名组件:仅在使用时创建

场景:例如在某个页面的侧边栏放一个公告。

在source/_posts/xxx.md的front-matter中或source/_data/wiki/proj1.yml中写入:
---
leftbar:
- 组件名1
- layout: markdown # 这就是基于`markdown组件`的匿名组件
title: '重要通知 [NOTE.2022-09]'
content: |
notice...
---

wiki文档专题

顺利上架一个完整的wiki项目需要几步?我们先看一个项目需要的文件结构。

目录树

source/  # 
├── _data/
│ ├── wiki/
│ │ ├── `proj1-ID.yml` # step1: 该目录下,一个项目对应一个配置文件
│ │ └── proj2-ID.yml
│ ├── `wiki.yml` # step3: 陈列其中的项目ID表示上架了
│ └── other.yml
├── wiki/ # 统一存放多个wiki项目. 实际上, wiki项目可以放在任何地方
│ ├── proj1/ # step2: 写项目的文章
│ │ ├── `index.md`
│ │ ├── page1.md
│ │ └── pageN.md
│ ├── proj2/
│ └── projN/
├── assets/ # 存放项目中链接的一些资源
└── ...

step1: 构建配置文件

/_data/wiki/proj1-ID.yml的配置模板
# 该文件用于配置一个具体的wiki项目。更详细的配置属性参见`scaffolds/可供调用的完整属性列表.yml`。
# 当前的文件名,一定就是项目ID,这两者必须相同。
# 项目ID要陈列于`/_data/wiki.yml`中才能使项目出现在`/wiki/`的列表中,不陈列则隐身。
# 项目ID、下面的name、/wiki/下的项目文件夹名,这三者不必相同。

########## 必有的 ###########
name: 笔记本 # 项目页面左上角的大标题、正上方的面包屑路径
subtitle: "每天一点,进步一点 | up up up~" # 项目页面左上角的副标题
title: Ray的笔记本 # 大封面和wiki列表页的标题
tags: # tags的类别形成了/wiki/index.html中的顶端导航栏。当你只想要一个隐身的项目时,tag也就没必要写了
base_dir: /wiki/my-notes/ # 给这个配置文件指定项目文件夹

########## 封面/列表页 ###########
icon: https://images.weserv.nl/?url=assets.taddream.site/gallery/xihu_tadpole_1.jpg # 列表页图标
cover: https://images.weserv.nl/?url=assets.taddream.site/gallery/xihu_tadpole_1.jpg # 封面页大图,不能如作者所言的用true,而是具体图片,
coverpage: [cover, title, description] # bool或list。设置了才能开启封面页,且能指定组件
description: |
① 计算机技术领域各工具/语言教程的学习笔记;
② 日常的遇到的零散知识点收录,经验总结等。

########## 顶部 ###########
banner: https://images.weserv.nl/?url=assets.taddream.site/gallery/xihu_tadpole_1.jpg

########## 两侧 ###########
search: # 覆盖`_config.stellar.yml`中对应的配置
#override: search # v1.26.8后,search不再是一个可自定义的组件了
filter: /wiki/my-notes/ # 限定搜索范围
placeholder: search in my-notes ...
tree: # 承担wiki下,子页面的分组、排序任务。
# 如果没有tree,那么子页面将按照文件名的字母顺序排列。
# 注:①子页面的文件名==下面列出的题目;②子页面的front matter中的title==项目主页左侧栏中出现的子标题。
# 而①不必等于②
# 子页面的front matter中的title一定不能为空(如果又想让页面标题为空,可设置`h1: ''`),否则该页面将隐身于toc。
'': # 可以为空
- index # 必须有一个index,对应项目的index.html。
'后端开发':
- lang-python
- lang-cpp
- server-webserver-apache
'前端开发':
- html-css-js
'AI和数据科学':
-
'大数据&数据库':
-
'工具类':
- git
'网络与系统管理':
-
'其他':
-
'日常笔记':
- set-of-debug-and-pieces-of-knowledge
- download-various-network-resources
repo: JamesRay0713/fastfet # 该设置可使得ghrepo组件生效
leftbar:
- tree
- gallery
- recent
rightbar:
- ghrepo
- toc

########## 底部 ###########
share: false # bool/list, 默认不显示底部分享

comment_title: '评论区仅供交流,有问题请提 [issue](https://github.com/JamesRay/上面的repo/issues) 反馈。' # 这样写是方便把评论放在对应github项目的issue中.
comments:
service: giscus
giscus:
data-repo: JamesRay0713/blog-comments # 仓库的issue模块,映射到本项目的评论区
data-mapping: number # 也可换成title、pathname等
data-term: 1 # 一个数字映射一个评论区,不同文章下设定相同数字,则它们共享一个评论区。这种方式在一个wiki中配置特别方便。
# 如果想关闭评论区,这里写false没效果,得去具体页面的front matter写`comments: false`

step2: 写项目

注意: 一般wiki项目(e.g. /wiki/proj1/)存放于/wiki/目录下, 但也可以放在任何地方.

项目中至少有一个index.md,其他文件自行添加。
每个文件的front matter至少包含下面3个属性:

/wiki/proj1/index.md
\---
layout: wiki # 使用wiki布局模板
wiki: proj1-ID # 这是项目id,对应 /_data/wiki/proj1-ID.yml
title: 这是分页标题 # 不设置标题时,则该页面对项目不可见
\---

step3: 上架项目

/_data/wiki.yml中增加当前项目ID,如下:

- proj1-ID
- proj2-ID

这样项目即可陈列于/wiki/index.html中.
如果你想要一个隐身的wiki项目, 不要在wiki.yml中写入该项目ID即可。

专栏文章专题

一个简化版的 wiki 系统,区别是:

  • 无需「上架」动作
  • 文章创建于 blog/source/_posts 文件夹内
  • 按照时间排序,默认最新的排最上面
  • 页面布局类似于普通文章

如何创建一个专栏

若你的专栏名为topic1, 那么你需要创建一个该专栏的配置文件:

source/_data/topic/topic1.yml
name: Ray's Notes    # 在面包屑导航上会显示较短的名字
title: Notes - 我的日常学习、工作笔记 # 在列表页会显示完整的专栏标题
description: 该专栏下的文章用于随时翻阅,它汇集了我平时学习、工作中的一些知识点和经验总结等。
order_by: -date # 默认是按发布日期倒序排序

如何发布专栏文章

它本质上还是post文章,只需在front matter中指定topic即可:

source/_posts/topic1-article1.md
topic: topic1   # 这里的专栏的ID就是刚才的`.yml`文件名

进阶专题

一站多作者配置

支持多个作者在一个站点发布文章。步骤如下:

  • I. 配置作者信息:在
    source/_data/authors.yml
    # 作者 1 (默认)
    JamesRay: # 这是author ID
    name: 'Ray~' # 这是作者名
    url: https://taddream.site # 没有也可以
    avatar: https://images.weserv.nl/?url=assets.taddream.site/my-best-avatar.png
    banner: https://images.weserv.nl/?url=assets.taddream.site/build_site_images/social_page_banner.jpg
    description: know yourself...
    # 作者 2
    author2:
    name: xxx
    ...
  • II. 非默认下在文章的front matter中指定作者:
    ---
    author: JamesRay # 注意:这里是author的ID,而不是具体呈现到文章顶部的`作者名`。
    ---

第三方插件专题

「katex」插件或 mathjax插件

用于渲染LaTeX公式。
先在md文件的front matter中插入katex: truemathjax: true;
后书写latex代码,如:$$\sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6}$$,
效果为:$$\sum_{i=0}^n i^2 = \frac{(n^2+n)(2n+1)}{6}$$

友链朋友圈

  • 什么是友链朋友圈?它是你所拥有的友情网站最新发布的文章的集合,项目来自hexo-circle-of-friends
  • 如何部署:,方法比较复杂。当然还有如下的极简版的部署。
部署极简版友链朋友圈

参考

step1: fork repo

fork @Rock-Candy-Tea/hexo-circle-of-friends,该仓库核心是:给它一组友链,它会自动化爬取友链的最新文章链接。

step2: 修改配置

进入./hexo_circle_of_friends/fc_settings.yaml文件,

  • 先把你的友链页面博客主题类型放进去
    (经过对082d3cf版本代码的测试,该配置似乎对友链文章的爬取工作起不到任何作用,但原作者又执意要求对此进行配置。)
    LINK: [
    { link: "https://taddream.site/explore/friends/", theme: "stellar" },
    ]
  • 再把你要爬取的友链集合给到该仓库。方法有两种:
    • 方法1,你主动传入友链集合的json文件:
      SETTINGS_FRIENDS_LINKS: {
      enable: true,
      json_api: "https://raw.github.xaox.cc/xaoxuu/friends/output/v2/data.json", #
      }
    • 方法2,让仓库自己去你指定的repo-issue抓取友链集合:
      注意,这个指定的repo是专用于接收友链issue的()。此时假设已有不少朋友把他们的网站链接放在了这个仓库的issue中。
      GITHUB_FRIENDS_LINKS: {
      enable: true, # true 开启github issue兼容
      type: "volantis", # volantis/stellar用户请在这里填写volantis
      owner: "xaoxuu", # 填写你的github用户名。这里由于我的`友链issue`还很少,就直接借用xaoxuu的友链库了。
      repo: "friends", # 填写你的github仓库名
      state: "open", # 填写抓取的issue状态(open/closed)
      }
step3: 开启仓库的自动化爬取
  • 设置极简模式:在./.github/workflows/main.yml文件中把SIMPLE_MODE设置为true
  • 设置Action的读写权限:setting-->Actions-->General-->勾选Read and write permissions-->Save
  • 启用github action:点击Actions-->I understand my workflows, go ahead and enable them
  • 启用工作流:点击左侧栏的update-friends-posts, 点击enable workflow。.
  • 运行工作流:点击Run workflow--->Run workflow
  • 等待: 运行完毕后,仓库会生成data.json,供用户自行取用。
  • 未来:该工作流将每隔一段时间运行一次,使data.json保持最新。
step4: 在博客中展示

可以在任意位置将data.json的url置于timeline标签插件中,实现朋友圈文章的展示。
展示效果参考场景3

对主题的研究和DIY

stellar源码架构浅读

完整目录结构

stellar-v1.27.0,目录49,文件268, 详见

框架中的一些变量

详见

  • page: 针对该页面的内容以及 front-matter 中自定义的变量。
  • theme: 主题的配置对象,其包含的所有属性来自_config.stellar.yml, _config.yml, themes/stellar/_config.yml
  • proj = theme.wiki.tree[page.wiki], 是一个wiki项目的配置对象,来自source/_data/wiki/{page.wiki}.yml

一些代码的理解

你的博客网站每一个页面的生成,都是从themes/stellar/layout/layout.ejs开始的。

TODO

创建快捷按钮

快速到顶、快速到底

topic文章组更具独立性

  • 现状: stellar的作者创造了topic专栏类文章布局,功能介于postwiki之间,可以更方便地将一类文章整合到一起. 但是但它的文章和post文章是混杂在一起的,因此你网站的homepage的文章列表中同时拥有posttopic文章.
  • 缺点: topic文章组的独立性不够,

front-matter中属性的增添

header属性失而复得

  • 问题:文章的front matter中,header属性失效,导致文章的标题无法自己决定显示与否。
  • 方法: 在themes\stellar\layout\_partial\sidebar\logo.ejsfunction layoutDiv()中的起始处添加一行代码即可:
    if(page.header == false) {return ''}
  • 效果: 页面默认下会显示logo区, 仅当设置header: false时才隐藏。

增添footer_social

  • 问题: 有时候不想在页面leftbar底部显示社交分享按钮,但stellar主题没有这个开关。
  • 方法: 在themes\stellar\layout\_partial\sidebar\index_leftbar.ejsfunction layoutFooterDiv()中的起始处添加一行代码即可:
    if(page.footer_social == false) {return ''}
  • 效果: 页面默认下会显示社交分享按钮, 仅当设置footer_social: false时才隐藏。

增添show_menu

  • 问题: 想自己决定左侧栏的菜单导航是否显示.
  • 方法: 添加一个判断语句包裹住el += partial('menu', {where: 'sidebar'})即可.
    stellar\layout\_partial\sidebar\index_leftbar.ejs
    if (page.show_menu !== false) {
    el += partial('menu', {where: 'sidebar'})
    }
  • 效果: 页面默认下会显示菜单导航, 仅当设置show_menu: false时才隐藏。

非post页面也能有article-footer模块

  • 问题: 我发现article-footer模块(包含reference和share)只能出现在post文章页中, 而在’普通page文章页’、’wiki文章页’…中是没有的. 如何让该模块全域有效呢?
  • 方法: 删掉如下条件判断即可.
    themes\stellar\layout\page.ejs
    // if (layout === 'post') {
    el += partial('_partial/main/article/article_footer')
    // }
  • 效果: 此后所有页面的front-matter中都可以使用sharereference属性了。

css样式的改变

封面图变大

我想让目录页/wiki//topic/的文章列表携带的封面图变大. 修改如下:

themes\stellar\source\css\_layout\list.styl
.post-list .post-card.wiki article .preview
margin: 0.5rem 1rem // 原来是 1rem 3rem
img
width: 160px // 原来是 96px
max-height: 90px // 原来是 96px

格局的改造

想让menubar图标和文字同时显示

menubar图标加文字

themes\stellar\layout\_partial\sidebar\menu.ejs

修改前
if (item.icon?.length > 0) {
el += icon(item.icon, 'no-lazy')
} else {
el += `<span>${__(item.title)}</span>`
}
修改后
if (item.icon?.length > 0) {
el += icon(item.icon, 'no-lazy')
}
el += `<span style="color: ${theme.style.color.text}">${__(item.title)}</span>`

合并文末的license和share模块

  • 目的:简化显示效果.
  • 对比:
    stellar-v1.27.0:旧版的article-footer
    2024/03/28修改后:新版的article-footer
  • 代码变动:
    1. 增加license相关的字符串, 作为share模块的文字部分
      article-footer.ejs
       // 在 `if (theme.article.share && showSharePlugin) {`内部添加.
      license = '本文由[Raymond~](https://taddream.site/)创作, 基于[CC BY-NC-SA 4.0](https://creativecommons.org/licenses/by/4.0/)协议, 转载请注明出处. 分享文章: ';
      if (page.author && theme.authors[page.author]) {
      license = license.replace('Raymond~', `${theme.authors[page.author].name}`).replace('https://taddream.site/', `${theme.authors[page.author].url}`);
      }
    2. 重构<section id="share"> 模块: 主要是将永久链接隐藏起来.
      article-footer.ejs
      <section id="share">
      <div class="header"><span>${__('meta.share')}</span></div>
      <div class="body">
      <div class="link"><input class="copy-area" readonly="true" id="copy-link" value="${page.permalink}" /></div>
      <div class="social-wrap dis-select">${socialButtons()}</div>
      ${qrcode()}
      </div>
      </section>
      article-footer.ejs
      <section id="share">  
      ${markdown(license).replace('</p>', '')}
      <span class="link" style="display: inline;">
      <input class="copy-area" readonly="" id="copy-link" value="${page.permalink}" style="display: none;">
      </span>
      ${socialButtons()}
      ${qrcode()}
      </p>
      </section>
    3. 让图标和文字在同一行: 给每个元素添加一个style属性即可
      article-footer.ejs 删掉一行
      el += icon(`share:${item}`)
      article-footer.ejs 新增三行
      //el += icon(`share:${item}`)   ### icon函数输出的是一个<img>标签,我想为其新增自定义的style, 因此改写此行.
      el += icon(`share:${item}`).replace('>', ' ');
      el += 'style="width: 1.5em; height: 1.5em; display: inline-block; margin-right: 10px;"';
      el += '>';
  • 注意事项:此后license模块显得多余,快去_config.stellar.ymlarticle.license=false. front matter中的license属性也不再使用.

经验之谈

  • 一个页面的sidebar配置了toc,但正文部分没有任何二级及以下标题,则toc会自动替换成recent,没有办法改变。
    • 暂时解决办法:当不想出现recent,且正文部分实在没办法有标题(如加密页面)时,那就别在sidebar里添加toc组件。

Static Badge Static Badge Static Badge Static Badge
Copyright © 2023-2024 Raymond H., All Rights Reserved.