footer跳动的心

效果预览

image-20220713161434326

查看步骤

编辑[blogroot]/themes/butterfly/layout/includes/footer.pug文件

将以下内容

1
©${theme.footer.owner.since} - ${nowYear} By ${config.author}

改为

1
&copy;${theme.footer.owner.since} - ${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author}

将以下内容

1
&copy;${nowYear} By ${config.author}

改为

1
&copy;${nowYear + ' '} <i id="heartbeat" class="fa fas fa-heartbeat"></i> ${config.author}

添加以下内容

1
<link rel="stylesheet" href="https://fastly.jsdelivr.net/gh/HCLonely/images@master/others/heartbeat.min.css">

参考下图

image-20220713162336871

鼠标样式

查看步骤

/themes/butterfly/source/css路径下创建一个mouse.css文件,在文件中添加如下代码:

1
2
3
4
5
6
7
8
9
body {
cursor:url(https://cdn.jsdelivr.net/gh/sviptzk/HexoStaticFile@latest/Hexo/img/default.cur),
default;
}
a,
img {
cursor:url(https://cdn.jsdelivr.net/gh/sviptzk/HexoStaticFile@latest/Hexo/img/pointer.cur),
default;
}

打开主题配置文件_config.yml,找到inject,在head处直接引入该文件:

1
2
3
inject:
head:
- <link rel="stylesheet" href="/css/mouse.css">

昼夜切换动画

效果预览

image-20220714202052344

查看步骤
  1. 新建[Blogroot]\themes\butterfly\layout\includes\custom\sun_moon.pug,这部分其实实质上就是一个svg文件,通过js操作它的旋转显隐,淡入淡出实现动画效果。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    svg(aria-hidden='true', style='position:absolute; overflow:hidden; width:0; height:0')
    symbol#icon-sun(viewBox='0 0 1024 1024')
    path(d='M960 512l-128 128v192h-192l-128 128-128-128H192v-192l-128-128 128-128V192h192l128-128 128 128h192v192z', fill='#FFD878', p-id='8420')
    path(d='M736 512a224 224 0 1 0-448 0 224 224 0 1 0 448 0z', fill='#FFE4A9', p-id='8421')
    path(d='M512 109.248L626.752 224H800v173.248L914.752 512 800 626.752V800h-173.248L512 914.752 397.248 800H224v-173.248L109.248 512 224 397.248V224h173.248L512 109.248M512 64l-128 128H192v192l-128 128 128 128v192h192l128 128 128-128h192v-192l128-128-128-128V192h-192l-128-128z', fill='#4D5152', p-id='8422')
    path(d='M512 320c105.888 0 192 86.112 192 192s-86.112 192-192 192-192-86.112-192-192 86.112-192 192-192m0-32a224 224 0 1 0 0 448 224 224 0 0 0 0-448z', fill='#4D5152', p-id='8423')
    symbol#icon-moon(viewBox='0 0 1024 1024')
    path(d='M611.370667 167.082667a445.013333 445.013333 0 0 1-38.4 161.834666 477.824 477.824 0 0 1-244.736 244.394667 445.141333 445.141333 0 0 1-161.109334 38.058667 85.077333 85.077333 0 0 0-65.066666 135.722666A462.08 462.08 0 1 0 747.093333 102.058667a85.077333 85.077333 0 0 0-135.722666 65.024z', fill='#FFB531', p-id='11345')
    path(d='M329.728 274.133333l35.157333-35.157333a21.333333 21.333333 0 1 0-30.165333-30.165333l-35.157333 35.157333-35.114667-35.157333a21.333333 21.333333 0 0 0-30.165333 30.165333l35.114666 35.157333-35.114666 35.157334a21.333333 21.333333 0 1 0 30.165333 30.165333l35.114667-35.157333 35.157333 35.157333a21.333333 21.333333 0 1 0 30.165333-30.165333z', fill='#030835', p-id='11346')
  2. 新建[Blogroot]\themes\butterfly\source\css\_layout\sun_moon.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
    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
    .Cuteen_DarkSky,
    .Cuteen_DarkSky:before
    content ''
    position fixed
    left 0
    right 0
    top 0
    bottom 0
    z-index 88888888

    .Cuteen_DarkSky
    background linear-gradient(#feb8b0, #fef9db)
    &:before
    transition 2s ease all
    opacity 0
    background linear-gradient(#4c3f6d, #6c62bb, #93b1ed)

    .DarkMode
    .Cuteen_DarkSky
    &:before
    opacity 1

    .Cuteen_DarkPlanet
    z-index 99999999
    position fixed
    left -50%
    top -50%
    width 200%
    height 200%
    -webkit-animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    animation CuteenPlanetMove 2s cubic-bezier(0.7, 0, 0, 1)
    transform-origin center bottom


    @-webkit-keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    @keyframes CuteenPlanetMove {
    0% {
    transform: rotate(0);
    }
    to {
    transform: rotate(360deg);
    }
    }
    .Cuteen_DarkPlanet
    &:after
    position absolute
    left 35%
    top 40%
    width 9.375rem
    height 9.375rem
    border-radius 50%
    content ''
    background linear-gradient(#fefefe, #fffbe8)

    .search
    span
    display none

    .menus_item
    a
    text-decoration none!important
    //按钮相关,对侧栏按钮做过魔改的可以调整这里的数值
    .icon-V
    padding 5px
  3. 新建[Blogroot]\themes\butterfly\source\js\sun_moon.js,去除了冗余代码,去jquery

    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
    function switchNightMode() {
    document.querySelector('body').insertAdjacentHTML('beforeend', '<div class="Cuteen_DarkSky"><div class="Cuteen_DarkPlanet"></div></div>'),
    setTimeout(function() {
    document.querySelector('body').classList.contains('DarkMode') ? (document.querySelector('body').classList.remove('DarkMode'), localStorage.setItem('isDark', '0'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')) : (document.querySelector('body').classList.add('DarkMode'), localStorage.setItem('isDark', '1'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')),
    setTimeout(function() {
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.transition = 'opacity 3s';
    document.getElementsByClassName('Cuteen_DarkSky')[0].style.opacity = '0';
    setTimeout(function() {
    document.getElementsByClassName('Cuteen_DarkSky')[0].remove();
    }, 1e3);
    }, 2e3)
    })
    const nowMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    if (nowMode === 'light') {
    activateDarkMode()
    saveToLocal.set('theme', 'dark', 2)
    GLOBAL_CONFIG.Snackbar !== undefined && btf.snackbarShow(GLOBAL_CONFIG.Snackbar.day_to_night)
    document.getElementById('modeicon').setAttribute('xlink:href', '#icon-sun')
    } else {
    activateLightMode()
    saveToLocal.set('theme', 'light', 2)
    document.querySelector('body').classList.add('DarkMode'), document.getElementById('modeicon').setAttribute('xlink:href', '#icon-moon')
    }
    // handle some cases
    typeof utterancesTheme === 'function' && utterancesTheme()
    typeof FB === 'object' && window.loadFBComment()
    window.DISQUS && document.getElementById('disqus_thread').children.length && setTimeout(() => window.disqusReset(), 200)
    }
  4. 修改[Blogroot]\themes\butterfly\layout\includes\head.pug,在文件末位加上一行:

    1
    +	include ./custom/sun_moon.pug
  5. 修改[Blogroot]\themes\butterfly\layout\includes\rightside.pug,把原本的昼夜切换按钮替换掉

    1
    2
    3
    4
    5
    6
    7
    when 'darkmode'
    if darkmode.enable && darkmode.button
    - button#darkmode(type="button" title=_p('rightside.night_mode_title'))
    - i.fas.fa-adjust
    + a.icon-V.hidden(onclick='switchNightMode()', title=_p('rightside.night_mode_title'))
    + svg(width='25', height='25', viewBox='0 0 1024 1024')
    + use#modeicon(xlink:href='#icon-moon')
  6. 修改[Blogroot]\themes\butterfly\_config.yml,引入js

    1
    2
    3
    4
    inject:
    head:
    bottom:
    - <script src="/js/sun_moon.js" async></script>

时间轴添加生肖

效果预览

image-20220714200028443

查看步骤
  1. [Blogroot]\themes\butterfly\scripts\目录下新建year.js

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    hexo.extend.helper.register('getAnimalIcon', function (year) {
    var index = parseInt(year) % 12;
    var icon = {
    0: 'icon-monkey',
    1: 'icon-rooster',
    2: 'icon-dog',
    3: 'icon-boar',
    4: 'icon-rat',
    5: 'icon-ox',
    6: 'icon-tiger',
    7: 'icon-rabbit',
    8: 'icon-dragon',
    9: 'icon-snake',
    10: 'icon-horse',
    11: 'icon-goat',
    }
    return icon[index]
    });
  2. 引入阿里矢量图标库图标,在[Blogroot]\themes\butterfly\source\css\目录下新建year.css

    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
    @import url("//at.alicdn.com/t/font_2264842_3izu8i5eoc2.css");
    /* 用的是别人的项目 */
    .iconfont {
    font-family: "iconfont" !important;
    font-size: 1.85em;
    /* 可以定义图标大小 */
    font-style: normal;
    -webkit-font-smoothing: antialiased;
    -moz-osx-font-smoothing: grayscale;
    }
    /* 生肖鼠 */
    .icon-rat:before {
    color: #85c3de;
    /* 可以自定义图标颜色 */
    }
    /* 生肖牛 */
    .icon-ox:before {
    color: #ffaf6e;
    }
    /* 生肖虎 */
    .icon-tiger:before {
    color: #f7c768;
    }
    /* 生肖兔 */
    .icon-rabbit:before {
    color: #ffbdd8;
    }
    /* 生肖龙 */
    .icon-dragon:before {
    color: #ff8787;
    }
    /* 生肖蛇 */
    .icon-snake:before {
    color: #c3d686;
    }
    /* 生肖马 */
    .icon-horse:before {
    color: #ffaf6e;
    }
    /* 生肖羊 */
    .icon-goat:before {
    color: #f7c768;
    }
    /* 生肖猴 */
    .icon-monkey:before {
    color: #c3d686;
    }
    /* 生肖鸡 */
    .icon-rooster:before {
    color: #ff8787;
    }
    /* 生肖狗 */
    .icon-dog:before {
    color: #85c3de;
    }
    /* 生肖猪 */
    .icon-boar:before {
    color: #ffbdd8;
    }
  3. 修改[Blogroot]\themes\butterfly\layout\includes\mixins\article-sort.pug,第7行开始,注意缩进。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
        - let title = article.title || _p('no_title')
    + - let animalIcon = getAnimalIcon(tempYear)
    if tempYear !== year
    - year = tempYear
    - .article-sort-item.year= year
    + .article-sort-item.year
    + span= year
    + i.iconfont(class=animalIcon)
    .article-sort-item(class=no_cover)
    if article.cover && theme.cover.archives_enable
  4. 修改主题配置文件_config.ymlinject配置项,引入year.css

    1
    2
    3
    4
    inject:
    head:
    - <link rel="stylesheet" href="/css/year.css" media="defer" onload="this.media='all'">
    bottom:

自定义字体

效果预览

image-20220714034903087

查看步骤
  1. 首先需要下载心仪的字体。推荐一个免费的字体库网站,支持在线转换预览和免费字体包下载。这里选择甜甜圈海报字体。根据页面按钮找到字体下载。得到相应的字体文件。为了方便起见,将其重命名为Candy.ttf

    不一定是ttf后缀,其他后缀也是完全正常的,例如eot、otf、fon、font、ttc、woff、woff2等。

  2. 将下载好的字体包放到本地文件夹下,这里推荐新建一个fonts文件夹。例如我是放在[Blogroot]\themes\butterfly\source\fonts\目录下

  3. 在自定义样式\themes\butterfly\source\css\custom.css中引入字体包:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    @font-face{
    font-family:'Candyhome' ; /* 字体名自定义即可 */
    src:url('/fonts/Candy.ttf'); /* 字体文件路径 */
    font-display : swap;
    }

    body {
    font-family: 'Candyhome', sans-serif;
    }

    关于font-family的写法,此处表示主字体用'Candyhome',若字体包内没有相应字体,则使用备用字体sans-serif,备用字体可以写多个。形如:

    1
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif
  4. 主题配置文件配置(照着配置就行,后面引入其它字体都不用改了好像):

    1
    2
    3
    4
    5
    6
    7
    # Global font settings
    # Don't modify the following settings unless you know how they work (非必要不要修改)
    font:
    global-font-size: "15px"
    code-font-size: "15px"
    font-family: ZhuZiAYuanJWD, -apple-system, BlinkMacSystemFont, "Segoe UI", "Helvetica Neue", Lato, Roboto, "PingFang SC", "STZhongsong", "Lantinghei SC", sans-serif
    code-font-family: consolas, Menlo, "PingFang SC", "Microsoft JhengHei", "Microsoft YaHei", sans-serif

公祭日自动变灰

效果预览

image-20220714210846891

查看步骤

站点公祭日自动变灰判定是通过js监测当前日期是否为公祭日,从而调整html的filter属性使站点变灰。

  1. [Blogroot]\themes\butterfly\source\js\目录下新建grayscale.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
    if(PublicSacrificeDay()){
    document.getElementsByTagName("html")[0].setAttribute("style","filter:gray !important;filter:grayscale(100%);-webkit-filter:grayscale(100%);-moz-filter:grayscale(100%);-ms-filter:grayscale(100%);-o-filter:grayscale(100%);");
    }

    function PublicSacrificeDay(){
    var PSFarr=new Array("0403","0404","0405","0406","0414","0512","0707","0807","0814","0909","0918","0930","1025","1213");
    //2020年4月4日 新冠肺炎哀悼日,清明节
    //2010年4月14日,青海玉树地震
    //2008年5月12日,四川汶川地震
    //1937年7月7日,七七事变 又称卢沟桥事变
    //2010年8月7日,甘肃舟曲特大泥石流
    //8月14日,世界慰安妇纪念日
    //1976年9月9日,毛主席逝世
    //1931年9月18日,九一八事变
    //烈士纪念日为每年9月30日
    //1950年10月25日,抗美援朝纪念日
    //1937年12月13日,南京大屠杀
    var currentdate = new Date();
    var str = "";
    var mm = currentdate.getMonth()+1;
    if(currentdate.getMonth()>9){
    str += mm;
    }else{
    str += "0" + mm;
    }
    if(currentdate.getDate()>9){
    str += currentdate.getDate();
    }else{
    str += "0" + currentdate.getDate();
    }
    if(PSFarr.indexOf(str)>-1){
    return 1;
    }else{
    return 0;
    }
    }
  2. 在主题配置文件_config.ymlinject配置项添加引入,此处因为这是个独立的js,而且体量极小,所以可以添加async异步加载标签

    1
    2
    3
    4
    inject:
    head:
    bottom:
    - <script async src="/js/grayscale.js"></script>

页脚计时器

效果预览

image-20220801092050368

查看步骤
  1. 安装插件

    1
    npm install hexo-butterfly-footer-beautify --save
  2. 添加 js

    butterfly\source\js 目录下添加 runtime.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
    setInterval(() => {
    let create_time = Math.round(
    new Date("2022-07-01 00:00:00").getTime() / 1000
    ); //在此行修改建站时间
    let timestamp = Math.round(new Date().getTime() / 1000);
    let second = timestamp - create_time;
    let time = new Array(0, 0, 0, 0, 0);

    var nol = function (h) {
    return h > 9 ? h : "0" + h;
    };
    if (second >= 365 * 24 * 3600) {
    time[0] = parseInt(second / (365 * 24 * 3600));
    second %= 365 * 24 * 3600;
    }
    if (second >= 24 * 3600) {
    time[1] = parseInt(second / (24 * 3600));
    second %= 24 * 3600;
    }
    if (second >= 3600) {
    time[2] = nol(parseInt(second / 3600));
    second %= 3600;
    }
    if (second >= 60) {
    time[3] = nol(parseInt(second / 60));
    second %= 60;
    }
    if (second > 0) {
    time[4] = nol(second);
    }
    if (Number(time[2]) < 22 && Number(time[2]) > 7) {
    currentTimeHtml =
    "<div id='runtime'>" +
    time[0] +
    " YEAR " +
    time[1] +
    " DAYS " +
    time[2] +
    " : " +
    time[3] +
    " : " +
    time[4] +
    "</div>";
    } else {
    currentTimeHtml =
    "<div id='runtime'>" +
    time[0] +
    " YEAR " +
    time[1] +
    " DAYS " +
    time[2] +
    " : " +
    time[3] +
    " : " +
    time[4] +
    "</div>";
    }
    document.getElementById("workboard").innerHTML = currentTimeHtml;
    }, 1000);
  3. 添加 css

    butterfly\source\css 目录下添加 runtime.css

    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
    /*电子钟字体*/
    @font-face {
    font-family: 'UnidreamLED';
    src: url("https://cdn.jsdelivr.net/npm/akilar-candyassets/fonts/UnidreamLED.ttf");
    font-display: swap;
    }
    div#runtime {
    width: 250px;
    margin: auto;
    color: #fff;
    padding-inline: 5px;
    border-radius: 10px;
    background-color: rgba(0,0,0,0.7);
    font-family: 'UnidreamLED';
    }
    [data-theme="dark"] div#runtime {
    color: #28b4c8;
    box-shadow: 0 0 5px rgba(28,69,218,0.71);
    animation: flashlight 1s linear infinite alternate;
    }
    /*悬停显示徽标提示语*/
    a.github-badge:hover:before {
    position: fixed;
    width: fit-content;
    margin: auto;
    left: 0;
    right: 0;
    top: 10%;
    border-radius: 10px;
    text-align: center;
    z-index: 100;
    content: attr(data-title);
    font-size: 20px;
    color: #fff;
    padding: 10px;
    background-color: var(--text-bg-hover);
    }
    [data-theme=dark] a.github-badge:hover:before {
    background-color: rgba(18,18,18,0.8);
    }
    @-moz-keyframes flashlight {
    from {
    box-shadow: 0 0 5px #1478d2;
    }
    to {
    box-shadow: 0 0 2px #1478d2;
    }
    }
    @-webkit-keyframes flashlight {
    from {
    box-shadow: 0 0 5px #1478d2;
    }
    to {
    box-shadow: 0 0 2px #1478d2;
    }
    }
    @-o-keyframes flashlight {
    from {
    box-shadow: 0 0 5px #1478d2;
    }
    to {
    box-shadow: 0 0 2px #1478d2;
    }
    }
    @keyframes flashlight {
    from {
    box-shadow: 0 0 5px #1478d2;
    }
    to {
    box-shadow: 0 0 2px #1478d2;
    }
    }
  4. 添加配置信息

    主题配置文件中添加

    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
    # footer_beautify
    footer_beautify:
    enable:
    timer: true # 计时器开关
    bdage: false # 徽标开关
    priority: 5 #过滤器优先权
    enable_page: all # 应用页面
    exclude: #屏蔽页面
    # - /posts/
    # - /about/
    layout: # 挂载容器类型
    type: id
    name: footer-wrap
    index: 0
    # 计时器部分配置项
    runtime_js: /js/runtime.js
    runtime_css: /css/runtime.css
    # 徽标部分配置项
    swiperpara: 3 #若非0,则开启轮播功能,每行徽标个数
    bdageitem:
    - link: https://hexo.io/ #徽标指向网站链接
    shields: https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo #徽标API
    message: 博客框架为Hexo_v5.4.0 #徽标提示语
    - link: https://butterfly.js.org/
    shields: https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender
    message: 主题版本Butterfly_v3.8.2
    - link: https://www.jsdelivr.com/
    shields: https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr
    message: 本站使用JsDelivr为静态资源提供CDN加速
    - link: https://vercel.com/
    shields: https://img.shields.io/badge/Hosted-Vercel-brightgreen?style=flat&logo=Vercel
    message: 本站采用双线部署,默认线路托管于Vercel
    - link: https://vercel.com/
    shields: https://img.shields.io/badge/Hosted-Coding-0cedbe?style=flat&logo=Codio
    message: 本站采用双线部署,联通线路托管于Coding
    - link: https://github.com/
    shields: https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub
    message: 本站项目由Github托管
    - link: http://creativecommons.org/licenses/by-nc-sa/4.0/
    shields: https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris
    message: 本站采用知识共享署名-非商业性使用-相同方式共享4.0国际许可协议进行许可
    swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css
    swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js
    swiperbdage_init_js: https://npm.elemecdn.com/hexo-butterfly-footer-beautify/lib/swiperbdage_init.min.js
  5. 参数释义

参数备选值/类型释义
prioritynumber【可选】过滤器优先级,数值越小,执行越早,默认为10,选填
enable.timertrue/false【必选】计时器控制开关
enable.bdagetrue/false【必选】徽标控制开关
enable_pagepath【可选】填写想要应用的页面,如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填all,默认为all
excludepath【可选】填写想要屏蔽的页面,可以多个。仅当enable_page为’all’时生效。写法见示例。原理是将屏蔽项的内容逐个放到当前路径去匹配,若当前路径包含任一屏蔽项,则不会挂载。
layout.typeid/class【可选】挂载容器类型,填写id或class,不填则默认为id
layout.nametext【必选】挂载容器名称
layout.index0和正整数【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位
runtime_jsurl【必选】页脚计时器脚本,可自行修改。
runtime_cssurl【可选】自定义样式,可自行修改。
swiperparanumber【可选】若非零,则开启轮播功能,此项表示每行最多容纳徽标个数,用来应对徽标过多显得页脚拥挤的问题
bdageitem.linkurl【可选】页脚徽标指向的网站链接
bdageitem.shieldsurl【必选】页脚徽标对应的API
bdageitem.messagetext【可选】页脚徽标悬停时显示的信息
swiper_cssurl【可选】swiper的依赖
swiper_jsurl【可选】swiper的依赖
swiperbdage_init_jsurl【可选】swiper初始化方法

首页文章轮播

效果预览

image-20221027090400668

查看步骤

1)安装插件,在博客根目录[Blogroot]下打开终端,运行以下指令:

1
npm install hexo-butterfly-swiper --save

2)在站点配置文件或者主题配置文件中添加

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# hexo-butterfly-swiper
# see https://akilar.top/posts/8e1264d1/
swiper:
enable: true # 开关
priority: 5 #过滤器优先权
enable_page: all # 应用页面
timemode: date #date/updated
layout: # 挂载容器类型
type: id
name: recent-posts
index: 0
default_descr: 再怎么看我也不知道怎么描述它的啦!
swiper_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.css #swiper css依赖
swiper_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper.min.js #swiper js依赖
custom_css: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiperstyle.css # 适配主题样式补丁
custom_js: https://npm.elemecdn.com/hexo-butterfly-swiper/lib/swiper_init.js # swiper初始化方法

3)参数释义

参数备选值/类型释义
prioritynumber【可选】过滤器优先级,数值越小,执行越早,默认为10,选填
enabletrue/false【必选】控制开关
enable_pagepath/all【可选】填写想要应用的页面的相对路径(即路由地址),如根目录就填’/‘,分类页面就填’/categories/‘。若要应用于所有页面,就填’all’,默认为all
timemodedate/updated【可选】时间显示,date为显示创建日期,updated为显示更新日期,默认为date
layout.typeid/class【可选】挂载容器类型,填写id或class,不填则默认为id
layout.nametext【必选】挂载容器名称
layout.index0和正整数【可选】前提是layout.type为class,因为同一页面可能有多个class,此项用来确认究竟排在第几个顺位
default_descrtext默认文章描述
swiper_cssurl【可选】自定义的swiper依赖项css链接
swiper_jsurl【可选】自定义的swiper依赖项加js链接
custom_cssurl【可选】适配主题样式补丁
custom_jsurl【可选】swiper初始化方法

4)在文章的front_matter中添加swiper_index配置项即可:

1
swiper_index: 1 # 置顶轮播图顺序,非负整数,数字越大越靠前

首页分类磁贴

效果预览

image-20221027103330509

查看步骤
  1. 修改 \themes\butterfly\layout\index.pug

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
      extends includes/layout.pug

    block content
    include ./includes/mixins/post-ui.pug
    #recent-posts.recent-posts
    + if theme.categoryBar.enable
    + .recent-post-item(style='height:auto;width:100%;padding:0px;')
    + #categoryBar!= list_categories(site.categories,{class: 'categoryBar',depth: 1})
    +postUI
    include includes/pagination.pug
  2. 新建 \themes\butterfly\source\css\_layout\categoryBar.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
    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
    if hexo-config('categoryBar.enable')
    #categoryBar
    width 100%!important
    ul
    &.categoryBar-list
    margin 5px 5px 0 5px!important
    padding 0!important

    li
    &.categoryBar-list-item
    font-weight bold
    display inline-block
    height 180px!important
    margin 5px .5% 0 .5%!important
    background-image linear-gradient(rgba(0, 0, 0, 0.4) 25%, rgba(16, 16, 16, 0) 100%)
    border-radius 10px
    padding 25px 0 25px 25px!important
    box-shadow rgba(50, 50, 50, 0.3) 50px 50px 50px 50px inset
    overflow hidden
    background-size 100%!important
    background-position center!important
    &:hover
    background-size 110%!important
    box-shadow inset 500px 50px 50px 50px rgba(50,50,50, 0.6)
    span
    &.categoryBar-list-count
    &::after
    transition all .5s
    transform translate(-100%, 0)
    a
    &.categoryBar-list-link
    color white!important
    font-size 20px!important
    &::before
    content '|'!important
    color white!important
    font-size 20px!important
    &:after
    content ''
    position relative
    width 0
    bottom 0
    display block
    height 3px
    border-radius 3px
    background-color white
    &:hover
    &:after
    width 90%
    left 1%
    transition all 0.5s

    span
    &.categoryBar-list-count
    display block!important
    color white!important
    font-size 20px!important
    &::before
    content '\f02d'!important
    padding-right 15px!important
    @extend .fontawesomeIcon
    &::after
    padding 5px
    display block!important
    color white!important
    font-size 20px!important
    position relative
    right -100%
    covers = hexo-config('categoryBar.cover')
    for cover,i in covers
    li.categoryBar-list-item:nth-child({i+1})
    background unquote(cover)
    descrs = hexo-config('categoryBar.descr')
    for descr,i in descrs
    li.categoryBar-list-item:nth-child({i+1})>span::after
    content descr!important
    if hexo-config('categoryBar.column') == 'odd'
    li
    &.categoryBar-list-item
    width 32.3%!important
    else if hexo-config('categoryBar.column') == 'even'
    li
    &.categoryBar-list-item
    width 24%!important
    @media screen and (max-width: 650px)
    li
    &.categoryBar-list-item
    width 48%!important
    height 150px!important
    margin 5px 1% 0 1%!important

    $caterow = hexo-config('categoryBar.row')?hexo-config('categoryBar.row'):2
    .categoryBar-list
    max-height 190px * $caterow
    overflow auto
    &::-webkit-scrollbar
    width 0!important
    @media screen and (max-width: 650px)
    .categoryBar-list
    max-height 160px * $caterow
  3. _config.butterfly.yml 添加配置项

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    categoryBar:
    enable: true
    column: odd # 显示列数,odd:3列 | even:4列
    row: 1 #显示行数,默认两行,超过行数切换为滚动显示
    descr:
    - 长篇小说连载
    - 杂谈教程
    - 玩转Win10
    - Ubuntu指南
    - 个人日记
    - 诗词歌赋
    cover:
    - url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover1.webp')
    - '#abcdef' # HEX格式色值需要用''包裹,不然会被识别成注释
    - rgba(45,67,89,0.7)
    - linear-gradient(rgba(0, 0, 0, 0.4) 25%, rgba(200,16 , 16, 0) 100%)
    - url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover5.webp')
    - url('https://cdn.jsdelivr.net/npm/akilar-candyassets/image/cover6.webp')

天气时钟

效果预览

image-20221027124411582

查看步骤
  1. 安装插件

    1
    npm install hexo-butterfly-clock --save
  2. 配置插件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    # electric_clock
    # see https://akilar.top/posts/4e39cf4a/
    electric_clock:
    enable: true # 开关
    priority: 5 #过滤器优先权
    enable_page: all # 应用页面
    exclude:
    # - /posts/
    # - /about/
    layout: # 挂载容器类型
    type: class
    name: sticky_layout
    index: 0
    loading: /img/loading.gif #加载动画自定义

Echarts 统计图表

由于得关闭 pjax 才能显示(暂不清楚原因),就不放了。还是舍不得关掉 pjax。

效果预览

image-20221028183939085

image-20221028183949085

查看步骤

1)在主题配置文件引进 Echarts

js下载地址

1
2
3
inject:
head:
- <script data-pjax src="/js/echarts.min.js"></script>
  1. 新建 [Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js(文件名称可以自定义), 添加 tag_ranking_bar 函数:

    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
    // 标签统计柱状图
    hexo.extend.helper.register('tag_ranking_bar', function (options) {
    const { type, id, topNum, title, color, yAxisName, seriesName } = options
    // id 和 type 必须指定
    if (!id || !type) return
    // 获取 tags 标签页信息
    const tagArr = []
    hexo.locals.get('tags').map(function (tag) {
    tagArr.push([tag.name, tag.length])
    })
    // 对数组进行排序,然后取 top 10
    tagArr.sort((x, y) => { return y[0] - x[0] })
    const echarts_obj = {
    tag: tagArr.slice(0, topNum)
    }
    return `
    <script type="text/javascript" id="${id}">
    var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    var tagsChart = echarts.init(document.getElementById("${id}"),themeMode);

    // 指定图表的配置项和数据
    var tagsOption = {
    color: "${color}",
    backgroundColor: '',
    title: {
    text: "${title}",
    x: 'center'
    },
    dataset: [
    {
    dimensions: ['name', 'count'],
    source: ${JSON.stringify(echarts_obj[type])}
    },
    {
    transform: {
    type: 'sort',
    config: { dimension: 'count', order: 'desc' }
    }
    }
    ],
    tooltip: {},
    xAxis: {
    type: 'category'
    },
    yAxis: {
    name: "${yAxisName}",
    type: 'value',
    splitLine: {
    show: false
    },
    axisTick: {
    show: false
    },
    axisLine: {
    show: true
    }
    },
    series: {
    name: "${seriesName}",
    type: 'bar',
    encode: { x: 'name', y: 'count' },
    datasetIndex: 1,
    itemStyle: {
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color: '#83bff6' },
    { offset: 0.5, color: '#188df0' },
    { offset: 1, color: '#188df0' }
    ])
    },
    emphasis: {
    itemStyle: {
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
    { offset: 0, color: '#2378f7' },
    { offset: 0.7, color: '#2378f7' },
    { offset: 1, color: '#83bff6' }
    ])
    }
    },
    markPoint: {
    symbolSize: 45,
    data: [
    {
    type: 'max',
    itemStyle: { color: '#425aef' },
    name: '最大值'
    },
    {
    type: 'min',
    itemStyle: { color: '#425aef' },
    name: '最小值'
    }
    ]
    },
    markLine: {
    itemStyle: { color: '#425aef' },
    data: [{ type: 'average', name: '平均值' }]
    }
    }
    };
    // 使用刚指定的配置项和数据显示图表。
    tagsChart.setOption(tagsOption);
    window.addEventListener("resize", () => {
    tagsChart.resize();
    });
    </script>`
    })
  2. [Blogroot]\themes\butterfly\layout\includes\page\tags.pug中添加 :

    1
    2
    #tag-echarts(style="height:320px")
    !=tag_ranking_bar({type:'tag',id:'tag-echarts',topNum:10,title:'Top 10 标签统计图',color:theme.theme_color,yAxisName:'文章篇数',seriesName:'标签统计'})
  1. [Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js 添加 categories_pic函数:

    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
    hexo.extend.helper.register('categories_pic', function (options) {
    const { id, title, seriesName } = options
    // id 必须指定
    if (!id) return
    const categoryArr = []
    hexo.locals.get('categories').map(function (category) {
    categoryArr.push({ name: category.name, value: category.length })
    })
    return `
    <script type="text/javascript" id="${id}">
    var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    var categoriesChart = echarts.init(document.getElementById("${id}"),themeMode);
    // 指定图表的配置项和数据
    var categoriesOption = {
    backgroundColor:'',
    title:{
    text:'${title}',
    x:'center'
    },
    tooltip:{
    formatter: "{a} <br/>{b} : {c} ({d}%)"
    },
    legend: {
    icon: "circle",
    top: 'bottom'
    },
    series: [
    {
    name: '${seriesName}',
    type: 'pie',
    radius: [40, 150],
    center: ['50%', '48%'],
    roseType: 'area',
    itemStyle: {
    borderRadius: 8
    },
    label: {
    formatter: "{b} : {c} ({d}%)"
    },
    data: ${JSON.stringify(categoryArr)}
    }
    ]
    };
    // 使用刚指定的配置项和数据显示图表。
    categoriesChart.setOption(categoriesOption);
    window.addEventListener("resize", () => {
    categoriesChart.resize();
    });
    </script>`
    })
  2. [Blogroot]\themes\butterfly\layout\includes\page\categories.pug 添加:

    1
    2
    #categories-echarts(style="height:400px")
    !=categories_pic({id:'categories-echarts',title:'文章分类统计图',seriesName:'分类统计'})
  1. [Blogroot]\themes\butterfly\scripts\helpers\hexo_echarts.js 添加 posts_echarts 函数:

    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
    hexo.extend.helper.register('posts_echarts', function (options) {
    let { title, id, seriesName } = options
    var moment = require('moment');
    const startDate = moment().subtract(1, 'years').startOf('month')
    const endDate = moment().endOf('month')

    const monthMap = new Map()
    const dayTime = 3600 * 24 * 1000
    for (let time = startDate; time <= endDate; time += dayTime) {
    const month = moment(time).format('YYYY-MM')
    if (!monthMap.has(month)) {
    monthMap.set(month, 0)
    }
    }
    hexo.locals.get('posts').forEach(function (post) {
    const month = post.date.format('YYYY-MM')
    if (monthMap.has(month)) {
    monthMap.set(month, monthMap.get(month) + 1)
    }
    })
    let postsArr = [...monthMap.entries()]
    return `
    <script type="text/javascript" id="${id}">
    var themeMode = document.documentElement.getAttribute('data-theme') === 'dark' ? 'dark' : 'light'
    var postsChart = echarts.init(document.getElementById("${id}"),themeMode);
    let postsOption = {
    color: ['#425aef'],
    title:{
    text:'${title}',
    x:'center'
    },
    tooltip:{
    trigger: 'axis',
    axisPointer: {
    type: 'shadow',
    shadowStyle:{
    color:'rgba(66,90,239,0.3)'
    }
    },
    },
    xAxis: {
    type: 'category',
    boundaryGap: false
    },
    yAxis: {
    name:'${seriesName}',
    axisLine: {
    show: true
    }
    },
    series: [
    {
    name:'${seriesName}',
    type: 'line',
    smooth:true,
    symbol: 'none',
    lineStyle: {
    color: '#425aef',
    width: 1
    },
    areaStyle: {
    color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{
    offset: 0,
    color: '#425aef',
    }, {
    offset: 1,
    color: '#FFFFFF'
    }])
    },
    data: ${JSON.stringify(postsArr)}
    }
    ]
    };
    postsChart.setOption(postsOption);
    window.addEventListener("resize", () => {
    postsChart.resize();
    });
    </script>`
    })

2)执行 hexo new page echarts,新增菜单

1
hexo new page echarts

3)主题配置文件:

1
2
menu:
统计: /echarts/ || fa fa-area-chart

4)在 [Blogroot]\source\echarts\index.md 添加 type: 'echarts':

5)在 [Blogroot]\themes\butterfly\layout\page.pug 大约 15 行处添加:

1
2
3
4
5
6
7
8
9
10
11
case page.type
when 'tags'
include includes/page/tags.pug
when 'link'
include includes/page/flink.pug
when 'categories'
include includes/page/categories.pug
+ when 'echarts'
+ include includes/page/echarts.pug
default
include includes/page/default-page.pug

6)新增文件 [Blogroot]\themes\butterfly\layout\includes\page\echarts.pug

1
2
3
4
5
6
7
8
9
10
11
//- 文章发布统计图
#posts-echart(style="height:320px")
!=posts_echarts({title:'文章发布统计',id:'posts-echart',seriesName:'文章篇数'})

//- 标签统计图表
#tag-echarts(style="height:320px")
!=tag_ranking_bar({type:'tag',id:'tag-echarts',topNum:10,title:'Top 10 标签统计图',color:theme.theme_color,yAxisName:'文章篇数',seriesName:'标签统计'})

//- 分类统计图表
#categories-echarts(style="height:400px")
!=categories_pic({id:'categories-echarts',title:'文章分类统计图',seriesName:'分类统计'})

7)主题配置文件关闭 Pjax

为了让页面刷新以显示图表,暂不清楚原因。当然也可以使用 exclude 去排除

1
2
3
4
pjax: 
enable: false
exclude:
# - /路径

添加右键菜单

效果预览

image-20221028232340308

查看步骤
  1. [Blogroot]\themes\butterfly\layout\includes\third-party\ 目录下新建 galmenu.pug 文件

    1
    2
    3
    4
    5
    6
    7
    8
    #rightMenu
    each MenuItem,index in theme.GalMenu.MenuGuoup
    .rightMenu-group
    each item in MenuItem.MenuItem
    a.rightMenu-item.faa-parent.animated-hover(href=url_for(item.link),title=item.name,id=item.id)
    i.fa.faa-tada(class=item.icon)
    if index != 0
    span.rightMenu-name=item.name
  2. 修改 [Blogroot]\themes\butterfly\layout\includes\additional-js.pug 文件,在末尾添加内容(注意缩进), 注意 butterfly_v3.6.0 取消了缓存配置,转为完全默认,需要将 {cache:theme.fragment_cache} 改为 {cache: true}

    1
    2
    +     if theme.GalMenu.enable
    + !=partial('includes/third-party/galmenu', {}, {cache: true})
  3. [Blogroot]\themes\butterfly\source\css\_layout\ 目录下新建 galmenu.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
    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
    /* rightMenu */
    #rightMenu {
    display: none;
    position: fixed;
    width: 160px;
    height: fit-content;
    top: 10%;
    left: 10%;
    background-color: var(--card-bg);
    border: 1px solid var(--style-border);
    border-radius: 8px;
    z-index: 100;
    box-shadow: 0 0 5px 2px rgba(0, 0, 0, 0.35);
    }

    #rightMenu .rightMenu-group {
    padding: 7px 6px;

    &:nth-child(1) {
    display: flex;
    align-items: center;
    justify-content: space-around;
    }

    &:not(:nth-last-child(1)) {
    border-bottom: 2px dashed #425aef;
    }

    &:not(:nth-child(1)) .rightMenu-item {
    margin: 0.25rem 0;
    }

    .rightMenu-item {
    height: 30px;
    line-height: 30px;
    border-radius: 8px;
    transition: 0.3s;
    color: var(--font-color);
    display: flex;

    &:hover {
    background-color: var(--text-bg-hover);
    color: var(--cyan-white);
    }

    i {
    display: inline-block;
    text-align: center;
    line-height: 30px;
    width: 30px;
    height: 30px;
    padding: 0 5px;
    }

    span.rightMenu-name {
    line-height: 30px;
    margin-left: 5px;
    letter-spacing: 5px;
    }
    }
    }

    .rightMenu-group.hide {
    display: none;
    }
  4. 新建 [Blogroot]\themes\butterfly\source\js\custom.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
    let weijin = {};
    weijin.showRightMenu = function (isTrue, x = 0, y = 0) {
    let $rightMenu = document.getElementById('rightMenu');
    $rightMenu.style.top = x + 'px';
    $rightMenu.style.left = y + 'px';

    if (isTrue) {
    $rightMenu.style.display="block";
    } else {
    $rightMenu.style.display="none";
    }
    }
    // 右键菜单事件
    if (!(navigator.userAgent.match(/(phone|pad|pod|iPhone|iPod|ios|iPad|Android|Mobile|BlackBerry|IEMobile|MQQBrowser|JUC|Fennec|wOSBrowser|BrowserNG|WebOS|Symbian|Windows Phone)/i))) {
    window.oncontextmenu = function (event) {
    var rightMenu_group_hide = document.getElementsByClassName('rightMenu-group.hide');
    for (var i=0;i<rightMenu_group_hide.length;i++) {
    rightMenu_group_hide[i].style.display="none";
    }
    if (document.getSelection().toString()) {
    document.getElementById('menu-tools').style.display="block";
    }
    if (event.ctrlKey) return true;
    if (localStorage.getItem("right_menu_switch") === 'off') return true
    let pageX = event.clientX + 10;
    let pageY = event.clientY;
    let rmWidth = document.getElementById('rightMenu').style.width;
    let rmHeight = document.getElementById('rightMenu').style.height;
    if (pageX + rmWidth > window.innerWidth) {
    pageX -= rmWidth + 10;
    }
    if (pageY + rmHeight > window.innerHeight) {
    pageY -= pageY + rmHeight - window.innerHeight;
    }



    weijin.showRightMenu(true, pageY, pageX);
    return false;
    };

    window.addEventListener('click', function () { weijin.showRightMenu(false); });
    }
  5. 在主题配置文件添加如下配置项

    1
    2
    3
    inject:
    bottom:
    - <script async src="/js/custom.js"></script>
    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
    # 自定义右键菜单
    GalMenu:
    enable: true # true or false 是否开启右键
    MenuGuoup:
    - MenuItem: #菜单配置
    - name: 后退
    icon: fa fa-arrow-left
    link: javascript:history.go(-1);
    - name: 前进
    icon: fa fa-arrow-right
    link: javascript:history.go(1);
    - name: 刷新
    icon: fa fa-refresh
    link: javascript:location.reload()
    - name: 返回顶部
    icon: fa fa-arrow-up
    link: '#'
    - MenuItem:
    - name: 回到主页
    icon: fas fa-home
    link: '/'
    - name: 博客统计
    icon: fa fa-area-chart
    link: '/echarts/'
    - MenuItem:
    - name: 昼夜模式
    icon: fas fa-adjust
    link: javascript:switchNightMode()

随机文章

查看步骤
  1. 主题根目录\scripts\目录下新建random.js文件

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    hexo.extend.generator.register('random', function (locals) {
    const config = hexo.config.random || {}
    const posts = []
    for (const post of locals.posts.data) {
    if (post.random !== false) posts.push(post.path)
    }
    return {
    path: config.path || 'random/index.html',
    data: `<html><head><script>var posts=${JSON.stringify(posts)};window.open('/'+posts[Math.floor(Math.random() * posts.length)],"_self")</script></head></html>`
    }
    })
  2. 使用/random/即可访问随机文章

唯一文章链接

查看步骤

Hexo默认的静态URL格式是 :year/:month/:day/:title,也就是按照年、月、日、标题来生成固定链接的。如 http://xxx.yy.com/2020/07/06/hello-world

这种默认配置的缺点就是一般文件名是中文,导致 url 链接里有中文出现,这会造成很多问题,也不利于 `seo ,另外就是年月日都会有分隔符。

知识点:

  1. 百度蜘蛛抓取网页的规则: 对于蜘蛛说网页权重越高、信用度越高抓取越频繁,例如网站的首页和内页。蜘蛛先抓取网站的首页,因为首页权重更高,并且大部分的链接都是指向首页。然后通过首页抓取网站的内页,并不是所有内页蜘蛛都会去抓取。

  2. 搜索引擎认为对于一般的中小型站点,3层足够承受所有的内容了,所以蜘蛛经常抓取的内容是前三层,而超过三层的内容蜘蛛认为那些内容并不重要,所以不经常爬取。出于这个原因所以permalink后面跟着的最好不要超过2个斜杠。

    对于这个问题,使用 hexo-abbrlink 插件可以完美解决。

  1. 在博客根目录 [Blogroot] 下打开终端,运行以下指令安装 hexo-abbrlink 插件

    1
    npm install hexo-abbrlink --save
  2. 修改文件 [Blogroot]\_config.yml

    1
    2
    3
    4
    5
    #设置永久链接
    permalink: posts/:abbrlink.html # 此处可以自己设置,也可以直接使用 :/abbrlink
    abbrlink:
    alg: crc16 #算法: crc16(default) and crc32
    rep: dec #进制: dec(default) and hex

    Abbrlink 插件拥有两项设置选项:

    • alg: 算法(目前支持 crc16crc32 算法,默认值是 crc16)
    • rep: 形式(生成的链接可以是十六进制格式也可以是十进制格式,默认值是十进制格式)

    生成的链接将会是这样的(官方样例):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    crc16 & hex
    https://post.zz173.com/posts/66c8.html

    crc16 & dec
    https://post.zz173.com/posts/65535.html
    crc32 & hex
    https://post.zz173.com/posts/8ddf18fb.html

    crc32 & dec
    https://post.zz173.com/posts/1690090958.html

    生成完后,原 md 文件的 Front-matter 内会增加 abbrlink 字段,值为生成的 ID 。这个字段确保了在修改了 Front-matter 内的博客标题 title 或创建日期 date 字段之后而不会改变链接地址。

    1. 注意在生成之前就要改好算法和形式,不然后面再改的话会导致链接不统一。
    2. 刚使用这个插件后,阅读人数和评论都会变为0,介意慎用!综上所述,这插件适合新站!
  3. 最后执行 hexo 命令三连: hexo chexo ghexo s,即可看到效果

标签右上角添加章数

查看步骤

修改 [Blogroot]\themes\butterfly\scripts\helpers\page.js,在约第 52 行处:

1
2
3
4
5
6
7
8
9
source.forEach(tag => {
const ratio = length ? sizes.indexOf(tag.length) / length : 0
const size = minfontsize + ((maxfontsize - minfontsize) * ratio)
let style = `font-size: ${parseFloat(size.toFixed(2))}${unit};`
const color = 'rgb(' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ', ' + Math.floor(Math.random() * 201) + ')' // 0,0,0 -> 200,200,200
style += ` color: ${color}`
- result += `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}</a>`
+ result += `<a href="${env.url_for(tag.path)}" style="${style}">${tag.name}<sup>${tag.length}</sup></a>`
})

修改滚动条样式

查看步骤

在主题根目录 source/css/custom.css 中添加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/* 滚动条 */
::-webkit-scrollbar-thumb {
background-color: #2ab1ff;
background-image: -webkit-linear-gradient(45deg, rgba(255, 255, 255, .4) 25%, transparent 25%, transparent 50%, rgba(255, 255, 255, .4) 50%, rgba(255, 255, 255, .4) 75%, transparent 75%, transparent);
border-radius: 3em;
}

::-webkit-scrollbar-track {
background-color: #ffffff;
border-radius: 3em;
}

::-webkit-scrollbar {
width: 8px;
height: 15px;
}

首页文章卡片修改

效果预览

image-20221101142414998

查看步骤
  1. 修改[Blogroot]\themes\butterfly\layout\includes\mixins\post-ui.pug,将整个文件的内容替换为以下代码:

    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
    mixin postUI(posts)
    each article , index in page.posts.data
    .recent-post-item
    -
    let link = article.link || article.path
    let title = article.title || _p('no_title')
    const position = theme.cover.position
    let leftOrRight = position === 'both'
    ? index%2 == 0 ? 'left' : 'right'
    : position === 'left' ? 'left' : 'right'
    let post_cover = article.cover
    let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
    -
    .recent-post-content(class=leftOrRight)
    a.article-content(href=url_for(link) title=subtitle)
    //- Display the article introduction on homepage
    case theme.index_post_content.method
    when false
    - break
    when 1
    .article-content-text!= article.description
    when 2
    if article.description
    .article-content-text!= article.description
    else
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .article-content-text!= expert
    default
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .article-content-text!= expert
    .recent-post-info
    a.article-title(href=url_for(link) title=subtitle)
    .article-title-link= title
    .recent-post-meta
    .article-meta-wrap
    if (is_home() && (article.top || article.sticky > 0))
    span.article-meta
    i.fas.fa-thumbtack.sticky
    span.sticky= _p('sticky')
    span.article-meta-separator |
    if (theme.post_meta.page.date_type)
    span.post-meta-date
    if (theme.post_meta.page.date_type === 'both')
    i.far.fa-calendar-alt
    span.article-meta-label=_p('post.created')
    time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
    span.article-meta-separator |
    i.fas.fa-history
    span.article-meta-label=_p('post.updated')
    time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
    else
    - let data_type_updated = theme.post_meta.page.date_type === 'updated'
    - let date_type = data_type_updated ? 'updated' : 'date'
    - let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
    - let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
    i(class=date_icon)
    span.article-meta-label=date_title
    time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
    if (theme.post_meta.page.categories && article.categories.data.length > 0)
    span.article-meta
    span.article-meta-separator |
    i.fas.fa-inbox
    each item, index in article.categories.data
    a(href=url_for(item.path)).article-meta__categories #[=item.name]
    if (index < article.categories.data.length - 1)
    i.fas.fa-angle-right.article-meta-link
    if (theme.post_meta.page.tags && article.tags.data.length > 0)
    span.article-meta.tags
    span.article-meta-separator |
    i.fas.fa-tag
    each item, index in article.tags.data
    a(href=url_for(item.path)).article-meta__tags #[=item.name]
    if (index < article.tags.data.length - 1)
    span.article-meta-link #[='•']

    mixin countBlockInIndex
    - needLoadCountJs = true
    span.article-meta
    span.article-meta-separator |
    i.fas.fa-comments
    if block
    block
    span.article-meta-label= ' ' + _p('card_post_count')

    if theme.comments.card_post_count
    case theme.comments.use[0]
    when 'Disqus'
    when 'Disqusjs'
    +countBlockInIndex
    a(href=full_url_for(link) + '#disqus_thread')
    when 'Valine'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment' itemprop="discussionUrl")
    span.valine-comment-count(data-xid=url_for(link) itemprop="commentCount")
    when 'Waline'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.waline-comment-count(id=url_for(link))
    when 'Twikoo'
    +countBlockInIndex
    a.twikoo-count(href=url_for(link) + '#post-comment')
    when 'Facebook Comments'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.fb-comments-count(data-href=urlNoIndex(article.permalink))
    .recent-post-cover
    img.article-cover(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=subtitle)

    if theme.ad && theme.ad.index
    if (index + 1) % 3 == 0
    .recent-post-item.ads-wrap!=theme.ad.index
  2. 修改[Blogroot]\themes\butterfly\source\css\_page\homepage.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
    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
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    //default color:
    :root
    --recent-post-bgcolor: rgba(255, 255, 255, 0.9)
    --article-content-bgcolor: #49b1f5
    --recent-post-triangle: #fff
    --recent-post-cover-shadow: #ffffff
    [data-theme="dark"]
    --recent-post-bgcolor: rgba(35,35,35,0.5)
    --article-content-bgcolor: #99999a
    --recent-post-triangle: #37e2dd
    --recent-post-cover-shadow: #232323
    .recent-posts
    padding 0 15px 0 15px

    .recent-post-item
    margin-bottom 15px
    width 100%
    background var(--recent-post-bgcolor)
    overflow hidden
    border-radius 15px
    .recent-post-info
    .article-title-link
    display -webkit-box
    -webkit-box-orient vertical
    -webkit-line-clamp 2
    overflow hidden
    .article-content
    background var(--article-content-bgcolor)
    position relative
    display flex
    align-items: center;
    justify-content: center;
    .article-content-text
    transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    display -webkit-box
    -webkit-box-orient vertical
    -webkit-line-clamp 4
    text-overflow: ellipsis
    overflow hidden
    color #fff
    text-shadow: 1px 2px 3px #000;
    .recent-post-cover
    position relative
    background transparent
    img
    &.article-cover
    height 100%
    width 100%
    object-fit cover

    .recent-post-info
    align-items center
    flex-direction column
    position relative
    background var(--recent-post-bgcolor)
    display flex
    color #000000
    .article-title
    height 50%
    font-size 24px
    display: flex
    align-items: center
    justify-content: flex-end
    flex-direction: column
    .article-title-link
    color: var(--text-highlight-color)
    transition: all .2s ease-in-out
    &:hover
    color: $text-hover
    .recent-post-meta
    height 50%
    display: flex
    align-items: center
    justify-content: flex-start
    flex-direction: column
    .article-meta-wrap
    font-size 12px
    color #969797
    display: -webkit-box;
    -webkit-box-orient: vertical;
    -webkit-line-clamp: 3;
    overflow: hidden;
    a
    color: var(--text-highlight-color)
    transition: all .2s ease-in-out
    color #969797
    &:hover
    color: $text-hover
    &.ads-wrap
    display: block !important
    height: auto !important
    @media screen and (min-width:600px)
    .recent-post-item
    &:hover
    .recent-post-content
    &.both,
    &.right
    transform translateX(21%)
    transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    &::before
    transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    left: 50px;
    .article-content-text
    margin 20px 20px 20px 60px
    &.left
    transform translateX(-21%)
    transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    &::before
    transition: all .8s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    right: 50px;
    .article-content-text
    margin 20px 60px 20px 20px


    .recent-post-content
    background var(--recent-post-bgcolor)
    position relative
    height 200px
    width 130%
    z-index 0
    display flex
    overflow hidden
    border 0px solid
    &::before
    content: "";
    width: 0;
    height: 0;
    background: transparent;
    position: absolute;
    z-index: 3;
    top: calc(50% - 10px);
    border-top: 10px solid transparent;
    border-bottom: 10px solid transparent;
    transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    &.both,
    &.right
    flex-direction: row;
    left calc(-23.07% - 41px)
    transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    &::before
    left: calc(23.07% + 40px);
    border-left: 6px solid var(--recent-post-triangle);
    .recent-post-info
    &::before
    background linear-gradient(to right, var(--recent-post-cover-shadow), transparent)
    left calc(100% - 1px)
    .article-content
    &::before
    right -59px
    border-left 60px solid var(--article-content-bgcolor)
    .article-content-text
    margin 20px 20px 20px 0px
    .article-title
    padding 0px 30px 0px 70px
    .recent-post-meta
    padding 0px 20px 0px 70px
    &.left
    flex-direction: row-reverse;
    right 9px
    transition: all .5s cubic-bezier(0.59, 0.01, 0.48, 1.17)
    &::before
    right: calc(23.07% + 40px);
    border-right: 6px solid var(--recent-post-triangle);
    .recent-post-info
    &::before
    background linear-gradient(to left, var(--recent-post-cover-shadow), transparent)
    right calc(100% - 1px)
    .article-content
    &::before
    left -59px
    border-right 60px solid var(--article-content-bgcolor)
    .article-content-text
    margin 20px 0px 20px 20px
    .article-title
    padding 0px 70px 0px 30px
    .recent-post-meta
    padding 0px 70px 0px 20px

    .article-content
    width 30%
    height 200px
    left 0
    align-items center
    &::before
    content ""
    width 0
    height 0
    background transparent
    position absolute
    z-index 2
    top 0
    border-top 100px solid transparent
    border-bottom 100px solid transparent
    .recent-post-info
    width 60%
    height 200px
    &::before
    content ""
    width 200px
    height 200px
    position absolute
    z-index 1
    top 0
    .recent-post-meta
    & > .article-meta-wrap
    margin: 6px 0
    color: $theme-meta-color
    font-size: 90%

    & > .post-meta-date
    cursor: default

    .sticky
    color: $sticky-color

    i
    margin: 0 4px 0 0

    .article-meta-label
    if hexo-config('post_meta.page.label')
    padding-right: 4px
    else
    display: none

    .article-meta-separator
    margin: 0 6px

    .article-meta-link
    margin: 0 4px

    if hexo-config('post_meta.page.date_format') == 'relative'
    time
    display: none

    a
    color: $theme-meta-color

    &:hover
    color: $text-hover
    text-decoration: underline
    .recent-post-cover
    width 40%
    height 200px
    @media screen and (max-width:600px)
    .recent-post-item
    height 400px
    .recent-post-content
    display flex
    flex-direction: column
    height 400px
    .article-content
    pointer-events none
    order: 1;
    height: 200px;
    position: absolute;
    width: calc(100% - 40px);
    z-index: 3;
    background: rgba(22,22,22,0.5);
    border-top-left-radius: 15px;
    border-top-right-radius: 15px;
    display: none
    opacity: 0
    .article-content-text
    height 120px
    color: white;
    width: 80%

    .recent-post-cover
    order: 2
    height 200px
    transition: all .5s
    .recent-post-info
    order: 3
    height 200px
    &::before
    content: '';
    width: 0;
    height: 0;
    position: absolute;
    z-index: 3;
    bottom: calc(100% - 4px);
    left: 0;
    border-bottom: 50px solid var(--recent-post-bgcolor);
    border-right: 300px solid transparent;
    &::after
    content: '';
    width: 0;
    height: 0;
    position: absolute;
    z-index: 3;
    bottom: calc(100% + 150px);
    right: 0;
    border-top: 50px solid var(--recent-post-bgcolor);
    border-left: 300px solid transparent;
    .article-title
    padding: 0px 35px 0px 35px
    .recent-post-meta
    padding: 0px 30px 0px 30px
    &:hover
    .article-content
    display: flex !important;
    animation: shutter-effect-content 0.5s 2 forwards linear
    .recent-post-info
    &::before
    animation: shutter-effect-left 0.5s 1 ease-in-out
    &::after
    animation: shutter-effect-right 0.5s 1 ease-in-out
    .recent-post-cover
    filter blur(2px)
    @keyframes shutter-effect-right {
    0%{
    bottom: calc(100% + 150px);
    border-top: 50px solid var(--recent-post-bgcolor);
    border-left: 300px solid transparent;
    }
    50%{
    bottom: 100%;
    border-top: 200px solid var(--recent-post-bgcolor);
    border-left: 600px solid transparent;
    }
    100%{
    bottom: calc(100% + 150px);
    border-top: 50px solid var(--recent-post-bgcolor);
    border-left: 300px solid transparent;
    }
    }
    @keyframes shutter-effect-left {
    0%{
    bottom: calc(100% - 4px);
    border-bottom: 50px solid var(--recent-post-bgcolor);
    border-right: 300px solid transparent;
    }
    50%{
    bottom: calc(100% - 4px);
    border-bottom: 200px solid var(--recent-post-bgcolor);
    border-right: 600px solid transparent;
    }
    100%{
    bottom: calc(100% - 4px);
    border-bottom: 50px solid var(--recent-post-bgcolor);
    border-right: 300px solid transparent;
    }
    }
    @keyframes shutter-effect-content {
    from {
    opacity: 0
    }
    to {
    opacity: 1
    }
    }
源代码

这里记录原来的代码,以便以后想换回去。

  1. post-ui.pug

    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
    mixin postUI(posts)
    each article , index in page.posts.data
    .recent-post-item
    -
    let link = article.link || article.path
    let title = article.title || _p('no_title')
    const position = theme.cover.position
    let leftOrRight = position === 'both'
    ? index%2 == 0 ? 'left' : 'right'
    : position === 'left' ? 'left' : 'right'
    let post_cover = article.cover
    let no_cover = article.cover === false || !theme.cover.index_enable ? 'no-cover' : ''
    -
    if post_cover && theme.cover.index_enable
    .post_cover(class=leftOrRight)
    a(href=url_for(link) title=title)
    img.post_bg(src=url_for(post_cover) onerror=`this.onerror=null;this.src='`+ url_for(theme.error_img.post_page) + `'` alt=title)
    .recent-post-info(class=no_cover)
    a.article-title(href=url_for(link) title=title)= title
    .article-meta-wrap
    if (is_home() && (article.top || article.sticky > 0))
    span.article-meta
    i.fas.fa-thumbtack.sticky
    span.sticky= _p('sticky')
    span.article-meta-separator |
    if (theme.post_meta.page.date_type)
    span.post-meta-date
    if (theme.post_meta.page.date_type === 'both')
    i.far.fa-calendar-alt
    span.article-meta-label=_p('post.created')
    time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))=date(article.date, config.date_format)
    span.article-meta-separator |
    i.fas.fa-history
    span.article-meta-label=_p('post.updated')
    time.post-meta-date-updated(datetime=date_xml(article.updated) title=_p('post.updated') + ' ' + full_date(article.updated))=date(article.updated, config.date_format)
    else
    - let data_type_updated = theme.post_meta.page.date_type === 'updated'
    - let date_type = data_type_updated ? 'updated' : 'date'
    - let date_icon = data_type_updated ? 'fas fa-history' :'far fa-calendar-alt'
    - let date_title = data_type_updated ? _p('post.updated') : _p('post.created')
    i(class=date_icon)
    span.article-meta-label=date_title
    time(datetime=date_xml(article[date_type]) title=date_title + ' ' + full_date(article[date_type]))=date(article[date_type], config.date_format)
    if (theme.post_meta.page.categories && article.categories.data.length > 0)
    span.article-meta
    span.article-meta-separator |
    i.fas.fa-inbox
    each item, index in article.categories.data
    a(href=url_for(item.path)).article-meta__categories #[=item.name]
    if (index < article.categories.data.length - 1)
    i.fas.fa-angle-right.article-meta-link
    if (theme.post_meta.page.tags && article.tags.data.length > 0)
    span.article-meta.tags
    span.article-meta-separator |
    i.fas.fa-tag
    each item, index in article.tags.data
    a(href=url_for(item.path)).article-meta__tags #[=item.name]
    if (index < article.tags.data.length - 1)
    span.article-meta-link #[='•']

    mixin countBlockInIndex
    - needLoadCountJs = true
    span.article-meta
    span.article-meta-separator |
    i.fas.fa-comments
    if block
    block
    span.article-meta-label= ' ' + _p('card_post_count')

    if theme.comments.card_post_count
    case theme.comments.use[0]
    when 'Disqus'
    +countBlockInIndex
    a(href=full_url_for(link) + '#disqus_thread')
    i.fa-solid.fa-spinner.fa-spin
    when 'Disqusjs'
    +countBlockInIndex
    a(href=full_url_for(link) + '#disqusjs')
    span.disqus-comment-count(data-disqus-url=full_url_for(link))
    i.fa-solid.fa-spinner.fa-spin
    when 'Valine'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.valine-comment-count(data-xid=url_for(link))
    i.fa-solid.fa-spinner.fa-spin
    when 'Waline'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.waline-comment-count(id=url_for(link))
    i.fa-solid.fa-spinner.fa-spin
    when 'Twikoo'
    +countBlockInIndex
    a.twikoo-count(href=url_for(link) + '#post-comment')
    i.fa-solid.fa-spinner.fa-spin
    when 'Facebook Comments'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.fb-comments-count(data-href=urlNoIndex(article.permalink))
    i.fa-solid.fa-spinner.fa-spin
    when 'Remark42'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.remark42__counter(data-url=urlNoIndex(article.permalink))
    i.fa-solid.fa-spinner.fa-spin

    //- Display the article introduction on homepage
    case theme.index_post_content.method
    when false
    - break
    when 1
    .content!= article.description
    when 2
    if article.description
    .content!= article.description
    else
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .content!= expert
    default
    - const content = strip_html(article.content)
    - let expert = content.substring(0, theme.index_post_content.length)
    - content.length > theme.index_post_content.length ? expert += ' ...' : ''
    .content!= expert

    if theme.ad && theme.ad.index
    if (index + 1) % 3 == 0
    .recent-post-item.ads-wrap!=theme.ad.index
  2. homepage.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
    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
    #recent-posts
    & > .recent-post-item:not(:first-child)
    margin-top: 20px

    & > .recent-post-item
    @extend .cardHover
    display: flex
    flex-direction: row
    align-items: center
    overflow: hidden
    height: 18em

    +maxWidth768()
    flex-direction: column
    height: auto

    &:hover
    img.post_bg
    transform: scale(1.1)

    &.ads-wrap
    display: block !important
    height: auto !important

    .post_cover
    overflow: hidden
    width: 44%
    height: 100%

    +maxWidth768()
    width: 100%
    height: 230px

    img.post_bg
    @extend .imgHover

    &.right
    order: 1

    +maxWidth768()
    order: 0

    & >.recent-post-info
    padding: 0 40px
    width: 57%

    +maxWidth768()
    padding: 20px 20px 30px
    width: 100%

    &.no-cover
    width: 100%

    +maxWidth768()
    padding: 30px 20px

    & > .article-title
    @extend .limit-more-line
    color: var(--text-highlight-color)
    font-size: 1.72em
    line-height: 1.4
    transition: all .2s ease-in-out
    -webkit-line-clamp: 2

    +maxWidth768()
    font-size: 1.43em

    &:hover
    color: $text-hover

    & > .article-meta-wrap
    margin: 6px 0
    color: $theme-meta-color
    font-size: 90%

    & > .post-meta-date
    cursor: default

    .sticky
    color: $sticky-color

    i
    margin: 0 4px 0 0

    .fa-spinner
    margin: 0

    .article-meta-label
    if hexo-config('post_meta.page.label')
    padding-right: 4px
    else
    display: none

    .article-meta-separator
    margin: 0 6px

    .article-meta-link
    margin: 0 4px

    if hexo-config('post_meta.page.date_format') == 'relative'
    time
    display: none

    a
    color: $theme-meta-color

    &:hover
    color: $text-hover
    text-decoration: underline

    & > .content
    @extend .limit-more-line
    -webkit-line-clamp: 2

和风天气组件

效果预览

image-20221101233016193

查看步骤
  1. 前往 和风天气,创建 天气简约插件

    image-20221101232010602

  2. 插件名称随意,调整配置选项后生成代码

    image-20221101232147327

    自定义颜色、背景颜色透明、其它默认即可。

  3. Hexo\themes\butterfly\source\js\路径下新建weather.js文件,将生成的代码复制进去

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    WIDGET = {
    "CONFIG": {
    "modules": "012",
    "background": "5",
    "tmpColor": "000000",
    "tmpSize": "16",
    "cityColor": "000000",
    "citySize": "16",
    "aqiColor": "FFFFFF",
    "aqiSize": "16",
    "weatherIconSize": "24",
    "alertIconSize": "18",
    "padding": "10px 10px 10px 10px",
    "shadow": "0",
    "language": "auto",
    "fixed": "false",
    "vertical": "top",
    "horizontal": "left",
    "key": "646fc52deb604b34a9491cd6bab08e9c"
    }
    }
  4. 在主题配置文件中找到injectbottom处引入以下两个js文件

    1
    2
    - <script defer data-pjax src="/js/weather.js"></script>
    - <script defer data-pjax src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script>
  5. \themes\butterfly\layout\includes\header路径下找到nav.pug文件,添加如下代码,注意位置

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    nav#nav
    span#blog_name
    a#site-name(href=url_for('/')) #[=config.title]

    + #he-plugin-simple
    + #none_space

    #menus
    if (theme.algolia_search.enable || theme.local_search.enable)
    #search-button
    a.site-page.social-icon.search
    i.fas.fa-search.fa-fw
    span=' '+_p('search.title')
    !=partial('includes/header/menu_item', {}, {cache: true})

    #toggle-menu
    a.site-page
    i.fas.fa-bars.fa-fw
  6. 之后在\themes\butterfly\source\css\_layout\head.styl中将#blog_name替换为#none_space就完成了。