修改Hexo Light主題功能樣式

目錄
  1. 1. 引用外觀
  2. 2. 加大字體顯示
  3. 3. 讓文章內的H1~H6標題顯示錨點符號
  4. 4. 修改搜尋框內容為Google自訂搜尋
  5. 5. 新增Google Adsense廣告區塊
    1. 5.1. 側邊欄
    2. 5.2. 文章下方
  6. 6. 新增側邊欄連結區塊
  7. 7. 在彙整頁和分類頁新增上下頁
  8. 8. 新增TOC(Table of Contents)
  9. 9. 修改Disqus留言板
  10. 10. 搜尋引擎最佳化(SEO)
    1. 10.1. 網頁加入canonical標記
    2. 10.2. 修改網頁描述
    3. 10.3. 文章連結加入nofollow
    4. 10.4. 建立網站地圖
  11. 11. 新增RSS訂閱

Hexo Light主題外觀簡單大方,沒有什麼華麗特效,算是很好修改。本文主要紀錄我個人修改需求功能,單一功能樣式修改步驟不多,但想改的東西累積起來,也是蠻多的。修改內容語法不加以詳細解釋,請自行Google結果。

引用外觀

原始引用外觀實在是不太好看,字體太大、句子全部置中。編輯/themes/light/source/css/_partial/article.styl,搜尋:

blockquote
  border-top 1px solid color-border
  border-bottom 1px solid color-border
  font-style italic
  font-family font-serif
  font-size 1.2em
  padding 0 30px 15px
  text-align center

改成:

blockquote
  border-left 6px solid #dfe2e5
  color #6a737d
  padding 0 20px
  text-align left

效果如圖:
Hexo Theme Light Quote

加大字體顯示

電腦和手機顯示的字體太小了,改大一點來看才不會吃力。編輯/themes/light/source/css/base/layout.styl,搜尋:

body
  background color-background
  color color-font
  font-family font-default
  font-size 14px
  text-shadow 0 0 1px transparent
  @media screen and (max-width: 1260px)
    margin 0 30px
  @media screen and (max-width: 600px)
    font-size 13px

font-size電腦預設是14px,手機預設是13px,我改成16px和15px。改完發現標籤雲沒有跟著變大,參考官方給的標籤雲參數來修改。編輯/themes/light/layout/_widget/tagcloud.ejs,搜尋:

<%- tagcloud(site.tags, {}) %>

改成:

<%- tagcloud(site.tags, {min_font: 12, max_font: 22}) %>

預設最小是10px,最大是20px,我改成12px和22px。改完重整一下,也會看到標籤雲相對變大。

讓文章內的H1~H6標題顯示錨點符號

參考〈hexo-theme-murasaki的_common.styl第37行〉的&:hover .headerlink:before這段語法。編輯/themes/light/source/css/_partial/article.styl,搜尋:

h1, h2
   font-weight normal
   border-bottom 1px solid color-border
   padding-bottom 10px
   margin-top 20px
   
h3, h4, h5, h6
   font-weight normal

改成:

h1, h2
   font-weight normal
   border-bottom 1px solid color-border
   padding-bottom 10px
   margin-top 20px
   &:hover .headerlink:before
     content '#'
     float left
     padding-right 1em
     margin-left -0.8em
     position absolute

h3, h4, h5, h6
   font-weight normal
   &:hover .headerlink:before
     content '#'
     float left
     padding-right 1em
     margin-left -0.8em
     position absolute

當游標移到H1~H6標題時,左邊便會自動顯示井字號錨點。

修改搜尋框內容為Google自訂搜尋

使用主題搜尋框,搜尋結果使用Google代管網頁。不選擇其他自訂搜尋效果,最大原因是只有Google代管才能使用目前視窗點進去搜尋連結,其他效果都是點進去搜尋連結會開新視窗。大型網站資料量夠大或是搜尋包含多個網站,開新視窗很方便。反之,個人網站資料量小,Google搜尋精準,尤其是重疊效果,搜尋結果開新視窗就顯得多餘。

如果你有Google Adsense,建議使用裡面的自訂搜尋設定,設定好後,產生程式碼如下:

<form action="http://www.google.com.tw" id="cse-search-box">
  <div>
    <input type="hidden" name="cx" value="partner-pub-xxxxxxxxxxxxxxxx" />
    <input type="hidden" name="ie" value="UTF-8" />
    <input type="text" name="q" size="25" />
    <input type="submit" name="sa" value="Search" />
  </div>
</form>

<script type="text/javascript" src="http://www.google.com.tw/coop/cse/brand?form=cse-search-box&lang=en"></script>

編輯/themes/light/layout/_widget/search.ejs,將內容:

<div class="search">
  <form action="//google.com/search" method="get" accept-charset="utf-8">
    <input type="search" name="q" results="0" placeholder="<%= __('search') %>">
    <input type="hidden" name="q" value="site:<%- config.url.replace(/^https?:\/\//, '') %>">
  </form>
</div>

改成:

<div class="search">
  <form action="http://www.google.com.tw" id="cse-search-box">
    <input type="hidden" name="cx" value="partner-pub-xxxxxxxxxxxxxxxx" />
    <input type="search" name="q" results="0" placeholder="<%= __('search') %>">
  </form>
</div>

修改完畢,自行測試效果,其他自訂搜尋效果也是類似修改方式,例如兩頁效果需新增一個分頁,內容為搜尋結果程式碼。

新增Google Adsense廣告區塊

側邊欄

到Google Adsense新增一個回應式廣告單元(依螢幕/裝置自動調整大小)。另外複製一個檔案在同資料夾下:/themes/light/layout/_widget/category.ejs,任意取名為adsense.ejs,修改其內容為:

<div class="widget tag">
  <h3 class="title">廣告</h3>
 <ul class="entry">
放置你的Google Adsense程式碼
 </ul>
</div>

不想要標題欄位,把<h3 class="title">廣告</h3></ul>這兩行移掉(用uBlock Origin擋掉至少會好看一點XD)。之後編輯/themes/light/_config.yml,在widgets:底下新增一個- adsense區塊。

文章下方

參考〈Hexo 블로그에 구글 애드센스(Adsense) 추가하기〉,新增/layout/_ads資料夾,裡面新增adsense.ejs,內容一樣加入回應式廣告單元程式碼。

編輯/layout/_partial/after_footer.ejs,搜尋<%- partial('post/category') %>,在上面加入:

<!-- google adsense start -->
<%- partial('_ads/adsense') %>
<!-- google adsense end -->

新增側邊欄連結區塊

參考〈Hexo中数据文件功能添加友情链接〉,在Hexo根目錄的source資料夾新增一個_data資料夾,在其資料夾再新增一個links.yml。內容範例格式為:

Google: http://www.google.com
Apple: http://www.apple.com
Hexo: http://hexo.io

另外複製一個檔案在同資料夾下:/themes/light/layout/_widget/category.ejs,任意取名為links.ejs,修改其內容為:

<% if (site.data.links){ %>
  <div class="widget tag">
    <h3 class="title">連結</h3>
      <ul class="entry">
        <% for (var i in site.data.links){ %>
          <li class='link'><a href='<%- site.data.links[i] %>'><%= i %></a></li>
        <% } %>
      </ul>
  </div>
<% } %>

編輯/themes/light/_config.yml,在widgets:底下新增一個- links區塊。之後編輯側邊欄連結,修改/source/_data/links.yml內容就可以了。

在彙整頁和分類頁新增上下頁

不知為何Light主題在這兩個頁面並無上下頁。編輯/themes/light/layout/archive.ejs(彙整)和/themes/light/layout/category.ejs(分類),在第一行下方加入:

<nav id="pagination">
  <% if (page.prev){ %>
    <a href="<%- config.root %><%- page.prev_link %>" class="alignleft prev"><%= __('prev') %></a>
  <% } %>
  <% if (page.next){ %>
    <a href="<%- config.root %><%- page.next_link %>" class="alignright next"><%= __('next') %></a>
  <% } %>
  <div class="clearfix"></div>
</nav>

之後就能在這兩種頁面看到上下頁了。

新增TOC(Table of Contents)

TOC就是文章內容的章節目錄,參考〈Hexo添加文章目录〉,寫長篇教學文時特別好用。編輯/themes/themename/layout/_partial/article.ejs,搜尋<%- item.content %>,新增的內容放到<%- item.content %>上方,其內容為:

  <% if (item.excerpt && index){ %>
        <%- item.excerpt %>
      <% } else { %>
        <% if (!index && item.toc){ %>
  <div id="toc" class="toc-article">
     <strong class="toc-title">目錄</strong>
     <%- toc(item.content) %>
  </div>
<% } %>
    <%- item.content %>

如果要關閉TOC編號,將上面的<%- toc(item.content) %>改成<%- toc(item.content, {list_number: false}) %>。手動輸入編號和錨點時,錨點連結需和TOC產生的連結一致,才不會錯亂。

新增TOC的CSS,編輯/themes/light/source/css/_partial/article.styl,加入:

/*toc*/
.toc-article
  background #eee
  border 1px solid #bbb
  border-radius 10px
  margin 0 0 0.3em 1.5em
  padding 1.2em 1em 0 1em
  max-width 28%
.toc-title
  font-size 120%
  padding 0.75em
#toc
  line-height 1em
  font-size 0.9em
  float right
  .toc
    padding 0
    margin 1em
    line-height 1.8em
    li
      list-style-type none
  .toc-child
    margin-left 1em

之後編輯文章內容時,文章的front matter加入toc: true,之後便會顯示TOC。文章本體內才會出現TOC,其他地方都不會出現。

效果如圖:
Hexo Theme Light TOC

修改Disqus留言板

原因:

其中被注释掉的disqus_config部分是用于初始化Disqus thread的。虽然不配置其中的url和identifier也可以用,但是这会导致Disqus直接使用当前页面的完整URL来初始化评论区。

也就是说,如果默认情况下你没有配置这些变量,访客每通过一个新的URL访问你的文章(就算只有Query String不一样),Disqus就会为它新建一个thread。这就导致了官方帮助文档中提到的split threads现象,即我上面在后台看到的一万个thread。

參考〈Hexo加入Disqus留言版(包含留言數)- 加入Disqus script〉,編輯/themes/light/layout/_partial/after_footer.ejs,搜尋:

<% if (config.disqus_shortname){ %>
<script type="text/javascript">
var disqus_shortname = '<%= config.disqus_shortname %>';
var disqus_url = '<%= config.url +"/"+ page.path %>';
var disqus_identifier = '<%= page.path %>';

改成:

<% if (config.disqus_shortname){ %>
<script type="text/javascript">
var disqus_shortname = '<%= config.disqus_shortname %>';
  var disqus_config = function() {
    this.page.url = '<%= page.permalink %>';
    this.page.identifier = '<%= page.path %>';
    this.page.title = '<%= page.title %>';
  };

搜尋引擎最佳化(SEO)

網頁加入canonical標記

安裝hexo-auto-canonical,編輯/themes/light/layout/_partial/head.ejs,加入:

<%- autoCanonical(config, page) %>

修改網頁描述

Head模版語法和其他主題相比,網頁描述語法的排列順序對搜尋引擎來說,並不友善,Google Search Console會提示出現很多重複的中繼說明。編輯/themes/light/layout/_partial/head.ejs,原始內容如下:

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
  <%
  var title = [];
  if (page.current > 1) title.push(__('page', page.current));
  if (page.title) title.push(page.title);
  if (page.category) title.push(page.category);
  if (page.tag) title.push(page.tag);
  if (page.archive){
    if (page.year) title.push(__('archive_b', page.year + (page.month ? '/' + page.month : '')));
    else title.push(__('archive_a'));
  }
  title.push(config.title);
  %>
  <title><%= title.join(' | ') %></title>
  <% if (config.author){ %><meta name="author" content="<%= config.author %>"><% } %>
  <% if (page.description){ %>
  <meta name="description" content="<%= page.description %>">
  <% } else if (config.description){ %>
  <meta name="description" content="<%= config.description %>">
  <% } else if (page.excerpt){ %>
  <meta name="description" content="<%= strip_html(page.excerpt).replace(/^\s*/, '').replace(/\s*$/, '') %>">
  <% } else if (page.content){ %>
  <meta name="description" content="<%= strip_html(page.content).replace(/^\s*/, '').replace(/\s*$/, '').substring(0, 150) %>">
  <% } %>
  <% if (page.keywords){ %><meta name="keywords" content="<%= page.keywords %>"><% } %>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">

  <% if (page.title){ %><meta property="og:title" content="<%= page.title %>"/><% } %>
  <meta property="og:site_name" content="<%= config.title %>"/>

  <% if(page.cover) { %>
    <meta property="og:image" content="<%= page.cover %>" />
  <% } else { %>
    <meta property="og:image" content="<%= config.cover %>"/>
  <% } %>

  <link href="<%- config.root %>favicon.png" rel="icon">
  <link rel="alternate" href="<% if (theme.rss){ %><%- theme.rss %><% } else { %><%- config.root %>atom.xml<% } %>" title="<%= config.title %>" type="application/atom+xml">
  <link rel="stylesheet" href="<%- config.root %>css/style.css" media="screen" type="text/css">
  <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  <%- partial('google_analytics') %>
</head>

改成(複製其他主題的head.ejs內容,已加canonical標記):

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8">
 <%
  var title = page.title;

  if (is_archive()){
    title = __('archive_a');

    if (is_month()){
      title += ': ' + page.year + '/' + page.month;
    } else if (is_year()){
      title += ': ' + page.year;
    }
  } else if (is_category()){
    title = __('category') + ': ' + page.category;
  } else if (is_tag()){
    title = __('tag') + ': ' + page.tag;
  }
  %>
  <title><% if (title){ %><%= title %> | <% } %><%= config.title %></title>
  <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=1">
  <%- open_graph({twitter_id: theme.twitter, google_plus: theme.google_plus, fb_admins: theme.fb_admins, fb_app_id: theme.fb_app_id}) %>
  <%- autoCanonical(config, page) %>
   <% if (theme.rss){ %>
    <link rel="alternate" href="<%- theme.rss %>" title="<%= config.title %>" type="application/atom+xml">
  <% } %>
  <% if (theme.favicon){ %>
    <link rel="icon" href="<%- theme.favicon %>">
  <% } %>
  <%- css('css/style') %>
  <!--[if lt IE 9]><script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script><![endif]-->
  <%- partial('google_analytics') %>
</head>

文章連結加入nofollow

參考〈hexo-filter-nofollow - Hexo官方的nofollow插件〉,安裝hexo-filter-nofollow,排除特定網域連結。編輯網站設定檔_config.yml,加入:

nofollow:
  enable: true
  field: site
  exclude:
    - 'exclude1.com'
    - 'exclude2.com'

建立網站地圖

安裝hexo-generator-sitemap,編輯網站設定檔_config.yml,加入:

sitemap:
  path: sitemap.xml

如果某篇文章不想加入Sitemap,文章的front matter加上sitemap: false

新增RSS訂閱

Hexo預設沒有RSS,安裝hexo-generator-feed,編輯網站設定檔_config.yml,加入:

feed:
  type: atom
  path: atom.xml
  limit: 10

limit為文章RSS輸出最大數量。