编写文章时,通常需要插入各种标签,以实现更丰富的内容展示
note 标签 写法如下;
1 2 3 {% box [title] [color:color] [child:codeblock/tabs] %} ... {% endbox %}
其中title为标签标题,color为标签颜色,child为标签内容。
这里是盒子的正文内容,可以写 Markdown 语法.比如;
插入图片 使用image插件控制图片大小和图片描述 写法如下:
1 {% image /path/photo.jpg width:400px 图片说明 %}
其中/img/bg.png为图片路径,width:500px为图片宽度,图片说明为图片描述。
fancybox插件 图片缩放功能,插件默认启用,在任意 image 标签中增加 fancybox:true 参数,即可为特定图片开启缩放功能 所有的 image 标签都开启此功能,可在主题配置文件中修改以下参数:
_config.stellar.yml 1 2 3 4 tag_plugins: image: fancybox: true
彩色可折叠代码块 备注标签可以实现更多种颜色,还可以通过设置child:codeblock来实现可折叠的代码块,示例如下;
1 2 3 {% folding child:codeblock open:true color:yellow 默认打开的代码折叠框 %} 代码块 {% endfolding %}
其中open:true为默认打开代码折叠框,color:yellow为黄色。 可以嵌套使用,当使用child:codeblock参数只需要在包含代码块的折叠框中添加,外层添加会影响会影响折叠感。
危险,请不要打开这个
通过设置颜色,以实现更醒目的作用,但不要滥用色彩哦~
警告,真的很危险
通过设置颜色,以实现更醒目的作用,但不要滥用色彩哦~
最后一次警告,千万不要打开这个
link 链接卡片 外链卡片标签的语法格式为:
1 {% link href [title] [icon:src] [desc:true /false] %}
1 2 3 4 href: 链接地址 title: 可选,手动设置标题(为空时会自动抓取页面标题) icon: 可选,手动设置图标(为空时会自动抓取页面图标) desc: 可选,是否显示摘要描述,为true 时将会显示页面描述
示例:
1 2 3 4 不带摘要的样式: {% link https://xaoxuu.com/blog/20221029/ %} 带摘要的样式: {% link https://xaoxuu.com/blog/20221029/ desc:true %}
自部署的 api 抓取网站信息
1、fork 本仓库 2、打开 vercel.com,部署该项目 3、进入 Environment Variables 页面,设置白名单 ,注意必须加上括号 [ ]
key
Value
HOSTS
[‘’, ‘localhost’, ‘yourdomain.com’]
环境变量键名
允许访问的域名列表
在给出的domain后添加/api/v1?url= url 调用,浏览器输入
1 https://yourdomain.vercel.app/api/v1?url=https://youtube.com
有返回值则api调用成功
1 2 3 4 5 6 { "title" : "YouTube" , "desc" : "Enjoy the videos and music you love, upload original content, and share it all with friends, family, and the world on YouTube." , "icon" : "https://www.youtube.com/s/desktop/ab292bc1/img/favicon_32x32.png" , "url" : "https://www.youtube.com/" }
配置到 Stellar 主题中 _config.stellar.yml 1 2 3 4 5 siteinfo: js: /js/services/siteinfo.js api: https://yourdomain.vercel.app/api/v1?url={href}
利用link做摘要卡片 设置 link 可以让整个卡片响应点击事件,实现点击跳转到对应文章/页面:
1 2 {% banner 博客进阶:自动化部署 本文讲了如何利用脚本和 GitHub Actions 简化博客搭建和部署流程,提高效率。 bg:https://res.xaox.cc/gh/cdn-x/xaoxuu@main/posts/20250706160404696.webp link:/blog/20221126/ % } {% endbanner % }
其中bg为背景图片,link为外部/内部跳转链接。
小技巧,可以通过修改banner.js文件,增加height高度,width宽度, margin对齐位置,来实现自定义banner样式。 修改源码后,升级主题会导致改动丢失,建议备份
blog\themes\stellar\scripts\tags\lib\banner.js 1 2 3 4 5 6 7 8 9 10 11 12 13 module.exports = ctx => function(args, content) { args = ctx.args.map(args , ['bg' , 'avatar' , 'link' , 'height' , 'width' , 'margin' ], ['title' , 'subtitle' ]) var el = '' var styles = [] if (args.height) styles.push(`height:$ {args.height }`) if (args.width) styles.push(`width:$ {args.width }`) if (args.margin) styles.push(`margin:$ {args.margin }`) if (styles.length > 0 ) { el += `<div class="tag-plugin banner" style="$ {styles.join(';') }">` } else { el += `<div class=" tag-plugin banner">` }
效果1 原高度
博客进阶:自动化部署
本文讲了如何利用脚本和 GitHub Actions 简化博客搭建和部署流程,提高效率。
效果2 130px高度
博客进阶:自动化部署
本文讲了如何利用脚本和 GitHub Actions 简化博客搭建和部署流程,提高效率。
也可以在不修改源代码的情况下,通过新建blog\scripts\banner.js粘贴以下内容,实现相同效果
blog\scripts\banner.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 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 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 'use strict' ; console.log('Load custom banner tag plugin...'); // Helper function to parse arguments function parseArgs(args, keys, others) { if (Array.isArray(args) == false ) { return args; } var map = {others: Array() }; args.forEach((arg , i) => { let kv = arg.trim(); if (kv.includes('://') && kv.split(':').length == 2 ) { // Pure URL map.others.push(kv); } else { kv = kv.split(':'); if (kv.length > 1 ) { if (keys.includes(kv [0 ]) == true ) { map [kv.shift() ] = kv.join(':'); } else { map.others.push(kv.join(':')); } } else if (kv.length == 1 ) { map.others.push(kv [0 ]); } } }); // Parse unnamed arguments if (others && others.length > 0 && map.others.length > 0 ) { if (Array.isArray(others) == false ) { others = [others ]; } others.forEach((arg , i) => { map [arg ] = map.others.shift(); }); // Merge the last part into the last argument if (map.others.length > 0 ) { map [others [others.length-1 ]] += ' ' + map.others.join(' '); map.others = []; } } return map; } // Custom banner implementation const customBanner = function(args, content) { const ctx = hexo; // Use local parseArgs args = parseArgs(args, [' bg' , 'avatar' , 'link' , 'height' , 'width' , 'margin' ], ['title' , 'subtitle' ]) var el = '' var styles = [] if (args.height) styles.push(`height:$ {args.height }`) if (args.width) styles.push(`width:$ {args.width }`) if (args.margin) styles.push(`margin:$ {args.margin }`) if (styles.length > 0 ) { el += `<div class="tag-plugin banner" style="$ {styles.join(';') }">` } else { el += `<div class=" tag-plugin banner">` } // bg const defaultBanner = ctx.theme.config.default && ctx.theme.config.default.banner ? ctx.theme.config.default.banner : '' ; el += `<img class="lazy bg" data-src="$ {args.bg ? args.bg : defaultBanner }">` // content el += `<div class=" content">` // content.top el += `<div class="top">` // content.top.back if (args.link?.length > 0 ) { el += `<div></div>` } else { el += ` <button class="back cap" onclick="window.history.back()"> <svg aria-hidden="true" viewBox="0 0 16 16 " fill=" currentColor"><path fill-rule="evenodd" d="M7.78 12. 53a.75.75 0 01 -1.06 0L2.47 8. 28a.75.75 0 010 -1. 06l4.25-4.25a.75.75 0 011.06 1. 06L4.81 7h7.44a.75.75 0 010 1. 5H4.81l2.97 2. 97a.75.75 0 010 1. 06z"></path></svg> </button> ` } // content.top.menus if (content) { const rows = content.split('\n').filter(item => item.trim().length > 0 ) for (let row of rows) { if (row.includes('tag-plugin navbar')) { el += row break } } } el += `</div>` // content.bottom el += `<div class="bottom">` // content.bottom.avatar if (args.avatar?.length > 0 ) { el += `<img class="avatar" src="$ {args.avatar }">` } // content.bottom.text-area if (args.title?.length > 0 || args.subtitle?.length > 0) { el += `<div class=" text-area">` if (args.title?.length > 0 ) { el += `<div class="text title">$ {args.title }</div>` } if (args.subtitle?.length > 0 ) { el += `<div class="text subtitle">$ {args.subtitle }</div>` } el += `</div>` } el += `</div>` el += `</div>` // link if (args.link?.length > 0 ) { el += `<a class="banner-link" href="$ {args.link }"></a>` } el += `</div>` return el }; // 1. Register custom banner immediately // Note: We use the original register method if possible, but hexo.extend.tag.register is bound to hexo.extend.tag hexo.extend.tag.register('banner', customBanner, true); // 2. Intercept future registrations to prevent overwrite by theme const originalRegister = hexo.extend.tag.register; // We need to bind the new function to hexo.extend.tag context or ensure 'this' is correct hexo.extend.tag.register = function(name, fn, options) { if (name === 'banner') { // Check if the function being registered is our custom one (by comparing reference or just assuming) // Since we already registered ours, any subsequent registration for 'banner' is likely from the theme if (fn !== customBanner) { return; // Block the theme's registration } } return originalRegister.apply(this, arguments); };
quot 强调引用 适合居中且醒目的引用 1 {% quot 特别引用 icon:default % }
支持自定义引号 1 {% quot 热门话题 icon:hashtag % }