博客四

前言

经过我前面对Hexo的解析,应该可以对Hexo有了更加深刻的理解了,下面就正式进入正题,制作一个Hexo的主题,一个人单独造轮子是非常痛苦的,况且已经有造的优秀轮子可以直接拿来使用,我们只是想造一个最适合自己的。

思考

我们参考Hexo的默认主题landscape,其实完成一个Hexo的主题是很简单,和写静态页面差不多,只是内容部分通过Hexo的变量去获取,而且Hexo还内置了一些辅助函数帮我们快速方便地完成繁琐的处理。

项目结构

在写代码之前应该先构建项目结构,一个Hexo主题的项目名就是主题名字本身,项目内的目录结构如下:

image.png

layout用来放置布局文件,soure用来放置静态文件,_config.yml是主题的配置文件

tips: 模板引擎有Jade,EJS,swig,Handlebars
建议使用ejs或者swig,
建议使用Sass这样的CSS预编译器

ejs 的标签系统非常简单,它只有以下三种标签:
<% code %>:JavaScript 代码。
<%= code %>:显示替换过 HTML 特殊字符的内容。
<%- code %>:显示原始 HTML 内容。

布局

编写布局文件(layout.ejs)

模板文件在layout文件夹下,文件名对应Hexo中的模板名,
基本上就是这些index,post,page,archive,category,tag

每一个模板文件对应的是一种布局,当使用hexo new <title>的时候,其实忽略了一个参数,完整的命令是hexo new [layout] <title>,这个[layout]就决定了文章使用何种方式布局,比如创建一个自己简介的About页面,hexo new page "about"其实就是使用了page布局。每种布局对应到我们的模板文件上就是index.ejs(首页),post.ejs(文章),archive.ejs(归档),tag.ejs(标签归档),page.ejs(分页)

url和模板的对应关系是这样的:


image.png

对于一般的header + content + footer的页面结构来说,header和footer往往是可以重复使用的,因此我们可以使用layout.ejs进行布局,动态的内容使用body变量去动态渲染,

layout.ejs

<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1,user-scalable=no"/>
    <title><%= config.title %></title>
    <%- css('css/style') %>
</head>
<body>
    <%- partial('_partial/header') %>
    <div class="main">
        <%- body %>
    </div>
    <%- partial('_partial/footer') %>
    <%- js('js/index.js') %>
</body>
</html>

partial,jscss是Hexo提供的辅助函数,

index.ejs

//index.ejs
<% page.posts.each(function(post){ %>
    <%- partial('_partial/article', {index: true, post: post}) %>
<% }) %>
<div class="pagination">
    <%- paginator({ total: Math.ceil(site.posts.length / config.per_page)}) %>
</div>

首页设计的是一些文章的摘要和一个分页器,通过Hexo的page变量拿到页面的数据渲染即可,这里我们不直接在index.ejs中写HTML结构,新建一个_partial/article.ejs,将文章数据传给子模板渲染,然后再额外传入一个参数{index: true},对后面的post.ejspage.ejs加以区分,让子模板能正确渲染。

post.ejs

//post.ejs
<%- partial('_partial/article', {index: false, post: page}) %>

文章页模板和首页差不多,只是对应的是一篇具体的文章,所以就把文章传入,再额外传入{index: false}告诉子模板不要按首页的方式去渲染就好了。

page.ejs

//page.ejs
<%- partial('_partial/article', {index: false, post: page}) %>

先设置成和文章一样的渲染,这样更快速方便。

_partial/article.ejs

//_partial/article.ejs
<% if(index){ %>
    //index logic...
   <%- partial('_partial/_article/index', {post: post}) %>
<% }else{ %>
    //post or page logic...
   <%- partial('_partial/_article/detail', {post: post}) %>
<% } %>

archive.ejs

//archive.ejs
<div class="archive">
  <% var lastyear; %>
  <% page.posts.each(function(post){ %>
    <% var year = post.date.year() %>
    <% if(lastyear !== year){ %>
      <h4 class="year"><%= year %></h4>
      <% lastyear = year %>
    <% } %>
    <div class="archive_item">
      <a class="title" href="<%- url_for(post.path) %>"><%= post.title %></a>
      <span class="date"><%= post.date.format('YYYY-MM-DD') %></span>
    </div>
  <% }) %>
  <div class="pagination">
    <%- paginator({ total: Math.ceil(site.posts.length / config.per_page)}) %>
  </div>
</div>

归档页模板和首页差不多,归档页只需要展示文章标题和最后的分页器就好

tag.ejs

//tag.ejs
<div class="tags">
    <h1><%= page.tag %></h1>
    <% page.posts.each(function(post){ %>
      <div class="tag_item">
        <a class="title" href="<%- url_for(post.path) %>"><%= post.title %></a>
        <span class="date"><%= post.date.format('YYYY-MM-DD') %></span>
      </div>
    <% }) %>
</div>

tag.ejs作用的是具体tag下的归档布局,因此和archive.ejs差不多

变量

Hexo提供了很多变量,其中模板文件中我们使用了page.post,site.posts.length,config.per_page等等,页面的内容就是根据这些变量获取的,由Hexo提供,拿来直接用,

一般就用到以下变量:

  • site: 对应整个网站的变量,一般会用到site.posts.length制作分页器

  • page: 对应当前页面的信息,例如我在index.ejs中使用page.posts获取了当前页面的所有文章而不是使用site.posts

  • config: 博客的配置信息,博客根目录下的_config.yml

  • theme: 主题的配置信息,对于主题根目录下的_config.yml

辅助函数(Helper)

制作一个分页器,我们需要知道文章的总数和每页展示的文章数,然后通过循环生成每个link标签,还要根据当前页面判断link标签的active状态,但是在Hexo中这些都不用我们自己来做了!
Hexo提供了paginator这一辅助函数帮助我们生成分页器,只需要将文章总数site.posts.length和每页文章数config.per_page传入就可以生成了。

其他的Helper:

  • list_tags([options]): 快速生成标签列表

  • js(path/to/js), css(path/to/css) 用来载入静态资源,path可以是字符串或数组(载入多个资源),默认会去source文件夹下去找。

  • partial(path/to/partial) 引用字模板,默认会去layout文件夹下找。

样式

可以使用HTML标签+CSS样式个性化我们的主题了,推荐使用CSS预处理语言的一种来写样式,这样就可以通过预处理语言自身的特点让样式更灵活。---Sass

添加评论功能

说实话这年头做的不错的免费服务真的不多

  • 多说 - 最多用户使用的评论,但遗憾2017年6月将暂定服务;不建议新用户使用,但为旧用户保留,也感谢多说一路的陪伴;

  • 网易云跟帖 - 网易提供的评论组件,功能比较简单,性能优秀;管理后台在查询上还不算特别智能,但足够普通用户使用,但是也已经关闭了;

  • 畅言 - 搜狐提供的评论组件,功能丰富,体验优异;但必须进行域名备案。只要域名备过案就可以通过审核,也就是说:可以在其他IDC备案然后解析到Github Page。虽然这样做可能会被注销备案,但却是是可行的。

  • Disqus - 国外使用较多的评论组件。万里长城永不倒,一枝红杏出墙来,你懂的。

留给我们使用的基本上已经不多了。

Hexo本身自带了disqus,百度可以解决

当然也可以选择畅言,这个直接百度下就有了,
提供 畅言http://changyan.kuaizhan.com/install/code/self-adaption

使用highlight.js提供代码高亮

highlight.js提供了多种语言的支持和多种皮肤,用法也很简单,载入文件后调用初始化方法,一切都帮你搞定,对于使用那种皮肤,喜好因人而异,我们干脆在主题的配置文件中做成配置项让用户自己选择:

//主题根目录/_config.yml

...other configs

# highlight.js
highlight_theme: zenburn

对应的layout.ejs中:
样式文件通过CDN引入,因为不同皮肤对应不同的文件名,所以十分灵活。

<link rel="stylesheet" href="//cdnjs.cloudflare.com/ajax/libs/highlight.js/9.4.0/styles/<%= theme.highlight_theme %>.min.css">

总结

基本上把一个主题应该具备的功能说清楚了,思路有了,剩下的就是动手做,然后不断的百度,谷歌,任何参考别人的主题代码,经过时间的打磨一定可以做出一个让你自己满意的主题的,嘻嘻。。


你以为这样就结束了吗,然而并没有

我们主题是有了,但是blog有很多我们需要的功能它并没有带有,所有这些功能,还需要我们自己来增加,所以下一步,就是自己制作一个开源的博客系统。

期待。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,980评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,178评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,868评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,498评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,492评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,521评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,910评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,569评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,793评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,559评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,639评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,342评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,931评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,904评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,144评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,833评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,350评论 2 342

推荐阅读更多精彩内容