淺析 Hexo 搭建部落格的原理

sunshine小小倩發表於2017-08-12

一直在用 Hexo 寫部落格,但是對其原理並不是很清晰,在網上找了一些資料,對 Hexo 有了新的認識,現在就來記錄一下

使用 Hexo + github pages 搭建部落格

記得剛開始知道 Hexo + github pages 搭建部落格是在 2016 年,那時候,閨蜜非常激動的給我說自己建了一個部落格,然後給我發過來了一個地址,我開啟之後感覺她技術好牛逼啊,這都可以做到(因為潛意識中,建立一個網址是需要很複雜的過程的,並且要讓別人通過地址訪問也是一個很麻煩甚至覺得很花錢的一件事情)。

然後她給我說很簡單,是用 Hexo + github pages 搭建的,當時是一臉懵逼啊,然後百度了一下,發現很多人都在使用 Hexo + github pages 搭建部落格。

拖延症的我又過了幾個月才開始按照網上的教程一步一步的建立自己的部落格。

github 的 pages 服務

開始只是按照網上的教程一步一步跟著做,將專案原始碼託管在 github 上,使用 github 的 pages 服務。其實 github 的 pages 服務不只是可以展示部落格,你的每一個 github 倉庫都有 pages 服務,可以通過簡單的設定通過專案的 index.html 為入口展示你的專案,這一點也很實用啊有木有!但是大部分的 pages 服務都是用來搭建個人部落格的。

例如,我之前的 canvasStar 的專案,我將原始碼上傳到了 github 上,然後如下設定:

pages服務第一步
pages服務第一步

pages服務第二步
pages服務第二步

github pages支援靜態頁面的解析

然後你就可以通過圖中紅色框框圈出的地址來訪問。

coding 的 pages 服務

在初創部落格的時候,是將程式碼放在 github 上,然後通過 pages 訪問,然後瞭解到國內訪問 github 速度還是慢一些,並且 github 不會被百度收錄,不利於 SEO,所以又將程式碼託管到了 coding 上,coding 也有類似的 pages 服務。也用了一段時間,但是 coding 現在不升級為會員開啟有廣告。於是就自己買了個虛擬主機,將程式碼直接放在了虛擬主機上。

為什麼使用 Hexo + github pages 搭建部落格

Hexo 是用來生成 HTML 的,github pages 用來展示 HTML(根據上面的介紹,我們可以理解我們還可以使用 coding 的 pages 服務,如果自己有伺服器的話,可以上傳到自己的伺服器)。

Hexo

使用 Hexo + github pages 搭建部落格,剛剛我們簡單介紹了 github pages,那麼現在我們就該介紹一下 Hexo,我們瞭解到 Hexo 是用來生成 HTML 的,那麼這篇文章我們就主要來講一下 Hexo 是怎樣生成 HTML 的。

什麼是 Hexo

hexo官網
hexo官網

在 Hexo 的官網,我們可以直觀的看到對 Hexo 的介紹:快速、簡潔且高效的部落格框架

在 Hexo 的文件中,我們可以找到官方對 Hexo 的定義:

Hexo 是一個快速、簡潔且高效的部落格框架。Hexo 使用 Markdown(或其他渲染引擎)解析文章,在幾秒內,即可利用靚麗的主題生成靜態網頁。

在官方文件中安裝了 Hexo 中我們就安裝了 Hexo,然後我們就可以看到文件結構如下:

.
├── _config.yml      // 站點配置檔案
├── db.json          // 快取檔案
├── node_modules     // 安裝的外掛以及hexo所需的一些nodejs模組
├── package.json     // 專案的依賴檔案
├── scaffolds        // 模版檔案
├── source           // 原始檔,用來存放你的文章 md 檔案
└── themes           // 主題檔案複製程式碼

然後我們可以安裝主題,比我我安裝的 NexT 主題,安裝完之後會在 themes 下面產生一個 next 檔案存放主題中的內容,文件結構如下:

.
├── LICENSE
├── README.en.md       // READEME 英文版
├── README.md          // READEME 中文檔案
├── _config.yml        // 主題配置檔案
├── bower.json
├── gulpfile.coffee
├── languages         // 多語言配置檔案
├── layout            // 模板檔案
├── package.json      // 專案的依賴檔案
├── scripts           // 主題的指令碼檔案
├── source            // 主題的資原始檔 CSS IMG
└── test複製程式碼

Hexo 的工作原理

這裡我們來分析一下 Hexo 每次部署的流程

  1. hexo g:生成靜態檔案。將我們的資料和介面相結合生成靜態檔案的過程。會遍歷主題檔案中的 source 資料夾(js、css、img 等靜態資源),然後建立索引,然後根據索引生成 pubild 資料夾中,此時的 publid 檔案是由 html、 js、css、img 建立的純靜態檔案可以通過 index.html 作為入口訪問你的部落格。
  2. hexo d:部署檔案。部署主要是根據在 _config.yml 中配置的 git 倉庫或者 coding 的地址,將 public 檔案上傳至 github 或者 coding 中。然後再根據上面的 github 提供的 pages 服務呈現出頁面。當然你也可以直接將你生成的 public 檔案上傳至你自己的伺服器上。

Hexo 的模板引擎

模板引擎的作用,就是將介面與資料分離。最簡單的原理是將模板內容中指定的地方替換成資料,實現業務程式碼與邏輯程式碼分離。

我們可以注意到,在 Hexo 中,source 資料夾和 themes 資料夾是在同級的,我們就可以將 source 資料夾理解為資料庫,而主題資料夾相當於 介面。然後我們 hexo g 就將我們的資料和介面相結合生成靜態檔案 public

Hexo 的模板引擎是預設使用 ejs 編寫的。hexo首先會解析 md 檔案,然後根據 layout 判斷佈局型別,再呼叫其他的檔案,這樣每一塊的內容都是獨立的,提高程式碼的複用性。最終會生成一個 html 頁面。

模板檔案在 layout 資料夾下,layout 檔案文件結構如下:

.
├── _custom                           // 通用佈局
├── _layout.swig                      // 預設佈局佈局
├── _macro                            // 外掛模板
├── _partials                         // 區域性佈局
├── _scripts                          // script模板
├── _third-party                      // 第三方外掛模板
├── archive.swig                      // 歸檔模板
├── category.swig                     // 分類别範本
├── index.swig                        // 首頁模板
├── page.swig                         // 其他模板
├── photo.swig                        // 照片模板(自定義)
├── post.swig                         // 文章模板
├── schedule.swig                     // 歸檔模板
└── tag.swig                          // 標籤模板複製程式碼

每個模板都預設使用layout佈局,您可在文章的前置申明中指定其他佈局,比如“post”或者“page”或是設為false來關閉佈局功能(如果不填預設是post,這個在_config.yml中可以設定預設值),您甚至可在佈局中再使用其他佈局來建立巢狀佈局。

在我們新建頁面或者新建文章的使用可以選定我們使用的模板。hexo new [layout] <title>就會使用對應的模板。

其中 _layout.swig 是通用模板,裡面引入了 headfooter 等公共元件,然後在其他的模板中會引入這個 _layout.swig 通用模板,比如 post.swig 模板

{% extends '_layout.swig' %}
{% import '_macro/post.swig' as post_template %}
{% import '_macro/sidebar.swig' as sidebar_template %}


{% block title %} {{ page.title }} | {{ config.title }} {% endblock %}

{% block page_class %}page-post-detail{% endblock %}


{% block content %}

  <div id="posts" class="posts-expand">
    {{ post_template.render(page) }}

    <div class="post-spread">
      {% if theme.jiathis %}
        {% include '_partials/share/jiathis.swig' %}
      {% elseif theme.baidushare %}
        {% include '_partials/share/baidushare.swig' %}
      {% elseif theme.add_this_id %}
        {% include '_partials/share/add-this.swig' %}
      {% elseif theme.duoshuo_shortname and theme.duoshuo_share %}
        {% include '_partials/share/duoshuo_share.swig' %}
      {% endif %}
    </div>
  </div>

{% endblock %}

{% block sidebar %}
  {{ sidebar_template.render(true) }}
{% endblock %}


{% block script_extra %}
  {% include '_scripts/pages/post-details.swig' %}
{% endblock %}複製程式碼

其中在第 11 行

{% block content %} 
    // 中間為該模板自定義內容
{% endblock %}複製程式碼

資料的填充

資料的填充主要是 hexo -g 的時候將資料傳遞給 swig 模板,然後再由 swig 模板填充到 HTML 中。

配置檔案中的資料

Hexo 的配置檔案 _config.yml 使用 yml語法 。例如部落格的名字、副標題等等之類。這些資料項組織在 config 物件中。可以數字、字串、物件、陣列,

配置檔案中資料的使用

如果要在模板中使用某個具體的值,比如字串、數字、邏輯變數或者物件的某個成員,可以在主題的模板檔案 swig 中直接使用:

{% block title %} {{ page.title }} | {{ config.title }} {% endblock %}複製程式碼

Hexo 中的變數

Hexo 提供了很多的變數,比如我們上面使用的 page 變數,還有 site 變數等,這些都是 Hexo 提供的,我們可以拿來直接使用的,常用的變數有:

  • site:對應整個網站的變數,一般會用到 site.posts.length 製作分頁器。
    • site.posts 所有文章
    • site.pages 所有分頁
    • site.categories 所有分類
    • site.tags 所有標籤
  • page:存放當前頁面的資訊,例如我在 index.ejs 中使用 page.posts 獲取了當前頁面的所有文章而不是使用 site.posts
  • configconfig 變數我們在主目錄下配置檔案 _config.yml 中儲存的資訊。
  • themetheme 變數是我們在主題目錄下配置檔案 _config.yml 中儲存的資訊。
  • path:當前頁面的路徑(不含根路徑)。
  • url:頁面完整網址。

頁面變數

Page(page) 這裡指的是 hexo new page 建立的那個頁面

  • page.title:文章標題
  • page.date:文章建立日期
  • page.updated:文章更新日期
  • page.comments:留言是否開啟
  • page.layout:佈局名稱
  • page.content:文章完整內容
  • page.excerpt:文章摘要
  • page.more:除了摘要的其他內容
  • page.source:文章原始路勁
  • page.full_source:文章完整原始路徑
  • page.path:文章網址(不含根路徑),通常在主題中使用url_for(page.path)
  • page.permalink:文章永久網址
  • page.prev:上一篇文章,如果此為第一篇文章則為null
  • page.next:下一篇文章,如果此為最後一篇文章則為null
  • page.raw:文章原始內容
  • page.photos:文章的照片(用於相簿)
  • page.link:文章的外鏈(用於連結文章)

Post(post) 變數

這裡指的是文章頁面,與page佈局相同,新增如下變數:

  • page.pulished:文章非草稿為true
  • page.categories:文章分類
  • page.tags:文章標籤

首頁(index)

  • page.per_page:每一頁顯示的文章數
  • page.total:文章數量
  • page.current:當前頁碼
  • page.current_url:當前頁的URL
  • page.posts:當前頁的文章
  • page.prev:前一頁頁碼,如果為第一頁,該值為0
  • page.prev_link:前一頁URL,如果為第一頁,則為''
  • page.next:後一頁頁碼,如果為最後一頁,則為0
  • page.next_link:後一頁URL,如果為最後一頁,則為''
  • page.path:當前頁網址(不含根路徑),通常在主題中使用url_for(page.path)

歸檔頁(archive)

與index佈局相同,但是新增如下變數:

  • archive 為true
  • year 歸檔年份(4位)
  • month 歸檔月份(不包含0)

總結

非要說 Hexo 是什麼的話,我覺得就是生成靜態頁面的工具,可以將我們使用 markdown 編寫的內容與主題模板相結合,生成 HTML 靜態檔案。並且可以和 github 的 pages 或者其他可以將靜態頁面展現出來的服務(例如 coding 的 pages 服務)相結合,一鍵部署。

再深入一點講 Hexo 的原理的話,那就應該是使用 yaml 語言 做配置檔案,使用 ejs 或者 swig 作為主題模板,與使用 markdown 書寫的內容結合,生成靜態 HTML 檔案。

參考文獻:

相關文章