点开查看开发记录

开发记录

2020-12-01:内测版v0.06

  1. 完成pug改写。
  2. 新版友链沿用Volantis主题的Site-card样式。
  3. 添加判断机制,保留原版友链,通过修改配置文件切换友链样式风格。

2020-12-02:正式版v1.02

  1. 移植Volantis的issues标签。实现站点友链更新。
  2. 参考小康大佬的基于Gitee的友链创建方案,实现站点友链更新。

2020-12-04:正式版v1.03

  1. 更新了issues仓库对应配置方案。Volantis文档还是不够完善
  2. 简化配置方案,覆盖安装即可。
  3. 添加了卓越科技的教程帖推荐。

2021-01-17:正式版v1.04

  1. 新增flexcard样式。

2021-01-18:正式版v1.041

  1. 微调头像显示位置,改为px绝对大小。避免因为字体或者页面关系导致的错位。
  2. 感谢@Nesxc反馈的bug。

2021-01-31:正式版v1.05

  1. 紧急修复,适配butterfly_v3.6.0,微调了flexcard的悬停内容显示位置。

2021-01-31:正式版v1.06

  1. 适配butterfly_v3.6.1发布,修复了fixed定位失效问题。移除紧急修复修改内容。

2021-02-04:正式版v1.07

  1. 新增默认站点截图,siteshot配置项留空的情况下,使用thum.io提供的API自动截图。修改flink.pug
    • volantis样式:
        .img
      + - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
      if theme.lazyload.enable
      - img(data-lazy-src=url_for(item.siteshot) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
      + img(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
      else
      - img(src=url_for(item.siteshot) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
      + img(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    • flexcard样式:
        .wrapper.cover
      + - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link
      if theme.lazyload.enable
      - img.cover.fadeIn(data-lazy-src=url_for(item.siteshot) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
      + img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
      else
      - img.cover.fadeIn(src=url_for(item.siteshot) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
      + img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )

2021-02-07:正式版v1.061

  1. 追加可能出现的BUG解决方案,针对flexcard风格提供适配样式表

2021-03-23:正式版v1.062

  1. 追加可能出现的BUG解决方案,修复对gallery标签的影响。
  2. 新增提示语,最新版已经不需要半自动截图项目。
点开查看参考内容

思路解读

Butterfly的友链太过单调了。加上之前正好移植了Volantis的一堆外挂标签样式,突发奇想用Site-card来写友链,效果相当理想。

资源下载

由于本教程涉及的所有修改对缩进格式等有严格要求,担心自己控制不好的可以直接下载静态资源。比照教程进行复制。

魔改步骤

  1. 新建友链页面。已开的可以跳过,从第2步开始.
    参照参考教程中的Butterfly友链界面配置教程先配置好默认友链页面。

    • 在Hexo博客根目录[Blogroot]下打开终端,输入hexo new page link

      hexo new page link
    • 打开[Blogroot]\source\link\index.md,添加一行type: 'link':

      ---
      title: link
      date: 2020-12-01 22:19:45
      type: 'link'
      ---
    • 新建文件[Blogroot]\source\_data\link.yml,没有_data文件夹的话也请自己新建。以下是默认友链格式示例(自己写的教程,夹带点私货不过分吧,嘻嘻)。打开[Blogroot]\source\_data\link.yml,输入:

      - class_name: 糖果屋のVIP
      class_desc: 售后服务享五折优惠2333
      link_list:
      - name: Akilar
      link: https://akilar.top
      avatar: https://akilar.top/img/siteicon/favicon.png
      descr: 欢迎光临糖果屋
    • 取消[Blogroot]\_config.butterfly.ymlmenu配置项内link页面的注释。

      menu:
      Home: / || fas fa-home
      Archives: /archives/ || fas fa-archive
      Tags: /tags/ || fas fa-tags
      Categories: /categories/ || fas fa-folder-open
      # List||fas fa-list:
      # - Music || /music/ || fas fa-music
      # - Movie || /movies/ || fas fa-video
      Link: /link/ || fas fa-link
      # About: /about/ || fas fa-heart
  2. 修改[Blogroot]\themes\butterfly\layout\includes\page\flink.pug,此处添加判断机制,使得可以通过修改配置文件来切换友链风格。

  3. 修改[Blogroot]\themes\butterfly\source\css\_page\flink.styl

    if hexo-config('flink_style') == 'butterfly'
    .flink#article-container
    .flink-desc
    margin: .2rem 0 .5rem

    .flink-list
    overflow: auto
    padding: 10px 10px 0
    text-align: center

    & > .flink-list-item
    position: relative
    float: left
    overflow: hidden
    margin: 15px 7px
    width: calc(100% / 3 - 15px)
    height: 90px
    border-radius: 8px
    line-height: 17px
    -webkit-transform: translateZ(0)

    +maxWidth1024()
    width: calc(50% - 15px) !important

    +maxWidth600()
    width: calc(100% - 15px) !important

    &:hover
    img
    transform: rotate(360deg)

    &:before
    position: absolute
    top: 0
    right: 0
    bottom: 0
    left: 0
    z-index: -1
    background: var(--text-bg-hover)
    content: ''
    transition: transform .3s ease-out
    transform: scale(0)

    &:hover:before,
    &:focus:before,
    &:active:before
    transform: scale(1)

    a
    color: var(--font-color)
    text-decoration: none

    img
    float: left
    margin: 15px 10px
    width: 60px
    height: 60px
    border-radius: 35px
    transition: all .3s

    .img-alt
    display: none

    .flink-item-name
    @extend .limit-one-line
    display: block
    padding: 16px 10px 0 0
    height: 40px
    font-weight: bold
    font-size: 1.43em

    .flink-item-desc
    @extend .limit-one-line
    display: block
    padding: 16px 10px 16px 0
    height: 50px
    font-size: .93em
    else if hexo-config('flink_style') == 'volantis'
    trans($time = 0.28s)
    transition: all $time ease
    -moz-transition: all $time ease
    -webkit-transition: all $time ease
    -o-transition: all $time ease
    .site-card-group
    display: flex
    flex-wrap: wrap
    justify-content: flex-start
    margin: -0.5 * 16px
    align-items: stretch
    .site-card
    margin: 16px * 0.5
    width: "calc(100% / 4 - %s)" % 16px
    @media screen and (min-width: 2048px)
    width: "calc(100% / 5 - %s)" % 16px
    @media screen and (max-width: 768px)
    width: "calc(100% / 3 - %s)" % 16px
    @media screen and (max-width: 500px)
    width: "calc(100% / 2 - %s)" % 16px
    display: block
    line-height: 1.4
    height 100%
    .img
    width: 100%
    height 120px
    @media screen and (max-width: 500px)
    height 100px
    overflow: hidden
    border-radius: 12px * 0.5
    box-shadow: 0 1px 2px 0px rgba(0, 0, 0, 0.2)
    background: #f6f6f6
    img
    width: 100%
    height 100%
    // trans(.75s)
    transition: transform 2s ease
    object-fit: cover

    .info
    margin-top: 16px * 0.5
    img
    width: 32px
    height: 32px
    border-radius: 16px
    float: left
    margin-right: 8px
    margin-top: 2px
    span
    display: block
    .title
    font-weight: 600
    font-size: $fontsize-list
    color: #444
    display: -webkit-box
    -webkit-box-orient: vertical
    overflow: hidden
    -webkit-line-clamp: 1
    trans()
    .desc
    font-size: $fontsize-footnote
    word-wrap: break-word;
    line-height: 1.2
    color: #888
    display: -webkit-box
    -webkit-box-orient: vertical
    overflow: hidden
    -webkit-line-clamp: 2
    .img
    trans()
    &:hover
    .img
    box-shadow: 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 2px 4px 0px rgba(0, 0, 0, 0.1), 0 4px 8px 0px rgba(0, 0, 0, 0.1), 0 8px 16px 0px rgba(0, 0, 0, 0.1)
    .info .title
    color: #ff5722
    else if hexo-config('flink_style') == 'flexcard'
    #article-container img
    margin 0 auto!important
    .flink-list
    overflow auto
    & > a
    width calc(25% - 15px)
    height 130px
    position relative
    display block
    margin 15px 7px
    float left
    overflow hidden
    border-radius 10px
    transition all .3s ease 0s, transform .6s cubic-bezier(.6, .2, .1, 1) 0s
    box-shadow 0 14px 38px rgba(0, 0, 0, .08), 0 3px 8px rgba(0, 0, 0, .06)
    &:hover
    .info
    transform translateY(-100%)
    .wrapper
    img
    transform scale(1.2)
    &:before
    position: fixed
    width:inherit
    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: rgba($theme-color,0.8)
    .cover
    width 100%
    transition transform .5s ease-out
    .wrapper
    position relative
    .fadeIn
    animation coverIn .8s ease-out forwards
    img
    height 130px
    pointer-events none
    .info
    display flex
    flex-direction column
    justify-content center
    align-items center
    width 100%
    height 100%
    overflow hidden
    border-radius 3px
    background-color hsla(0, 0%, 100%, .7)
    transition transform .5s cubic-bezier(.6, .2, .1, 1) 0s
    img
    position relative
    top 22px //因为字体大小不同,可能导致头像偏高,可以在此处通过修改top的值来微调头像框的位置至卡片正中。
    width 66px
    height 66px
    border-radius 50%
    box-shadow 0 0 10px rgba(0, 0, 0, .3)
    z-index 1
    text-align center
    pointer-events none
    span
    padding 20px 10% 60px 10%
    font-size 16px
    width 100%
    text-align center
    box-shadow 0 0 10px rgba(0, 0, 0, .3)
    background-color hsla(0, 0%, 100%, .7)
    color var(--font-color)
    white-space nowrap
    overflow hidden
    text-overflow ellipsis
    .flink-list>a .info,
    .flink-list>a .wrapper .cover
    position absolute
    top 0
    left 0

    @media screen and (max-width:1024px)
    .flink-list
    & > a
    width calc(33.33333% - 15px)

    @media screen and (max-width:600px)
    .flink-list
    & > a
    width calc(50% - 15px)

    [data-theme=dark]
    .flink-list a .info,
    .flink-list a .info span
    background-color rgba(0, 0, 0, .6)
    .flink-list
    & > a
    &:hover
    &:before
    background-color: rgba(#121212,0.8);

  4. 因为Volantis的site-card比Butterfly的flink-card多出了一个站点缩略图,所以需要再额外添加一条配置项。修改[Blogroot]\source\_data\link.yml,添加一条名为siteshot的配置项。

    - class_name: 糖果屋のVIP
    class_desc: 售后服务享五折优惠2333
    link_list:
    - name: Akilar
    link: https://akilar.top
    avatar: https://akilar.top/img/siteicon/favicon.png
    descr: 欢迎光临糖果屋
    siteshot: https://cdn.jsdelivr.net/gh/Akilarlxh/ScreenShot@gh-pages/akilar.top.jpg
    # siteshot就是站点缩略图的链接。
  5. [Blogroot]\_config.butterfly.yml中添加配置项:

    # 友链样式,butterfly为默认样式,volantis为站点卡片样式.flexcard为弹性卡片样式
    flink_style: volantis # butterfly | volantis | flexcard
  6. 站点卡片添加了懒加载和图片失效替换。对应配置项为[Blogroot]\_config.butterfly.yml中的:

    # Replace Broken Images (替換無法顯示的圖片)
    error_img:
    flink: # 头像失效替换图
    post_page: # 站点缩略图
  7. 可能遇到的bug:使用flexcard样式时,因为全站字体大小配置与本站不一致的关系,可能导致友链卡片的头像位置偏移较大。请读者按照flink.styl里的注释内容自己微调。

站点图片批量半自动截图

该项目的本意是为了弥补因为thum.io参数问题导致图片过大,从而加载较慢的问题。先将其保存下来再使用jsdelivr加速。最新版友链已经将thum.io的api内置,且调整了参数,图片大小缩小了将近40倍。也就不是很依赖于jsdelivr加速了。当然若是秉持能快一点是一点原则的用户,还是可以使用的

半自动截图内容非必要

这里使用的是@ChenYFan大佬的项目,通过调用thum.io提供的接口,配合github action再次欢呼,github action真香,自动下载站点截图到github中,再配合jsdelivr+github图床来引用图片。

使用方法

  1. 首先fork项目到自己的github仓库。此处提供两个。一个是原项目。一个是我自己配置过的项目。区别在于我根据thum.io提供的接口文档修改了参数,使得站点截图较小。(用我自己的站点截图作为示例,两者大小是1.2MB:34KB的程度,缩小了将近40倍。当然清晰度也不可同日而语,酌情选择)

  2. 获取Token,(此处直接使用当初为github actions教程准备的配图了)。
    访问Github->头像(右上角)->Settings->Developer Settings->Personal access tokens->generate new token,创建的Token名称随意,但必须勾选repo项。


    token只会显示这一次,之后将无法查看,所以务必保证你已经记录下了Token。之后如果忘记了就只能重新生成重新配置了。

  3. 在你fork的项目仓库设置中,新建secrets。变量名为TOKEN,必须严格大写。

  4. 首先需要clone项目到本地。

    git clone git@github.com:[GithubUsername]/ScreenShot.git

    然后打开项目中的ScreenShot\.github\workflows\get.yml,
    按照示例添加你的友链地址。

    curl https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/https://<YourDomain>/ -o <YourDoamin>.jpg

    记得将curl https://purge.jsdelivr.net/gh/[GithubUsername]/ScreenShot@gh-pages/*.*中的[GithubUsername]改为你自己的github账号名。

    之后每次提交就会自动启动github action,将图片下载到ScreenShotgh-pages分支。并且通过purge.jsdelivr.net刷新缓存。

  5. 最后,在友链配置中,就能用https://cdn.jsdelivr.net/gh/[GithubUsername]/ScreenShot@gh-pages/[friend_link].jpg来引用站点缩略图了。

    - class_name: 糖果屋のVIP
    class_desc: 售后服务享五折优惠2333
    link_list:
    - name: Akilar
    link: https://akilar.top
    avatar: https://akilar.top/img/siteicon/favicon.png
    descr: 欢迎光临糖果屋
    siteshot: https://cdn.jsdelivr.net/gh/Akilarlxh/ScreenShot@gh-pages/akilar.top.jpg # 留空则调用API自动截图
  6. 可能遇到的bug

    • 没有启动github action:请到仓库中找到Action,将其打开。
    • 图片缓存未刷新:purge.jsdelivr.net的强制刷新也是玄学,这种时候只能等待了。或者手动发布release,然后使用版本号。这个是jsdelivr的使用技巧,不多做讨论。

靓仔已经在迫不及待的加我友链了,而靓女还在犹豫要不要再加下我的联系方式。


提交issues自动更新友链

使用issues自动更新友链的实质是借助相应的API读取仓库issues并获取相应的数据,然后用js写到页面上。因为不同的js没法根据配置文件进行主题样式切换,所以请读者自行选择相应的方案。(事实上两种样式是可以共存的,因为通过读取issues写入友链页面的就是完整的HTML语言,只要同时加载flink.styl和site-card.styl的内容,赋予它样式就好。真正没法共存的是通过读取link.yml生成友链页面的部分。)

思路拓展:考虑到自动更新是读取issues,而有一款评论是直接将评论变为issues进行提交。也就是gitalk评论。想必头脑灵活的读者已经有思路了。主要是我自己懒得写了。


更多好帖

  1. @卓越科技基于@小康issues提交友链更新方案和@ChenYFan的博客站点自动截图方案制作。同时还实现了在Butterfly原版友链的基础上新增了鼠标悬停显示站点预览图的功能。

可能出现的BUG

根据Heo的反馈的BUG特性,如果开启了fancybox或者medium_zoom功能,会在页面编译时给img便签强行渲染上fancybox或者medium_zoom的外壳,导致小概率的点击图片放大时,会同时跳转到友链页。(反正我都是正常放大图片,没有跳转的情况。)


解决方案(相对的,友链图片将无法放大,酌情修改):

  1. 关闭fancybox,一劳永逸。
  2. 给友链页的img标签添加禁止点击属性style="pointer-events:none;"。使用内联样式,使得只对友链页生效而不会影响其他页面的fancybox渲染。修改[Blogroot]\themes\butterfly\layout\includes\page\flink.pug

    示例可能不是最新,注意内联样式的添加位置即可。

        if theme.lazyload.enable
    - img(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
    + img(style="pointer-events:none;" data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' )
    else
    img(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    .info
    if theme.lazyload.enable
    - img(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    + img(style="pointer-events:none;" data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )
    else
    img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' )

issues写入友链需要jquery支持,Butterfly_v3.4.0以后实现去jquery化,需要自己添加jquery。还得保证加载顺序在issues.js之前。

    inject:
head:
bottom:
+ - <script src=" https://cdn.jsdelivr.net/npm/jquery@latest/dist/jquery.min.js"></script>
- <script defer src="https://cdn.jsdelivr.net/npm/hexo-theme-volantis@latest/source/js/issues.min.js"></script>

部分读者反馈,在使用flexcard样式的友链时,头像被遮盖半个,无法完全显示。

  1. 主要原因是开启了fancybox,强制给图片套了个壳,导致部分样式被覆写。
  2. 次要原因是对flex的布局适用性较差。

解决方案,修改[Blogroot]\themes\butterfly\source\css\_page\flink.styl中关于flexcard的样式逻辑,使用!important控制权重。

  .info
- display flex
+ display block!important
flex-direction column
justify-content center
align-items center
width 100%
height 100%
overflow hidden
border-radius 3px
background-color hsla(0, 0%, 100%, .7)
transition transform .5s cubic-bezier(.6, .2, .1, 1) 0s
+ .fancybox
+ overflow visible!important
img
position relative
top 22px
width 66px
height 66px
border-radius 50%
box-shadow 0 0 10px rgba(0, 0, 0, .3)
z-index 1
text-align center
pointer-events none
span
+ display block!important
padding 20px 10% 60px 10%
font-size 16px
width 100%
text-align center
box-shadow 0 0 10px rgba(0, 0, 0, .3)
background-color hsla(0, 0%, 100%, .7)
color var(--font-color)
white-space nowrap
overflow hidden
text-overflow ellipsis

部分读者反馈,在使用flexcard样式的友链时,Butterfly的gallery相册样式出现严重偏移。推测是友链样式中某个标签定位重写的作用域没有限制好,导致堆叠样式重构。

紧急修复方案如下:
在自定义样式中加入以下内容:

/*相册页面定位修复*/
a > img, .justified-gallery > div > img,
.justified-gallery > figure > img,
.justified-gallery > a > a > img,
.justified-gallery > div > a > img,
.justified-gallery > figure > a > img,
.justified-gallery > a > svg,
.justified-gallery > div > svg,
.justified-gallery > figure > svg,
.justified-gallery > a > a > svg,
.justified-gallery > div > a > svg,
.justified-gallery > figure > a > svg{
  position:static!important;
}

如果不清楚怎么修改自定义css的读者可以参考站内教程:自定义魔改样式及示例

TO DO

flink.pug魔改,移值Volantis的site-card样式

保留原版友链,通过配置文件切换样式

siteshot站点预览图批量半自动化截图

使用issues,经审批后自动更新友链