点击查看更新记录

更新记录

2021-12-15:正式版v1.0

  1. 重写related_posts.js文件,沿用最新文章的布局
  2. 调整与相关教程的联动内容

思路解析

点击查看思路解析

之前一直没有留意到,butterfly的原生相关推荐版块和其他布局比起来实在是太突兀了(主要是没有圆角),就那么突然的出现在文章和评论区之间,包括我和@贰猹都觉得有必要改动这个(不过贰猹是不要侧栏党),@洪哥的倒是和整个文本融合的不错(是配色效果吗?)。出于我守财的习惯,我通常不会直接删除主题已有的一些功能,那么要怎么处理这个那么大一块的推荐版块呢?
我的做法就是,把它丢到可以自由控制显隐的侧栏里。还能顺便沿用我之前写的SAO UI和手机端侧栏fixed卡片样式。

说干就干,首先,要定位这个侧栏卡片的源码位置,用F12确定了它的class为relatedPosts,然后在主题源码里全局搜索,发现这个居然不是在pug中生成,而是通过一个hexo的helper函数来处理的,也就是butterfly\scripts\helpers\related_post.js,好在写插件的时候已经充分接触过这种情况。
第一步,先在F12里复制整个最新文章侧栏卡片的html源码,然后对这部分源码进行美化处理,得到骨架。

<div class="card-widget card-recent-post">

<div class="item-headline"><i class="fas fa-history"></i><span>最新文章</span>
</div>

<div class="aside-list">

<div class="aside-list-item">

<a class="thumbnail" href="/posts/451ac5f8/" title="Butterfly fixed card widget">
<img src="https://assets.akilar.top/image/cover1.webp" alt="cover" >
</a>
<div class="content">
<a class="title" href="/posts/451ac5f8/" title="Butterfly fixed card widget">Butterfly fixed card widget</a>
<time datetime="2021-12-09T02:03:59.000Z" title="发表于 2021-12-09 10:03:59">2021-12-09</time>
</div>
</div>

</div></div>

到这一步,基本可以发现推荐版块和最新文章版块的要素变量其实差不多,因此可以很轻易的搬过来,这里我还可以直接沿用一部分class名,这样就能继承已有的css样式,省的我费力写UI了。
然后就是找到related_posts.js中关于html代码构建的部分,按照上面分析出的骨架和现有的变量进行拼装就OK了。

魔改步骤

  1. 修改[Blogroot]\themes\butterfly\scripts\helpers\related_post.js,从大概47行开始到70行的部分。
      if (relatedPosts.length > 0) {
    - result += '<div class="relatedPosts">'
    - result += `<div class="headline"><i class="fas fa-thumbs-up fa-fw"></i><span>${headlineLang}</span></div>`
    - result += '<div class="relatedPosts-list">'
    + result += '<div class="card-widget card-recommend-post">'
    + result += `<div class="item-headline"><i class="fas fa-dharmachakra"></i><span>${headlineLang}</span></div>`
    + result += '<div class="aside-list">'
    for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
    const cover =
    relatedPosts[i].cover === false
    ? relatedPosts[i].randomcover
    : relatedPosts[i].cover
    - result += `<div><a href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">`
    - result += `<img class="cover" src="${this.url_for(cover)}" alt="cover">`
    + result += `<div class="aside-list-item">`
    + result += `<a class="thumbnail" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}"><img src="${this.url_for(cover)}" alt="${relatedPosts[i].title}"></a>`
    + result += `<div class="content">`
    + result += `<a class="title" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">${relatedPosts[i].title}</a>`
    if (dateType === 'created') {
    - result += `<div class="content is-center"><div class="date"><i class="far fa-calendar-alt fa-fw"></i> ${this.date(relatedPosts[i].created, hexoConfig.date_format)}</div>`
    + result += `<time datetime="${this.date(relatedPosts[i].created, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].created, hexoConfig.date_format)}">${this.date(relatedPosts[i].created, hexoConfig.date_format)}</time>`
    } else {
    - result += `<div class="content is-center"><div class="date"><i class="fas fa-history fa-fw"></i> ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</div>`
    + result += `<time datetime="${this.date(relatedPosts[i].updated, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}">${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</time>`
    }
    - result += `<div class="title">${relatedPosts[i].title}</div>`
    - result += '</div></a></div>'
    + result += `</div></div>`
    }

    result += '</div></div>'
    return result
    }
    if (relatedPosts.length > 0) {
    result += '<div class="card-widget card-recommend-post">'
    result += `<div class="item-headline"><i class="fas fa-dharmachakra"></i><span>${headlineLang}</span></div>`
    result += '<div class="aside-list">'
    for (let i = 0; i < Math.min(relatedPosts.length, limitNum); i++) {
    const cover =
    relatedPosts[i].cover === false
    ? relatedPosts[i].randomcover
    : relatedPosts[i].cover
    result += `<div class="aside-list-item">`
    result += `<a class="thumbnail" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}"><img src="${this.url_for(cover)}" alt="${relatedPosts[i].title}"></a>`
    result += `<div class="content">`
    result += `<a class="title" href="${this.url_for(relatedPosts[i].path)}" title="${relatedPosts[i].title}">${relatedPosts[i].title}</a>`
    if (dateType === 'created') {
    result += `<time datetime="${this.date(relatedPosts[i].created, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].created, hexoConfig.date_format)}">${this.date(relatedPosts[i].created, hexoConfig.date_format)}</time>`
    } else {
    result += `<time datetime="${this.date(relatedPosts[i].updated, hexoConfig.date_format)}" title="发表于 ${this.date(relatedPosts[i].updated, hexoConfig.date_format)}">${this.date(relatedPosts[i].updated, hexoConfig.date_format)}</time>`
    }
    result += `</div></div>`
    }
    result += '</div></div>'
    return result
    }
  2. 因为原本的版块是在文章下方,而现在我们需要把它改到侧栏。所以需要修改[Blogroot]\themes\butterfly\layout\post.pug大约26行的位置先移除在文章底部的推荐版块。
      if theme.post_pagination
    include includes/pagination.pug
    - if theme.related_post && theme.related_post.enable
    - != related_posts(page,site.posts)

    if page.comments !== false && theme.comments && theme.comments.use
  3. 然后修改[Blogroot]\themes\butterfly\layout\includes\widget\index.pug,这个文件每个版本都长得不太一样,这里仅供参考。因为感觉文章也最新文章和推荐文章同时存在,最新文章就显得有点多余了,所以我把最新文章的侧栏卡片注释了。
    #aside-content.aside-content
    //- post
    if is_post()
    if showToc && theme.toc.style_simple
    .sticky_layout
    include ./card_post_toc.pug
    else
    !=partial('includes/custom/SAO_card_player', {}, {cache:theme.fragment_cache})
    !=partial('includes/widget/card_announcement', {}, {cache:theme.fragment_cache})
    !=partial('includes/widget/card_top_self', {}, {cache:theme.fragment_cache})
    .sticky_layout
    if showToc
    include ./card_post_toc.pug
    + if theme.related_post && theme.related_post.enable
    + != related_posts(page,site.posts)
    - - !=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
    + //- !=partial('includes/widget/card_recent_post', {}, {cache:theme.fragment_cache})
    !=partial('includes/widget/card_ad', {}, {cache:theme.fragment_cache})
  4. 那么如果你还有用到我写的fixed侧栏卡片样式的话,记得也去改下那边的配置项,修改[Blogroot]\_config.butterfly.yml
      #侧栏悬浮卡片控制按钮
    #https://akilar.top/posts/451ac5f8/
    fixed_card_widget:
    enable: true
    page: #页面显示按钮
    - type: class #侧栏卡片选择器类型
    name: card-info #侧栏卡片选择器名称
    index: 0 #侧栏卡片选择器序列
    icon: fas fa-address-book #图标
    title: 用户信息 #悬停显示提示
    - type: class
    name: card-clock
    index: 0
    icon: fas fa-cloud-sun
    title: 电子钟
    - type: class
    name: card-shuo
    index: 0
    icon: fas fa-comments
    title: 碎碎念
    - type: class
    name: card-recent-post
    index: 0
    icon: fas fa-history
    title: 最新文章
    - type: id
    name: card-newest-comments
    index: 0
    icon: fas fa-comment-dots
    title: 最新评论
    - type: class
    name: card-tags
    index: 0
    icon: fas fa-tags
    title: 标签
    - type: class
    name: card-webinfo
    index: 0
    icon: fas fa-chart-line
    title: 网站咨询
    post: #文章页显示按钮
    - type: class
    name: card-info
    index: 0
    icon: fas fa-address-book
    title: 用户信息
    - type: class
    name: card-clock
    index: 0
    icon: fas fa-cloud-sun
    title: 电子钟
    - type: class
    - name: card-recent-post
    + name: card-recommend-post
    index: 0
    - icon: fas fa-history
    + icon: fas fa-dharmachakra
    - title: 最新文章
    + title: 相关推荐
  5. 改动完成后运行hexo clean,hexo generate,hexo server三件套就能看到完成效果了。

此处有必要说明一下,因为改动以后,是将推荐版块放到了侧栏卡片,所以如果要想看到相关推荐侧栏卡片,至少需要满足以下几个条件:

  1. 关闭了style_simple,这样才不至于在文章页只能看到一个目录卡片。
  2. 当前文章有相同tag的文章可推荐。如果没有相同tag的文章,自然不存在可以推荐的内容,也就不会生成相关推荐版块。
  3. 开启了related_post配置项,推荐都没开的话就别指望有相关推荐版块了吧。