所有有修改的魔改代码,只需要去掉前面的 + 即可,不需要调整相关代码的缩进,而-的那一行直接删除即可

更新 Hexo 及插件和主题

点击查看参考教程
点击查看步骤

更新时需要提前做好备份,更新后出现问题可以退回

  • 更新 Butterfly 主题前,提前备份好原有主题文件夹的代码
    • Butterfly 仓库源码 将源码下载后,覆盖 themes\butterfly 文件夹,然后把新的配置文件更新到根目录下自己创建的 _config.butterfly.yml 中,同时需要重新修改相当多的魔改内容(因为更新主题源代码覆盖掉了自己的魔改内容)
  • 使用 npm update 可以自动更新插件和 Hexo 版本
  • 通过 npm outdated 可以检查 Hexo 和插件的最新版本
    • 然后修改 package.json,将插件名称所对应的版本号更改为要更新的版本号
    • 使用 npm install --save,开始更新插件

侧边栏天气卡片

点击查看参考教程
点击查看步骤
  • 前往和风天气开发平台,创建天气标准插件,调整好样式后,点击最下面的生成代码,这里需要登录或者注册账号
  • 生成代码后,只需要保留 WIDGET 部分
  • 创建 themes\butterfly\layout\includes\widget\card_weather.pug
    // 本小站的插件样式代码
    .card-widget.card-weather(style='width:100%,height:270px')
    .item-headline
    i(class="fas fa-cloud-sun")
    span="天气"
    #he-plugin-standard
    script.
    WIDGET = {
    "CONFIG": {
    "layout": "2",
    "width": 270,
    "height": 270,
    "background": "5",
    "dataColor": "000000",
    "language": "zh",
    "key": "!{theme.aside.card_weather.key}"
    }
    }
    script(src='https://widget.qweather.net/standard/static/js/he-standard-common.js?v=2.0')
  • 修改 themes\butterfly\layout\includes\widget\index.pug
      #aside-content.aside-content
    //- post
    if is_post()
    ...
    else
    !=partial('includes/widget/card_author', {}, {cache: true})
    ...
    # 请注意,添加的位置表明了在侧边栏的优先级顺序,也可以在 post 这里不添加
    + !=partial('includes/widget/card_weather', {}, {cache: true})
    .sticky_layout
    if showToc
    include ./card_post_toc.pug
    ...
    !=partial('includes/widget/card_ad', {}, {cache: true})

    else
    //- page
    !=partial('includes/widget/card_author', {}, {cache: true})
    ...
    # 请注意,添加的位置表明了在侧边栏的优先级顺序
    + !=partial('includes/widget/card_weather', {}, {cache: true})
    .sticky_layout
    if showToc
    include ./card_post_toc.pug
    ...
    ...
  • _config.butterfly.yml 中的 aside 下添加 card_weather 配置
    aside:
    enable: true
    ...
    card_weather:
    enable: true
    key: #你开始获取的key
  • 在 css 文件中添加
    #he-plugin-standard{
    width:100%!important;
    margin-bottom:20px!important;
    }
    .wv-lt-location>a,
    .wv-lt-location>span,
    .wv-n-h-now-tmp>span,
    .wv-n-h-now-txt>span,
    .wv-n-h-now-rain>a,
    .wv-n-h-now-rain>span,
    .wv-f-forecast-date>a,
    .wv-f-a {
    color: var(--font-color) !important;
    font-family: 'HYTMR', 'Microsoft Yahei', 'PingFang SC', 'SimSun' !important;
    font-size: 14px;
    }

    .wv-n-h-now-aqi-item {
    display: none;
    }

友链样式美化

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 可以在 source/link 下的 index.md 文件中添加自己的友链,方便别人引用,内容会出现在友链页面的最后
    - name: SuburbiaXX
    link: https://suburbiaxx.fun/
    avatar: https://pic.imgdb.cn/item/641c531ea682492fcc0713a3.jpg
    description: 努力空想的摆烂小孩
    siteshot: https://pic.imgdb.cn/item/6582efb0c458853aef03d900.webp

配置文章链接转数字或字母

点击查看参考教程
点击查看步骤
  • 安装插件
    npm install hexo-abbrlink --save
  • _config.yml 中添加配置
    # abbrlink config
    abbrlink:
    alg: crc32 #support crc16(default) and crc32 进制
    rep: hex #support dec(default) and hex 算法
    drafts: false #(true)Process draft,(false)Do not process draft. false(default)
    ## Generate categories from directory-tree
    ## depth: the max_depth of directory-tree you want to generate, should > 0
    auto_category:
    enable: true #true(default)
    depth: #3(default)
    over_write: false
    auto_title: false #enable auto title, it can auto fill the title by path
    auto_date: false #enable auto date, it can auto fill the date by time today
    force: false #enable force mode,in this mode, the plugin will ignore the cache, and calc the abbrlink for every post even it already had abbrlink.

文章页 H1-H6 图标风车样式效果

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 改完之后,在 css 上调整了一下风车的样式,为了让风车更加靠近文字,取消了所有的 margin-left 样式
    /* 小风车颜色、大小 */
    #content-inner.layout h1::before {
    color: #ef50a8;
    - margin-left: -1.55rem;
    font-size: 1.3rem;
    margin-top: -0.23rem;
    }

    #content-inner.layout h2::before {
    color: #fb7061;
    - margin-left: -1.35rem;
    font-size: 1.1rem;
    margin-top: -0.12rem;
    }

    #content-inner.layout h3::before {
    color: #ffbf00;
    - margin-left: -1.22rem;
    font-size: 0.95rem;
    margin-top: -0.09rem;
    }

    #content-inner.layout h4::before {
    color: #a9e000;
    - margin-left: -1.05rem;
    font-size: 0.8rem;
    margin-top: -0.09rem;
    }

    #content-inner.layout h5::before {
    color: #57c850;
    - margin-left: -0.9rem;
    font-size: 0.7rem;
    margin-top: 0rem;
    }

    #content-inner.layout h6::before {
    color: #5ec1e0;
    - margin-left: -0.9rem;
    font-size: 0.66rem;
    margin-top: 0rem;
    }

文章顶部波浪效果

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

侧边栏电子时钟

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 建议申请和风天气应用的 key 和高德地图的 key
    • 和风天气应用的 key 和之前导航栏和风天气插件的 key 不一样

loading 加载动画

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

异步加载

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 拿捏不准的异步加载情况可以在测试的时候都试试

网站恶搞标题

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 本小站的配置如下
    // 动态标题
    var OriginTitile = document.title;
    var titleTime;
    document.addEventListener('visibilitychange', function () {
    if (document.hidden) {// 离开当前页面时标签显示内容
    document.title = '😶‍🌫️离去不必挽留~';
    clearTimeout(titleTime);
    } else {// 返回当前页面时标签显示内容
    document.title = '✨归来仍存欣喜~';
    titleTime = setTimeout(function () {// 两秒后变回正常标题
    document.title = OriginTitile;
    }, 2000);
    }
    });

algolia 搜索

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 主要参考的是最后一个链接教程
  • 本小站的配置如下,此处需要注意,如果配置一切正常,但是在最后使用 hexo algolia 指令时报错了,有可能是因为 fields 参数中配置的内容过多,导致超出了长度限制,此时需要将 fields 中的内容进行删减(本人亲身踩坑)
  • 出现问题也可以去 algolia 的 dashboard 中看看 Index 的上传情况,根据更多的报错来进行调整
    <!-- _config.butterfly.yml  -->
    # Algolia search
    algolia_search:
    enable: true
    hits:
    per_page: 6
    labels:
    input_placeholder: Search for Posts
    hits_empty: "我们没有找到任何搜索结果: ${query}"
    hits_stats: "找到${hits}条结果(用时${time} ms)"

    <!-- _config.yml -->
    # algolia config
    algolia:
    appId: "..." // 此处需要填写自己的 appId
    apiKey: "..." // 此处需要填写自己的 apiKey
    adminApiKey: "..." // 此处需要填写自己的 adminApiKey
    chunkSize: 5000
    indexName: "..." // 此处需要填写自己的 indexName
    fields:
    - content:strip:truncate,0,500
    - description:strip
    - title
    - path

导航栏

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 参考了大佬们的许多教程,主要是参考了第一个链接的教程

图形统计

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

侧边栏归档修改

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

侧边栏标签修改

点击查看参考教程
点击查看步骤
  • 对应 tag 的数量角标没出现的话,需要把 _config.butterfly.yml 中 aside -> card_tags -> color 改成 true

时间轴生肖

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

侧边栏个人卡片

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 本小站的 css 配置
    /* 侧边栏个人卡片 */
    #aside-content>.card-widget.card-info {
    background: linear-gradient(-45deg, #bbd2c5, #90b6cc, #b6bcd6, #bfc1cf);
    background-size: 400%;
    box-shadow: rgba(0, 0, 0, 0.05);
    animation: gradient 20s ease infinite;
    position: relative;
    color: #fff;
    }

    .site-data>a .headline,
    .site-data>a .length-num {
    color: #fff;
    }

页脚徽标

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 本小站直接在 \themes\butterfly\layout\includes\footer.pug 中的合适位置添加了页脚徽标,配置如下(这里没有放上备案信息的徽标情况,按需添加即可)
    <p>
    <a style="margin-inline:5px;text-decoration:none;" target="_blank" href="https://hexo.io/">
    <img src="https://img.shields.io/badge/Frame-Hexo-blue?style=flat&logo=hexo" title="博客框架为 Hexo">
    </a>
    <a style="margin-inline:5px;text-decoration:none;" target="_blank" href="https://butterfly.js.org/">
    <img src="https://img.shields.io/badge/Theme-Butterfly-6513df?style=flat&logo=bitdefender" title="主题采用 butterfly">
    </a>
    <a style="margin-inline:5px;text-decoration:none;" target="_blank" href="https://www.jsdelivr.com/">
    <img src="https://img.shields.io/badge/CDN-jsDelivr-orange?style=flat&logo=jsDelivr" title="本站使用 JsDelivr 为静态资源提供 CDN 加速">
    </a>
    <a style="margin-inline:5px;text-decoration:none;" target="_blank" href="https://github.com/">
    <img src="https://img.shields.io/badge/Source-Github-d021d6?style=flat&logo=GitHub" title="本站项目由 Github 托管">
    </a>
    <a style="margin-inline:5px;text-decoration:none;" target="_blank" href="http://creativecommons.org/licenses/by-nc-sa/4.0/">
    <img src="https://img.shields.io/badge/Copyright-BY--NC--SA%204.0-d42328?style=flat&logo=Claris" title="本站采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可">
    </a>
    </p>
  • 备案信息的徽标图片,则可以通过图片转成 base64,然后直接在页脚徽标中使用

外挂标签 plus

点击查看参考教程
点击查看步骤
  • 针对外挂标签的 url,修改了 node_modules\hexo-butterfly-tag-plugins-plus\index.js 中 link.js 部分的内容
    //link.js
    // {% link title, url %}
    // {% link title, url, img %}
    hexo.extend.tag.register('link', function(args) {
    var configtemp = hexo.config.tag_plugins || hexo.theme.config.tag_plugins
    args = args.join(' ').split(',')
    let text = ''
    let url = ''
    let img = ''
    if (args.length < 2) {
    return
    } else if (args.length == 2) {
    text = args[0].trim()
    url = args[1].trim()
    } else if (args.length == 3) {
    text = args[0].trim()
    url = args[1].trim()
    img = args[2].trim()
    }
    let result = '';
    // 发现如果不套一层 div 在其它可渲染 md 的容器中容易被分解
    result += '<div class="tag link"><a class="link-card" title="' + text + '" href="' + url + '">';
    // left
    result += '<div class="left">';
    result += '<img src="' + (img || configtemp.link.placeholder) + '"/>';
    result += '</div>';
    // right
    result += '<div class="right"><p class="text">' + text + '</p><p class="url">' + url + '</p></div>';
    + result += '<i class="fa-solid fa-arrow-right"></i>';
    result += '</a></div>';

    return result;
    });
  • 因为一般不用到网站的图标爬取(参考 zhheo 的 blog),因为有些网站没有图标,于是将 akilar 的 hexo-butterfly-tag-plugins-plus 中的 css 配置注释,手动 down 下来然后在 _config.butterfly.ymlinject 引入方便魔改,修改了 #article-container a.link-card 等,具体如下
    #article-container a.link-card {
    + width: 100%;
    margin: 0.25rem auto;
    background: #f6f6f6;
    display: inline-flex;
    align-items: center;
    cursor: pointer;
    text-align: center;
    - min-width: 200px;
    - max-width: 361px;
    color: #444;
    border-radius: 12px;
    text-decoration: none;
    }

    #article-container a.link-card p {
    + text-align: left;
    margin: 0;
    }

    #article-container a.link-card p.url {
    flex-shrink: 0;
    color: rgba(68, 68, 68, 0.65);
    font-size: 13px;
    + display: block; /* 确保元素是块级元素 */
    + max-width: 300px; /* 设置最大宽度,根据需要调整 */
    + overflow: hidden;
    + white-space: nowrap;
    + text-overflow: ellipsis; /* 使用省略号表示溢出的文本 */
    }

    +#article-container a.link-card i {
    + font-size: x-large;
    + margin-left: auto;
    + margin-right: 35px;
    }

系列文章

点击查看步骤
  • butterfly 自带了 series,但是在每一页的文章的传送门中并没有指向当前位置的功能,直接在 \themes\butterfly\scripts\tag\series.js 中进行魔改,在生成列表的过程中进行判断即可
    // 做了特判,如果当前页面的路径和系列文章的路径一致,则在 li 的内容后面添加标记
    let result = ''
    seriesArr.forEach(ele => {
    - result += `<li><a href="${urlFor(ele.path)}" title="${ele.title}">${ele.title}</a></li>`
    + if (this.path === ele.path) {
    + result += `<li><a href="${urlFor(ele.path)}" title="${ele.title}">${ele.title}</a><span style="color: #ff8c00; font-weight: bold">&emsp;&emsp;&emsp;&emsp;⇦当前位置📌</span></li>`
    + } else {
    + result += `<li><a href="${urlFor(ele.path)}" title="${ele.title}">${ele.title}</a></li>`
    + }
    })

首页文章卡片布局

点击查看参考教程
点击查看步骤
  • 参照教程进行的魔改发现 slidecard.styl 样式出现了点问题,便去找了一些其他的教程,最终使用了 fomalhaut 的代码作为基础进行魔改
  • 魔改了 slidecard.styl 中的样式
    //default color:
    :root
    --recent-post-bgcolor: rgba(247, 252, 254, 0.5) //默认背景
    --article-content-bgcolor: rgba(110, 155, 197, 0.8) //描述版块背景
    --recent-post-arrow: #3271ae //箭头配色
    --recent-post-cover-shadow: transparent//封面遮罩层配色,建议和默认值的颜色相对应。
    --recent-post-transition: all 0.5s cubic-bezier(0.59, 0.01, 0.48, 1.17) //动画效果。不了解的不要改动
    [data-theme="dark"]
    --recent-post-bgcolor: rgba(35,35,35,0.5)
    --article-content-bgcolor: rgba(153, 153, 154, 0.9)
    --recent-post-arrow: #f8fbf8
    --recent-post-cover-shadow: transparent
    // 默认的首页卡片容器布局
    .recent-posts
    padding 0 15px 0 15px
    height fit-content
    .recent-post-item
    margin-bottom 15px
    width 100%
    background var(--recent-post-bgcolor)
    overflow hidden
    border-radius 15px
    .recent-post-content
    display flex
    background var(--recent-post-bgcolor)
    position relative
    .recent-post-cover
    display flex
    background transparent
    .recent-post-info
    display flex
    background transparent
    flex-direction column
    justify-content center
    align-items center
    .article-title
    height 50%
    display: flex
    text-align: center
    align-items: center
    justify-content: flex-end
    flex-direction: column
    .article-title-link
    color: var(--text-highlight-color)
    transition: all .2s ease-in-out
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
    &:hover
    color: $text-hover
    .recent-post-meta
    height 50%
    display: flex
    text-align: center
    align-items: center
    justify-content: flex-start
    flex-direction: column
    .article-meta-wrap
    color #969797
    display: -webkit-box;
    -webkit-box-orient: vertical;
    overflow: hidden;
    a
    color: var(--text-highlight-color)
    transition: all .2s ease-in-out
    color #969797
    &:hover
    color: $text-hover
    .article-content
    display flex
    text-align: center
    flex-direction row
    align-items center
    justify-content center
    .article-content-text
    display -webkit-box
    -webkit-box-orient vertical
    text-overflow: ellipsis
    overflow hidden
    color #fff
    text-shadow 1px 2px 3px #000
    &::before
    content "❝"
    font-size 20px
    &::after
    content "❞"
    font-size 20px
    &.ads-wrap
    display: block !important
    height: auto !important
    // PC端滑动卡片样式
    @media screen and (min-width:1069px)
    .recent-posts
    padding 0 15px 0 15px
    .recent-post-item
    .recent-post-content
    position relative
    height 200px
    width 100%
    transition var(--recent-post-transition)
    &:hover
    .recent-post-cover-shadow
    width 10.1%
    transition var(--recent-post-transition)
    .recent-post-cover
    width 10%
    transition var(--recent-post-transition)
    .article-content
    width calc(30% + 80px)
    transition var(--recent-post-transition)
    .article-content-text
    opacity 1
    .recent-post-arrow
    transition var(--recent-post-transition)
    .recent-post-cover-shadow
    z-index: 1
    transition var(--recent-post-transition)
    position: absolute
    height 200px
    width 40%
    .recent-post-cover
    height 200px
    width 40%
    transition var(--recent-post-transition)
    img
    border-radius 15px
    height 100%
    width 100%
    object-fit cover

    .recent-post-info
    height 200px
    width calc(60% - 80px)
    .article-title
    margin: 0px 40px
    font-size 24px
    .article-title-link
    -webkit-line-clamp: 2;
    .recent-post-meta
    margin: 0px 20px
    .article-meta-wrap
    font-size 12px
    -webkit-line-clamp: 3;
    .article-content
    height 200px
    width 90px
    background var(--article-content-bgcolor)
    transition var(--recent-post-transition)
    .article-content-text
    -webkit-line-clamp 4
    transition: var(--recent-post-transition)
    opacity 0
    .recent-post-arrow
    transition var(--recent-post-transition)
    display block
    position absolute
    height 20px
    width 8px
    background var(--recent-post-arrow)
    &.both,
    &.right
    .recent-post-cover-shadow
    left 0
    background linear-gradient(to left, var(--recent-post-cover-shadow), transparent)
    .recent-post-cover
    order: 1
    .recent-post-info
    order: 2
    .article-content
    order: 3
    clip-path polygon(0 50%, 80px 0, 100% 0, 100% 100%, 80px 100%)
    .article-content-text
    margin 20px 40px 20px 80px
    .recent-post-arrow
    order: 4
    left calc(100% - 80px)
    top calc(50% - 10px)
    clip-path polygon(0 10px, 8px 0, 8px 20px)
    &:hover
    .recent-post-arrow
    left calc(100% - 40px)
    &.left
    .recent-post-cover-shadow
    right 0
    background linear-gradient(to right, var(--recent-post-cover-shadow), transparent)
    .recent-post-cover
    order: 4
    .recent-post-info
    order: 3
    .article-content
    order: 2
    clip-path polygon(100% 50%,calc(100% - 80px) 100%,0 100%,0 0,calc(100% - 80px) 0)
    .article-content-text
    margin 20px 80px 20px 40px
    .recent-post-arrow
    order: 1
    left 72px
    top calc(50% - 10px)
    clip-path polygon(0 0, 8px 10px, 0 20px)
    &:hover
    .recent-post-arrow
    left 32px
    // 双栏布局卡片自适应适配
    @media screen and (min-width:572px) and (max-width:1068px)
    .recent-posts
    padding 0 15px 0 15px
    display flex
    flex-direction row
    flex-wrap wrap
    .recent-post-item
    border-radius 15px
    overflow hidden
    width 47%
    margin 0px 3% 20px 0px
    nav#pagination
    width: 100%
    // 手机端单栏布局自适应适配
    @media screen and (max-width:572px)
    .recent-posts
    padding 0 15px 0 15px
    .recent-post-item
    border-radius 15px
    overflow hidden

    // 手机端及双栏卡片样式
    @media screen and (max-width:1068px)
    .recent-posts
    .recent-post-item
    .recent-post-content
    flex-direction column
    flex-wrap nowrap
    align-items center
    max-height 350px
    height: auto
    width 100%
    .recent-post-cover
    width 100%
    height 200px
    clip-path polygon(0 130px,0 0,100% 0,100% 130px,50% 100%)
    img
    height 200px
    width 100%
    object-fit cover
    .recent-post-info
    height 150px
    width 100%
    padding 0px 25px 5px 25px
    .article-title
    margin: 0px 40px
    font-size 18px
    .article-title-link
    -webkit-line-clamp: 2;
    .recent-post-meta
    margin: 0px 20px
    .article-meta-wrap
    font-size 12px
    -webkit-line-clamp: 3;
    .article-content
    position absolute
    height 200px
    width 100%
    background rgba(25,25,25,0.5)
    clip-path polygon(0 130px,0 0,100% 0,100% 130px,50% 100%)
    .article-content-text
    -webkit-line-clamp 3
    font-size 16px
    margin 0px 25px 30px 25px
    .recent-post-arrow
    display block
    background var(--article-content-bgcolor)
    position absolute
    height 10px
    width 20px
    clip-path polygon(0 0,100% 0,50% 100%)
    top 20px
  • 在教程的基础上修改了 post-ui.pug 中的内容,使其小标签间距更合理
    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)
    .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=title)
    .recent-post-info
    if (numberone !== 1 && is_current('/') && (!article.top || (article.new && article.top)))
    span.newPost 最新
    - var numberone = 1
    a.article-title(href=url_for(link) title=title)
    .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'
    +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))
    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
    when 'Artalk'
    +countBlockInIndex
    a(href=url_for(link) + '#post-comment')
    span.artalk-count(data-page-key=url_for(link))
    i.fa-solid.fa-spinner.fa-spin
    a.article-content(href=url_for(link) title=title)
    //- 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-arrow

    if theme.ad && theme.ad.index
    if (index + 1) % 3 == 0
    .recent-post-item.ads-wrap!=theme.ad.index

文章卡片加上最新标识

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

  • 基于首页文章卡片布局基础上进行的魔改

侧边栏最近文章修改

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

页脚计时器

点击查看参考教程
点击查看步骤
  • \themes\butterfly\layout\includes\footer.pug 中添加一个 #workboard 容器
  • 创建一个 foot_timer.js 文件,利用 js 定时器进行计时并且实现按照秒的刷新
    var now = new Date();
    console.log(now);
    function createtime() {
    // 当前时间
    now.setTime(now.getTime() + 1000);
    // 网站诞生时间
    var grt = new Date("09/04/2022 00:00:00");
    var days = (now - grt) / 1e3 / 60 / 60 / 24,
    dnum = Math.floor(days),
    hours = (now - grt) / 1e3 / 60 / 60 - 24 * dnum,
    hnum = Math.floor(hours);
    1 == String(hnum).length && (hnum = "0" + hnum);
    var minutes = (now - grt) / 1e3 / 60 - 1440 * dnum - 60 * hnum,
    mnum = Math.floor(minutes);
    1 == String(mnum).length && (mnum = "0" + mnum);
    var seconds = (now - grt) / 1e3 - 86400 * dnum - 3600 * hnum - 60 * mnum,
    snum = Math.round(seconds);
    1 == String(snum).length && (snum = "0" + snum);
    let currentTimeHtml = "";
    (currentTimeHtml = `<div style="font-size:13px;font-weight:bold">自 2022-9 以来,小站苟活了 ${dnum}${hnum} 小时 ${mnum}${snum} 秒 <i id="heartbeat" class='fas fa-heartbeat'></i></div>`),
    document.getElementById("workboard") &&
    (document.getElementById("workboard").innerHTML = currentTimeHtml);
    }
    // 设置重复执行函数,周期1000ms
    setInterval(() => {
    createtime();
    }, 1000);
/* 页脚心跳 css 动画 */
@keyframes iconAnimate {
0%,
100% {
transform: scale(0.9);
/* 动画开始和结束时图标保持原始大小 */
}
15% {
transform: scale(1.3);
/* 快速跳动到较大大小 */
}
30% {
transform: scale(0.9);
/* 返回原始大小 */
}
45%,
60% {
transform: scale(1.1);
/* 较小的第二次跳动 */
}
70% {
transform: scale(0.9);
/* 再次返回原始大小 */
}
}

#heartbeat {
color: red;
animation: iconAnimate 1.5s cubic-bezier(0.5, 0.1, 0.1, 1) infinite;
}

右侧滚动条

点击查看步骤
  • 将 themes\butterfly\source\css_global\index.styl 进行修改
    // 在 54 行左右,去掉掉原有的滚动条样式
    // scrollbar - chrome/safari
    -*::-webkit-scrollbar
    - width: 5px
    - height: 5px

    -*::-webkit-scrollbar-thumb
    - background: var(--scrollbar-color)

    -*::-webkit-scrollbar-track
    - background-color: transparent

    // scrollbar - firefox
    -*
    - scrollbar-width: thin
    - scrollbar-color: var(--scrollbar-color) transparent
  • 在自己的 css 文件中写入新的滚动条样式
    /* 滚动条 */
    ::-webkit-scrollbar {
    width: 8px;
    height: 8px;
    }
    ::-webkit-scrollbar-track {
    background-color: rgba(73, 177, 245, 0.2);
    /* border-radius: 2em; */
    }
    ::-webkit-scrollbar-thumb {
    background-color: #49b1f5;
    background-image: -webkit-linear-gradient(45deg,
    rgba(255, 255, 255, 0.4) 25%,
    transparent 25%,
    transparent 50%,
    rgba(255, 255, 255, 0.4) 50%,
    rgba(255, 255, 255, 0.4) 75%,
    transparent 75%,
    transparent);
    /* border-radius: 2em; */
    }
    ::-webkit-scrollbar-corner {
    background-color: transparent;
    }
    ::-moz-selection {
    color: #fff;
    background-color: #49b1f5;
    }

代码块样式调整

点击查看步骤
  • \themes\butterfly\source\css\_highlight\theme.styl 中,调整对应的 $highlight-addition = #4CAF50

头图模糊效果

点击查看步骤
  • 有些压缩过后的头图颗粒感非常明显,打算通过模糊进行处理,在自身的 css 文件中添加如下代码
    /* 对背景图应用模糊效果,此处不模糊主页的头图 */
    #footer::before,
    #page-header:not(.full_page):before {
    backdrop-filter: blur(5px);
    }

gulp 压缩静态资源

点击查看参考教程
点击查看步骤

直接照着参考教程进行的魔改

lazyload(未使用)

点击查看参考教程

字体魔改(未使用)

点击查看参考教程

文章加密(未使用)

点击查看参考教程

顶部加载条(弃用)

点击查看参考教程
点击查看步骤

已经在 loading 加载动画中实现

底部备案号(弃用)

点击查看参考教程
点击查看步骤

在页脚徽标中实现

  • 改为使用页脚徽标后,同样在 footer.pug 中修改,参考本文的页脚徽标部分

顶部天气小组件(弃用)

点击查看参考教程
点击查看步骤

发现只会在页面初次加载中生成,可能和修改了导航栏有关,遂弃用,改用侧边栏的天气卡片

  • 前往和风天气开发平台,创建天气简约插件,调整好样式后,点击最下面的生成代码,这里需要登录或者注册账号
  • \themes\butterfly\source\js 下创建 weather.js 文件,将生成的代码粘贴进去
    // 本小站的插件样式代码
    WIDGET = {
    "CONFIG": {
    "modules": "201",//改变显示顺序的012是温度、城市、图标
    "background": "5",
    "tmpColor": "9ecbff",
    "tmpSize": "17",
    "cityColor": "9ecbff",
    "citySize": "17",
    "aqiColor": "9ecbff",
    "aqiSize": "17",
    "weatherIconSize": "24",
    "alertIconSize": "18",
    "padding": "14px 10px 10px 10px",
    "shadow": "1",
    "language": "zh",
    "borderRadius": "10",
    "fixed": "false",
    "vertical": "top",
    "horizontal": "left",
    "key": "..." // 此处需要填写自己的和风天气 key
    }
    }
  • 在主题配置文件 _config.butterfly.yml 中的 injectbottom 中引入 weather.js 文件
    - <script async src="/js/weather.js"></script>  # 天气插件
    - <script async src="https://widget.qweather.net/simple/static/js/he-simple-common.js?v=2.0"></script> # 天气插件官方js
  • themes\butterfly\layout\includes\header 文件夹下的 nav.pug 文件中添加天气插件的位置
    nav#nav
    span#blog-info
    a(href=url_for('/') title=config.title)
    if theme.nav.logo
    img.site-icon(src=url_for(theme.nav.logo))
    if theme.nav.display_title
    span.site-name=config.title
    + #he-plugin-simple
    #menus
  • 此时保存后,重新部署,就可以看到天气插件了

相关资源帖

感谢大佬们的帖子