Hexo NexT主題側(cè)邊欄展示相關(guān)文章

原文載于:Hexo NexT主題側(cè)邊欄展示相關(guān)文章


Hexo的NexT主題展示相關(guān)文章和熱門文章使用 hexo-related-popular-posts 插件骨杂,但hexo-related-popular-posts 默認(rèn)展示位置是在頁面底部稠肘,而頁面底部本身內(nèi)容較多迎变,多數(shù)人注意不到相關(guān)文章。因此痢掠,考慮將相關(guān)文章展示在側(cè)邊欄回论。

初始想法是將相關(guān)文章新建一個與目錄塊平齊的相關(guān)文章塊振诬,隨著頁面的滾動椭员,目錄吸附在頁面頂部露乏,相關(guān)文章塊展示在目錄塊下方碧浊。無奈前端了解不多,試了下覺得難度系數(shù)略高瘟仿。取了個折衷方案箱锐,將相關(guān)文章與目錄顯示在同一div中。

概覽

效果圖

話不多說劳较,可在原地址看效果: https://finisky.github.io/2019/12/05/sidebarrelatedposts/

側(cè)邊欄相關(guān)文章:


側(cè)邊欄相關(guān)文章

原來的側(cè)邊欄:


原始的目錄

實現(xiàn)原則

  • 修改盡量小驹止,不對Hexo和NexT源碼改動太多,添加新文件少改老文件观蜗,以免今后升級困難
  • 復(fù)用hexo-related-popular-posts的相關(guān)文章處理邏輯
  • 風(fēng)格與主題保持一致

所有改動一覽

修改改三個文件臊恋,新增兩個文件:

~/finisky/themes/next/layout$ git status
On branch related
Changes not staged for commit:
  (use "git add <file>..." to update what will be committed)
  (use "git checkout -- <file>..." to discard changes in working directory)

        modified:   _macro/post.swig
        modified:   _macro/sidebar.swig
        modified:   ../source/css/_common/outline/sidebar/sidebar.styl

Untracked files:
  (use "git add <file>..." to include in what will be committed)

        _partials/post/post-related-sidebar.swig
        ../source/css/_common/outline/sidebar/sidebar-related.styl

獲取相關(guān)文章數(shù)據(jù)

復(fù)用hexo-related-popular-posts計算出來的相關(guān)文章數(shù)據(jù)即可,源碼在_partials/post/post-related.swig (隱去無關(guān)內(nèi)容):

{%- set popular_posts = popular_posts_json(theme.related_posts.params, page) %}
{%- if popular_posts.json and popular_posts.json.length > 0 %}
  <div class="popular-posts-header">{{ theme.related_posts.title or __('post.related_posts') }}</div>
  <ul class="popular-posts">
  {%- for popular_post in popular_posts.json %}
...
      <div class="popular-posts-title"><a href="{{ popular_post.path }}" rel="bookmark">{{ popular_post.title }}</a></div>
      {%- if popular_post.excerpt and popular_post.excerpt != '' %}
        <div class="popular-posts-excerpt"><p>{{ popular_post.excerpt }}</p></div>
      {%- endif %}
    </li>
  {%- endfor %}
  </ul>
{%- endif %}

顯然墓捻,可以通過popular_posts這個變量訪問到相關(guān)文章數(shù)據(jù)抖仅。

從側(cè)邊欄模板開始

看下前端代碼,可以找到Table of Contents的模板在themes/next/layout/_macro/sidebar.swig中砖第。該文件定義了整個側(cè)邊欄:

<aside class="sidebar">
  <div class="sidebar-inner">

    {%- set display_toc = page.toc.enable and display_toc %}
    {%- if display_toc %}
      {%- set toc = toc(page.content, { "class": "nav", list_number: page.toc.number, max_depth: page.toc.max_depth }) %}
      {%- set display_toc = toc.length > 1 and display_toc %}
    {%- endif %}

    <ul class="sidebar-nav motion-element">
      <li class="sidebar-nav-toc">
        {{ __('sidebar.toc') }}
      </li>
      <li class="sidebar-nav-overview">
        {{ __('sidebar.overview') }}
      </li>
    </ul>

    <!--noindex-->
    <div class="post-toc-wrap sidebar-panel">
      {%- if display_toc %}
        <div class="post-toc motion-element">{{ toc }}</div>
      {%- endif %}
    </div>
    <!--/noindex-->

    <div class="site-overview-wrap sidebar-panel">
      {{ partial('_partials/sidebar/site-overview.swig', {}, {cache: theme.cache.enable}) }}

      {{- next_inject('sidebar') }}
    </div>

    {%- if theme.back2top.enable and theme.back2top.sidebar %}
      <div class="back-to-top motion-element">
        <i class="fa fa-arrow-up"></i>
        <span>0%</span>
      </div>
    {%- endif %}

  </div>
</aside>

看起來實現(xiàn)并不復(fù)雜撤卢,copy下Table of Contents的div,只把內(nèi)容修改成popular_posts即可梧兼。實驗了下發(fā)現(xiàn)naive了放吩,這樣修改頁面渲染會出問題,js報錯羽杰,頁面展示異常渡紫。想到應(yīng)該是js修改了這些元素的內(nèi)容,驗證:

~/finisky/themes/next$ grep -r "post-toc" .
...
./source/js/utils.js:    const navItems = document.querySelectorAll('.post-toc li');
./source/js/utils.js:    var tocElement = document.querySelector('.post-toc-wrap');
./source/js/utils.js:      document.querySelectorAll('.post-toc .active').forEach(element => {
./source/js/utils.js:      while (!parent.matches('.post-toc')) {
./source/js/utils.js:    document.querySelector('.post-toc-wrap').style.maxHeight = sidebarWrapperHeight;
./source/js/utils.js:    var hasTOC = document.querySelector('.post-toc');

可見utils.js會獲取class為"post-toc"的元素并操作考赛,會引發(fā)上述錯誤腻惠。

我們僅需要復(fù)用TOC的css顯示風(fēng)格,不會用到j(luò)s的這些動態(tài)操作欲虚。同時集灌,我們不希望改變原有的邏輯。綜上复哆,比較好的實現(xiàn)方式是copy下TOC的css欣喧,在此基礎(chǔ)上修改成相關(guān)文章的css style。

添加css: sidebar-related.styl

搜索找到toc的css文件在:themes/next/source/css/_common/outline/sidebar/sidebar-toc.styl文件中梯找。添加新的sidebar-related.styl在此目錄中:

.sidebar-related {
  font-size: $font-size-small;

  ol {
    list-style-type: disc;
    margin: 0;
    padding: 0 2px 5px 25px;
    text-align: left;
  }
}

.sidebar-related-title {
  margin-top: 20px;
  padding-left: 0;

  li {
    border-bottom-color: $sidebar-highlight;
    color: $sidebar-highlight;
    border-bottom: 1px solid;
    cursor: pointer;
    display: inline-block;
    font-size: $font-size-small;
  }
}

上面這個小css文件也頗費了些周折唆阿,把無用的style去掉,調(diào)整margin和padding和list-style-type锈锤。當(dāng)然驯鳖,也可改成自己喜歡的樣式闲询,不一定強求與原主題一致。

修改css: sidebar.styl

還要將新加的文件import到themes/next/source/css/_common/outline/sidebar/sidebar.styl中浅辙,添加一行扭弧,修改如下:

...
 @import 'sidebar-toc' if (hexo-config('toc.enable'));
+@import 'sidebar-related' if (hexo-config('toc.enable'));

 @import 'site-state' if (hexo-config('site_state'));
...

添加側(cè)邊欄列表: post-related-sidebar.swig

在themes/next/layout/_partials/post/文件夾中添加post-related-sidebar.swig:

{%- set popular_posts = popular_posts_json(theme.related_posts.params, page) %}
{%- if page.toc.enable and theme.related_posts.enable and (theme.related_posts.display_in_home or not is_index) and popular_posts.json and popular_posts.json.length > 0 %}
<div>
  <ul class="sidebar-related-title">
    <li>
      {{ theme.related_posts.title or __('post.related_posts') }}
    </li>
  </ul>

  <!--noindex-->
  <div class="sidebar-related">
    <ol>
      {%- for popular_post in popular_posts.json %}
      <li><a href="{{ popular_post.path }}" rel="bookmark"><span class="nav-text">{{ popular_post.title }}</span></a></li>
      {%- endfor %}
    </ol>
  </div>
  <!--/noindex-->
</div>
{%- endif %}

此處用到了前面定義的兩個css style: sidebar-related-title和sidebar-related。同時用popular_posts變量輸出了超鏈接和文章標(biāo)題记舆。

只有在啟用了TOC和相關(guān)文章鸽捻,且相關(guān)文章有內(nèi)容的情況下才在側(cè)邊欄顯示。

修改側(cè)邊欄: sidebar.swig

萬事俱備泽腮,改一下側(cè)邊欄的文件:themes/next/layout/_macro/sidebar.swig御蒲,僅添加三行,把原始的TOC外面包一層div诊赊,再引用前文寫好的post-related-sidebar.swig即可:

@@ -8,6 +8,7 @@
   <aside class="sidebar">
     <div class="sidebar-inner">

+      <div>
       {%- set display_toc = page.toc.enable and display_toc %}
       {%- if display_toc %}
         {%- set toc = toc(page.content, { "class": "nav", list_number: page.toc.number, max_depth: page.toc.max_depth }) %}
@@ -36,6 +37,9 @@

         {{- next_inject('sidebar') }}
       </div>
+      </div>
+      {{ partial('_partials/post/post-related-sidebar.swig') }}

       {%- if theme.back2top.enable and theme.back2top.sidebar %}
         <div class="back-to-top motion-element">

完整sidebar.swig如下:

{% macro render(display_toc) %}
  <div class="toggle sidebar-toggle">
    <span class="toggle-line toggle-line-first"></span>
    <span class="toggle-line toggle-line-middle"></span>
    <span class="toggle-line toggle-line-last"></span>
  </div>

  <aside class="sidebar">
    <div class="sidebar-inner">

      <div>
      {%- set display_toc = page.toc.enable and display_toc %}
      {%- if display_toc %}
        {%- set toc = toc(page.content, { "class": "nav", list_number: page.toc.number, max_depth: page.toc.max_depth }) %}
        {%- set display_toc = toc.length > 1 and display_toc %}
      {%- endif %}

      <ul class="sidebar-nav motion-element">
        <li class="sidebar-nav-toc">
          {{ __('sidebar.toc') }}
        </li>
        <li class="sidebar-nav-overview">
          {{ __('sidebar.overview') }}
        </li>
      </ul>

      <!--noindex-->
      <div class="post-toc-wrap sidebar-panel">
        {%- if display_toc %}
          <div class="post-toc motion-element">{{ toc }}</div>
        {%- endif %}
      </div>
      <!--/noindex-->

      <div class="site-overview-wrap sidebar-panel">
        {{ partial('_partials/sidebar/site-overview.swig', {}, {cache: theme.cache.enable}) }}

        {{- next_inject('sidebar') }}
      </div>
      </div>

      {{ partial('_partials/post/post-related-sidebar.swig') }}

      {%- if theme.back2top.enable and theme.back2top.sidebar %}
        <div class="back-to-top motion-element">
          <i class="fa fa-arrow-up"></i>
          <span>0%</span>
        </div>
      {%- endif %}

    </div>
  </aside>
  <div id="sidebar-dimmer"></div>
{% endmacro %}

至此厚满,側(cè)邊欄已可顯示相關(guān)文章,還差最后一步碧磅。

去掉文中相關(guān)文章:post.swig

將原始文末顯示的相關(guān)文章去掉痰滋,刪除三行themes/next/layout/_macro/post.swig:

     {### END POST BODY ###}
     {#####################}

-    {%- if theme.related_posts.enable and (theme.related_posts.display_in_home or not is_index) %}
-      {{ partial('_partials/post/post-related.swig') }}
-    {%- endif %}

     {%- if not is_index %}
       {{- next_inject('postBodyEnd') }}

大功告成~

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市续崖,隨后出現(xiàn)的幾起案子敲街,更是在濱河造成了極大的恐慌,老刑警劉巖严望,帶你破解...
    沈念sama閱讀 219,427評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件多艇,死亡現(xiàn)場離奇詭異,居然都是意外死亡像吻,警方通過查閱死者的電腦和手機峻黍,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,551評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來拨匆,“玉大人姆涩,你說我怎么就攤上這事〔衙浚” “怎么了骨饿?”我有些...
    開封第一講書人閱讀 165,747評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長台腥。 經(jīng)常有香客問我宏赘,道長,這世上最難降的妖魔是什么黎侈? 我笑而不...
    開封第一講書人閱讀 58,939評論 1 295
  • 正文 為了忘掉前任察署,我火速辦了婚禮,結(jié)果婚禮上峻汉,老公的妹妹穿的比我還像新娘贴汪。我一直安慰自己脐往,他們只是感情好,可當(dāng)我...
    茶點故事閱讀 67,955評論 6 392
  • 文/花漫 我一把揭開白布扳埂。 她就那樣靜靜地躺著业簿,像睡著了一般。 火紅的嫁衣襯著肌膚如雪聂喇。 梳的紋絲不亂的頭發(fā)上辖源,一...
    開封第一講書人閱讀 51,737評論 1 305
  • 那天蔚携,我揣著相機與錄音希太,去河邊找鬼。 笑死酝蜒,一個胖子當(dāng)著我的面吹牛誊辉,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播亡脑,決...
    沈念sama閱讀 40,448評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼堕澄,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了霉咨?” 一聲冷哼從身側(cè)響起蛙紫,我...
    開封第一講書人閱讀 39,352評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎途戒,沒想到半個月后坑傅,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,834評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡喷斋,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,992評論 3 338
  • 正文 我和宋清朗相戀三年唁毒,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片星爪。...
    茶點故事閱讀 40,133評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡浆西,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出顽腾,到底是詐尸還是另有隱情近零,我是刑警寧澤,帶...
    沈念sama閱讀 35,815評論 5 346
  • 正文 年R本政府宣布抄肖,位于F島的核電站秒赤,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏憎瘸。R本人自食惡果不足惜入篮,卻給世界環(huán)境...
    茶點故事閱讀 41,477評論 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望幌甘。 院中可真熱鬧潮售,春花似錦痊项、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,022評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至肮帐,卻和暖如春咖驮,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背训枢。 一陣腳步聲響...
    開封第一講書人閱讀 33,147評論 1 272
  • 我被黑心中介騙來泰國打工托修, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人恒界。 一個月前我還...
    沈念sama閱讀 48,398評論 3 373
  • 正文 我出身青樓睦刃,卻偏偏與公主長得像,于是被迫代替她去往敵國和親十酣。 傳聞我的和親對象是個殘疾皇子涩拙,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,077評論 2 355

推薦閱讀更多精彩內(nèi)容