製做第一個hexo主題

這裏是我寫的主題toki以及預覽。 歡迎star,個人簡歷,若是您有各廠內推的機會,不妨考慮我,致謝?!css


Hexo是一個知名的靜態博客生成工具,尤爲在github用戶中廣爲人知。hexo的主題能夠自由變換,可是想要找到一個徹底合本身心意的主題彷彿大海撈針。與其不停尋找,不如本身動手製做一個主題,既解決了本身看什麼主題都不合心的問題,還能在其中學習更多知識。 html

這裏是我寫的主題toki以及預覽。若是你以爲這篇文章對你起到了一點做用,歡迎你star或者fork進行進一步的學習,沒必要擔憂難度,由於這也是我第一個hexo主題。git

hexo主題結構

目錄結構以下:github

.
├── _config.yml   
├── layout        
│   └── _partial  
└── source        
    ├── css
    ├── fonts
    └── js

其中config文件是存儲與主題相關的變量,如點贊、評論功能是否開啓,在整個站點下也有一個config文件,它是用來存儲一些和整個站點有關的,好比站點的標題。而並不是全部的hexo主題都支持點贊,因此點贊功能的開啓放在具體的theme下更合適。 瀏覽器

Layout文件夾下存放的是佈局模板文件,能夠用ejs、jade等編寫,裏邊包含index、post等hexo中默認使用的模板,也能夠編寫一個本身額外定義的頁面,好比about頁。對於這些本身額外編寫的模板,須要用戶本身執行hexo new [layout] <title>中聲明layout:about才能夠。_partial子文件夾中存放的是一些能夠服用的組件或者想要細分的部分,如打賞部分、點贊部分,能夠分離出來,使得結構更加清晰明瞭。markdown

Source文件夾下存放的是資源文件,好比css文件,字體文件,圖片文件等。source文件在最後生成的時候會把其中的文件都直接放在根目錄下,因此在文件中引用地址的時候不須要寫source,而是直接寫./css/app.css就能夠。hexo

hexo變量和函數

想要編寫一個hexo模板,咱們在其中一定要添加一些hexo站點下的信息,如網站的title。還有咱們以前提到的主題下也有一個config文件,其中的變量咱們也須要調用。除了以上兩個部分,hexo還提供了一些用來簡化操做的輔助函數。
具體的變量和輔助函數能夠訪問hexo官網。這裏只介紹一些經常使用的。app

變量:函數

  • page.title
  • site.posts
  • page.excerpt

關於整個站點下的config文件須要經過config.xxx來進行調用,對於這個主題的config文件須要經過theme.xxx來調用。而諸如page、site等就是hexo自身的一些變量了。工具

函數:

  • <%- list_categories([options]) %>
  • <%- titlecase(string) %>

模板文件

Hexo已經定義的模板文件有如下幾個:

  • index
  • post
  • page
  • archive
  • category
  • tag

特別的還有一個layout文件,能夠在layout文件中編寫一些公共部分,實如今其餘頁面中的複用,若是你對模板引擎並不瞭解,我建議你先學習相關知識是很是必要的,不過不用太多,花十幾分鍾大概理解一下就能夠。
固然你並不須要都要包括這些模板,只是寫了這些模板文件後,你不須要hexo new它,它也有固定的頁面地址。每一個主題最少能夠只包括一個index頁面便可。可是爲了功能上比較完善,我仍是建議最少編寫index、post、archive這三個頁面。
在hexo中編寫文件,須要選擇一種模板引擎,這裏我使用的ejs,hexo本身提供的ejs的支持,並且理解起來也很容易,沒什麼選擇其餘的理由。固然若是你想要編寫的主題比較龐大,那仍是選擇本身最順手的好。
咱們分別講解index、post、archive的編寫,而後在進行拓展。

layout頁面

這一頁要包含菜單、頁腳聲明。

<!DOCTYPE html>
<html lang="en">
    <head>
        <title><%= config.title %></title>
             <!-- 引入站點的標題-->
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <%- css('./css/app.css') %>
          <!-- 這裏的css 就是一個輔助函數-->
    </head>
    <body>
            <%- partial('_partial/header') %>
            <!-- 引入其餘部分-->
            <main>
                 <%- body %>
                <!-- 這裏會將其餘頁面的內容填充進來組成一個完整的頁面 -->
            </main>
    <%- partial('_partial/footer') %>
    </body>
</html>

index頁面

顯然的,這是咱們進入網站看到的第一個頁面,通常來講,這個頁面要包含最近的文章展現,根據我的喜愛,也能夠添加標籤雲、最新評論等。

<section class="posts">
    <% page.posts.each(function (post) { %>
        <article class="post">
            <h1>
                <a class="title" href="<%- url_for(post.path) %>"> 
                    <%= post.title %> 
                </a>
            </h1>
            <%- partial('_partial/meta',{page:post}) %>
            <div class="content">
                <% if(post.excerpt) {%>
                <%- post.excerpt %>
                <%}  else{ %>
                <%- post.content %>
                <% } %>
            </div>
            <div class="continue">
            <a href="<%- url_for(post.path) %>">
            <%- __('Post.Continue') -%>
            <i class="fa fa-angle-right" aria-hidden="true"></i>
            </a>
            </div>
        </article>
        <% }) %>
</section>
<%- partial('_partial/paginator') %>

這個頁面看起來要複雜了許多。咱們從大到小入手:經過page.posts咱們獲取到了文章列表,對於其中的post,又有title、tag、category等量。content四獲取文章的內容,而excerpt是用來獲取摘要。若是在書寫markdown 文章時加入<!-- more -->那麼在這以前的內容將會被視爲摘要,若是你懶得作,也可使用自動生成摘要的插件。
<%- partial('_partial/meta',{page:post}) %>這段代碼中比layout頁面中的引入要多出了一個參數,這裏是將meta這個頁面中的page都賦值爲post。主要是用來進行參數傳遞做用,這裏是由於meta不只在主頁要用,在文章頁也要使用,而文章頁中咱們時經過page.tags來取得內容的。
<%- __('Post.Continue') -%>這個寫法看起來有些奇怪,它也是一個輔助函數嗎?雖然在hexo的文檔中沒有把它明確爲一個輔助函數,但實際上這確實是一個函數,它的做用是進行站點國際化。聽起來很高大上吧!不過其實實現很簡單,在上述的項目結構中咱們還能夠增長一個language目錄,其中針對每一種語言增長一個yml文件,把須要國際化的量儲存在裏邊,根據整個站點config中的language聲明的語言而進行動態調整。好比,咱們在en.yml 將Continue聲明爲continue,在zh-CN.yml中聲明爲繼續閱讀。
<%- partial('_partial/paginator') %>這裏咱們引入了一個paginator組件,它是用來分頁的,跟普通的分頁不一樣,hexo中分頁的實際工做咱們絲毫沒有涉及,只須要簡單地使用輔助函數就能夠:

<%- paginator({
      prev_text: "&laquo; "+  __('Paginator.Prev'),
      next_text: __('Paginator.Next')+" &raquo;"
  }) %>

post頁面

有了前面兩個頁面的基礎,這裏就不廢話了。

<article class="post">
            <h1>
                <a class="title" href="<%- url_for(page.path) %>"> 
                    <%= page.title %> 
                </a>
            </h1>
<%- partial('_partial/meta') %>
<%- partial('_partial/toc') %>
            <div class="content">
                <%- page.content %>
            </div>
<%- partial('_partial/copyright') %>
</article>

archive頁面

<section class="archive">
  <ul class="post-archive">
    <% var last = 1997 %>
    <% page.posts.each(function (post) { %>
    <% if (last != post.date.year()){ %>
     <span class="year"> <a><%=post.date.year()%></a></span>
      <% last = post.date.year()%>
    <%}%>
      <li class="post-item">
        <span class="date"><%= date(post.date, "MM-DD") %></span>
        <a class="title" href="<%- url_for(post.path) %>"><%= post.title %></a>
      </li>
    <% }) %>
  </ul>
</section>
<%- partial('_partial/paginator') %>

對這個頁面,咱們只講解一下<% var last = 1997 %>,這裏參考了hexo自帶主題landscape的方案。爲了實現按照不一樣年份歸檔,先定義一個很小的年份值,若是之後的年份不一樣於以前的值,那就把last置爲它,而且顯示一個較大的年份塊。

添加樣式

這裏咱們選用的是stylus來書寫css,選擇它的緣由也很簡單,由於hexo自帶。

這裏已經沒什麼須要額外講解的了,css總不會也跟其餘的有不一樣吧。只是請注意,爲了保證你的主題可以被更多人使用,請務必作好不一樣瀏覽器的兼容。相似地,你也應該在配置文件中增長更多的自定義開關,你不能默認認爲用戶老是想向你提供兩個打賞的二維碼,因此一個二維碼的樣式呢?或者索性不想要打賞呢?

提交主題

經歷了以上這些,你的主題已經基本具備可用性了,可是如何讓更多人知道而且使用你的主題呢?你能夠經過在各類技術型社區發帖,也能夠發動身邊的人使用。更官方的方案,是向hexo提交本身的主題。你具體能夠參考這裏主題| Hexo。準備好一份截圖,fork一份hexojs/site添加本身的主題信息和截圖後再向官方提出pull request請求,沒必要擔憂,由於他們真的很友善。

相關文章
相關標籤/搜索