Hexo主题开发手记(1)

最近抽空学习了一下前端的基础知识,在之前我也抽空看了相关知识,但是发现没有实践而且不够系统,所以索性这次借着hexo博客搭建来巩固和实践一下所学。

准备

虽然我们是开发hexo的博客主题,但是为了方便我们开发中调试和预览,所以我们还是首先得安装hexo到我们本地目录。

1
hexo init 搭建hexo主题

注意,上面的“搭建hexo主题”是我本地的一个目录。

然后发布,http://localhost:4000 查看

1
2
cd 搭建hexo主题
hexo server

hexo主题

这个是hexo预置的主题landspace,接下来还需要安装hexo-server和hexo-browsersync。另外我们的主题需要pug和stylus的渲染引擎,所以如下一并安装了:

  • hexo-server : hexo的服务运行环境。
  • hexo-browsersync : 页面自动刷新插件。
  • hexo-renderer-jade : pug的编译工具,内包括了pug的渲染引擎。
  • hexo-renderer-stylus : stylus的渲染引擎。
    1
    npm install hexo-server hexo-browsersync hexo-renderer-jade hexo-renderer-stylus --save-dev

注意,新版的hexo-renderer-jade已经包括了处理pug的渲染引擎。

主题结构

通常来说一个hexo主题需要包括下面元素:

  1. 首页 Home
  2. 归档页 Archive
  3. 标签页 Tag
  4. 分类页 Category
  5. 文章页 Post
  6. 页面详情页 Page

这些页面文件都要放到layout目录里。构建的时候将会读取里面的内容进行编译。像CSS,JS,IMG这些都可以算作是资源文件,构建的时候作为引用的资源。这些都放到source目录里。

生成结构

生成Hexo主题的话,用Yeoman是很方便的。如果系统里没有首先先安装一下npm install yo -g,然后再安装一下npm install generator-hexo-theme -g。(注意全局安装可能需要权限)于是我们就拥有了一个可以生成主题目录结构的脚手架工具。

进入之前创建好的Hexo的博客目录,找到themes文件夹,进入。然后yo hexo-theme,这样就会自动生成对应选项,根据选项我们选择pug和stylus,给这个主题命名为temp。然后就会生成一个还不错的项目目录结构。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
.
├── _config.yml # 主题配置文件
├── layout # 布局文件夹
│ ├── archive.pug # 归档页
│ ├── category.pug # 分类页
│ ├── includes # 复用的公共页
│ │ ├── layout.pug # 页面布局
│ │ ├── pagination.pug # 翻页模板
│ │ └── recent-posts.pug # 文章列表模板
│ ├── index.pug # 主页
│ ├── page.pug # 页面详情页
│ ├── post.pug # 文章详情页
│ └── tag.pug # 标签页
└── source # 资源文件夹
├── css # CSS
│ └── temp.styl
├── favicon.ico # 站点图标
└── js # JS
└── temp.js

配置根目录的_config.xml来设置主题为dp2px

1
theme: dp2px

启动hexo服务

1
hexo server

hexo启动服务

查看我们的主题页面如下(为了看起来直观,我拷贝了文章到_post目录):

hexo文章页面

可以看到首页没有任何样式,接下来我们就需要来完善这些页面的布局和样式了。

配置首页链接

我也是初次使用pug,所以看的不是很明白,没关系,我们来先做一下熟悉的事情,配置首页的菜单和链接。

1
2
3
4
5
6
7
# main menu navigation
menu:
首页: /
关于: /about
归档: /archives
标签: /tags
分类: /categories

然后用我们最熟悉的命令创建tags和categories目录

1
2
3
4
>>> $ hexo new page tags
INFO Created: ~/Documents/搭建hexo主题/source/tags/index.md
>>> $ hexo new page categories
>>> INFO Created: ~/Documents/搭建hexo主题/source/categories/index.md

OK!接下来我们分别打开这两个index.md文件并分别添加一个type: tags 和 type: categories

1
2
3
title: categories
date: 2018-10-24 19:24:07
type: categories

来开始编辑我们第一个pug页面,打开themes/dp2px/page.pug,追加如下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
extends includes/layout.pug

block content
if page.type === 'tags'
.tag-cloud
.tag-cloud__title= page.title
| -
span.tag-cloud__amount= site.tags.length
.tag-cloud-tags!= tagcloud({min_font: 12, max_font: 30, amount: 200, color: true, start_color: '#A4D8FA', end_color: '#0790E8'})
else if page.type === 'categories'
.category-lists
.category__title= page.title
| -
span.category__amount= site.categories.length
div!= list_categories()
else
article#page
h1= page.title
!= page.content
div!= paginator()

上面的tagcloud()函数是官方提供的生成标签云的函数,参考链接:https://hexo.io/zh-cn/docs/helpers.html#tagcloud

同样list_categories()函数也是官方提供的生成分类列表的函数,参考链接:https://hexo.io/zh-cn/docs/helpers.html#list-categories

这样我们的tags页面和categories页面就可以显示出来了。

hexo的tags和categories

各个pug文件的关系分析

index.pug

首先我们打开index.pug文件

1
2
3
4
5
extends includes/layout.pug

block content
include includes/recent-posts.pug
div!= paginator()

看到这个index.pug继承了layout.pug。
对layout中的block content进行了覆盖,引入了recent-posts.pug

paginator()函数是官方提供生成分页链接的,可以设置它的样式,参考链接:https://hexo.io/zh-cn/docs/helpers.html#paginator

recent-posts.pug

在index.pug中我们看到content中引入了recent-posts.pug

1
2
3
4
5
6
7
8
if page.posts.length > 0
#recent-posts
h1 Recent Posts
each post in page.posts.sort('date', -1).limit(10).toArray()
.recent-post-item
a(href=config.root + post.path)= post.title
if post.date
time(datetime=post.date.toJSON())= date(post.date, date_format)

我们看到这里主要是遍历了page.posts.在hexo中有很多预置变量,page就是。

变量描述
site网站变量
page针对该页面的内容以及 front-matter 所设定的变量。
config网站配置
theme主题配置。继承自网站配置。
_ (单下划线)函数库
path当前页面路径(不含根路径)
url当前页面完整网址
env环境变量

关于其他变量的详细请查看官方文档:https://hexo.io/zh-cn/docs/variables

上面的page.posts是页面文章对象,我们看到使用limit(10)拿出了前10个文章显示。

所以,recent-posts.pug是首页最近发布的文章列表。

layout.pug

layout.pug是hexo主题页面中最重要的页面,因为几乎所有页面都继承自它。它提供了一个基础的页面结构模板。

最上面定义了一个pageTitle变量,并根据条件赋值

1
2
3
4
5
6
7
- var pageTitle = page.title || config.subtitle || ''
- if (is_archive()) pageTitle = 'Archives'
- if (is_tag()) pageTitle = 'Tag: ' + page.tag
- if (is_category()) pageTitle = 'Category: ' + page.category
- if (is_month()) pageTitle += ': ' + page.month + '/' + page.year
- if (is_year()) pageTitle += ': ' + page.year
- pageTitle += ' [ ' + config.title + ' ]'

其中 is_archive()、is_tag()这几个函数都是预置函数,判断页面类型的。

接下来定义了head头

1
2
3
4
5
6
7
8
head
meta(charset='UTF-8')
title= pageTitle
if theme.stylesheets !== undefined && theme.stylesheets.length > 0
//- stylesheets list from config.yml
each url in theme.stylesheets
link(rel='stylesheet', href=url)
link(rel="icon", href=config.root + 'img/favicon.png')

可以看到样式文件通过themes下面的_config.yml中的theme.stylesheets来配置。

接下来body中定义了页面菜单、内容模板、以及页脚说明、最后通过theme.scripts加载了js文件。

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
body
#menu-outer
nav#menu-inner
each url, label in theme.menu
a(href=url)= label
#content-outer
#content-inner
if body
div!= body
else
block content
#bottom-outer
#bottom-inner
span Site construction by
span= ' ' + config.author + ' '
span using
a(href='http://hexo.io')
span hexo blog framework
span .
br
a(href=config.root) Home
if theme.scripts !== undefined && theme.scripts.length > 0
//- scripts list from config.yml
each url in theme.scripts
script(src=url)

所以,对于我们来说核心的任务是完成这个layout.pug的布局和样式。

评论

Ajax Android AndroidStudio Animation Anroid Studio AppBarLayout Babel Banner Buffer Bulma ByteBuffer C++ C11 C89 C99 CDN CMYK COM1 COM2 CSS Camera Raw, 直方图 Chrome Class ContentProvider CoordinatorLayout C语言 DML DOM Dagger Dagger2 Darktable Demo Document DownloadManage ES2015 ESLint Element Error Exception Extensions File FileProvider Flow Fresco GCC Git GitHub GitLab Gradle Groovy HTML5 Handler HandlerThread Hexo Hybrid I/O IDEA IO ImageMagick IntelliJ Intellij Interpolator JCenter JNI JS Java JavaScript JsBridge Kotlin Lab Lambda Lifecycle Lint Linux Looper MQTT MVC MVP Maven MessageQueue Modbus Momentum MySQL NDK NIO NexT Next Nodejs ObjectAnimator Oracle VM Permission PhotoShop Physics Python RGB RS-232 RTU Remote-SSH Retrofit Runnable RxAndroid RxJava SE0 SSH Spring SpringBoot Statubar Style Task Theme Thread Tkinter UI UIKit UML VM virtualBox VS Code VUE ValueAnimator ViewPropertyAnimator Vue Vue.js Web Web前端 Workbench api apk bookmark by关键字 cli compileOnly computed css c语言 databases demo hexo hotfix html iOS icarus implementation init jQuery javascript launchModel logo merge methods mvp offset photos pug query rxjava2 scss servlet shell svg tkinter tomcat transition unicode utf-8 vector virtual box vscode watch webpack 七牛 下载 中介者模式 串口 临潼石榴 主题 书签 事件 享元模式 仓库 代理模式 位运算 依赖注入 修改,tables 光和色 内存 内核 内部分享 函数 函数式编程 分支 分析 创建 删除 动画 单例模式 压缩图片 发布 可空性 合并 同向性 后期 启动模式 命令 命令模式 响应式 响应式编程 图层 图床 图片压缩 图片处理 图片轮播 地球 域名 基础 增加 备忘录模式 外观模式 多线程 大爆炸 天气APP 太白山 头文件 奇点 字符串 字符集 存储引擎 宇宙 宏定义 实践 属性 属性动画 岐山擀面皮 岐山肉臊子 岐山香醋 工具 工厂模式 年终总结 开发技巧 异常 弱引用 恒星 打包 技巧 指令 指针 插件 插值 摄影 操作系统 攻略 故事 数据库 数据类型 数组 文件 新功能 旅行 旋转木马 时序图 时空 时间简史 曲线 杂谈 权限 枚举 架构 查询 标准库 标签选择器 样式 核心 框架 案例 桥接模式 检测工具 模块化 模板 模板引擎 模板方法模式 油泼辣子 泛型 洛川苹果 浅色状态栏 渲染 源码 源码分析 瀑布流 热修复 版本 版本控制 状态栏 状态模式 生活 留言板 相册 相对论 眉县猕猴桃 知识点 码云 磁盘 科学 笔记 策略模式 类图 系统,发行版, GNU 索引 组件 组合模式 绑定 结构 结构体 编码 网易云信 网格布局 网站广播 网站通知 网络 美化 联合 脚手架 膨胀的宇宙 自定义 自定义View 自定义插件 蒙版 虚拟 虚拟机 补码 补齐 表单 表达式 装饰模式 西安 观察者模式 规范 视图 视频 解耦器模式 设计 设计原则 设计模式 访问者模式 语法 责任链模式 贪吃蛇 转换 软件工程 软引用 运算符 迭代子模式 适配器模式 选择器 通信 通道 配置 链表 锐化 错误 键盘 闭包 降噪 陕西地方特产 面向对象 项目优化 项目构建 黑洞
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×