Hexo Light主題外觀簡單大方,沒有什麼華麗特效,算是很好修改。本文主要紀錄我個人修改需求功能,單一功能樣式修改步驟不多,但想改的東西累積起來,也是蠻多的。修改內容語法不加以詳細解釋,請自行Google結果。
原始引用外觀實在是不太好看,字體太大、句子全部置中。開啟/themes/light/source/css/_partial/article.styl
,搜尋:
1 2 3 4 5 6 7 8
| 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
|
改成:
1 2 3 4 5 6 7 8 9 10
| blockquote border-top 1px solid color-border border-bottom 1px solid color-border border-right 1px solid color-border border-left: 7px solid #DDD font-style italic font-family font-serif font-size 1.1em padding 0 30px 15px text-align left
|
效果如圖:

電腦和手機顯示的字體太小了,改大一點來看才不會吃力。開啟/themes/light/source/css/base/layout.styl
,搜尋:
1 2 3 4 5 6 7 8 9 10
| 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。改完發現標籤雲沒有跟著變大,查一下標籤雲字體大小寫在外掛裡。開啟/node_modules/hexo/lib/plugins/helper/tagcloud.js
,搜尋:
1 2 3 4
| options = options || {};
var min = options.min_font || 10; var max = options.max_font || 20;
|
預設最小是10px,最大是20px,我改成12px和22px。改完重整一下,標籤雲相對變大。
使用主題搜尋框,搜尋結果使用Google代管網頁。不選擇其他自訂搜尋效果,最大原因是只有Google代管才能使用目前視窗點進去搜尋連結,其他效果都是點進去搜尋連結會開新視窗。大型網站資料量夠大或是搜尋包含多個網站,開新視窗很方便。反之,個人網站資料量小,Google搜尋精準,尤其是重疊效果,搜尋結果開新視窗就顯得多餘。
如果你有Google Adsense,建議使用裡面的自訂搜尋設定,設定好後,產生程式碼如下:
1 2 3 4 5 6 7 8 9 10
| <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
,原始內容:
1 2 3 4 5 6
| <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>
|
改成:
1 2 3 4 5 6
| <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新增一個回應式廣告單元(依螢幕/裝置自動調整大小)。另外複製一個檔案在同資料夾下:/themes/light/layout/_widget/category.ejs
,任意取名為adsense.ejs
,修改其內容為:
1 2 3 4 5 6
| <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/comment.ejs
,搜尋<section id="comment">
,底下加入:
1 2 3
| <!-- google adsense start --> <%- partial('_ads/adsense') %> <!-- google adsense end -->
|
此區廣告可用留言區塊來控制開關。
參考〈Hexo中数据文件功能添加友情链接〉,在Hexo根目錄的source
資料夾新增一個_data
資料夾,在其資料夾再新增一個links.yml
。內容範例格式為:
1 2 3
| Google: http://www.google.com Apple: http://www.apple.com Hexo: http://hexo.io
|
另外複製一個檔案在同資料夾下:/themes/light/layout/_widget/category.ejs
,任意取名為links.ejs
,修改其內容為:
1 2 3 4 5 6 7 8 9 10
| <% 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
內容就可以了。
使用command進入Hexo資料夾,輸入指令新增一個Twitter獨立頁面,到Twitter網頁找到小工具程式碼(使用者時間軸顯示):
1 2
| <a class="twitter-timeline" href="https://twitter.com/你的帳號" data-widget-id="xxxxxxxxxxxx">@你的帳號 發送的推文</a> <script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+"://platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script>
|
以上程式碼放到獨立頁面如果無法使用,改成:
1
| <a class="twitter-timeline" href="https://twitter.com/你的帳號" data-widget-id="xxxxxxxxxxxx" data-chrome="noborders nofooter" data-tweet-limit="10" >@你的帳號 發送的推文</a><script async src="https://platform.twitter.com/widgets.js"></script>
|
其中data-tweet-limit="10"
為顯示推文數量,評論記得要關閉。
不知為何Light主題在這兩種連結頁面並無上下頁?開啟/themes/light/layout
資料夾中的archive.ejs
(彙整)和category.ejs
(分類),在第一行下方新增內容:
1 2 3 4 5 6 7 8 9
| <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就是文章內容的章節目錄,參考〈Hexo添加文章目录〉,寫長篇教學文時特別好用。開啟/themes/themename/layout/_partial/article.ejs
,搜尋<%- item.content %>
,新增內容放到<%- item.content %>
上方,完整內容為:
1 2 3 4 5 6 7 8 9 10
| <% 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
,在最下方新增內容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| /*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,其他地方都不會出現。
效果如圖:

原因:
其中被注释掉的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
,搜尋:
1 2 3 4 5
| <% 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 %>';
|
改成:
1 2 3 4 5 6 7 8
| <% 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 %>'; };
|
安裝hexo-auto-canonical,開啟/themes/light/layout/_partial/head.ejs
,最底下加入內容:
1
| <%- autoCanonical(config, page) %>
|
Head模版語法和其他主題相比,網頁描述語法的排列順序對搜尋引擎來說,並不友善,Google Search Console會提示出現很多重複的中繼說明。開啟/themes/light/layout/_partial/head.ejs
,原始內容如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45
| <!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標記):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <!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>
|
參考〈hexo-filter-nofollow - Hexo官方的nofollow插件〉,安裝hexo-filter-nofollow,排除特定網域連結。開啟網站設定檔_config.yml
,加入內容:
1 2 3 4 5 6
| nofollow: enable: true field: site exclude: - 'exclude1.com' - 'exclude2.com'
|
安裝hexo-generator-sitemap,開啟網站設定檔_config.yml
,加入內容:
1 2
| sitemap: path: sitemap.xml
|
如果某篇文章不想加入Sitemap,文章的front matter加上sitemap: false
。
Hexo預設沒有RSS,安裝hexo-generator-feed,開啟網站設定檔_config.yml
,加入內容:
1 2 3 4
| feed: type: atom path: atom.xml limit: 10
|
limit為文章RSS輸出最大數量。