前言
参考:
实践贴
Hexo: 从零开始编写自己的主题
编写自己的 Hexo 主题 | Easy Hexo 👨💻
Hexo主题开发
理论贴
Hexo高级教程 - 文集 - 简书
hexo-pagination函数释义 | 竹山一叶
hexo 源码分析 | Weakyon Blog
hexo源码分析(二) | HDi - 随便记
Hexo源码剖析-CSDN博客
Hexo源码分析(一)issue #4976的研究 | 拔剑Sketon
基础知识 markdown→html
我们的markdown源文件,通过转换插件转换为html格式内容。这部分内容结合特定的布局文件将会生成对应的html页面。文章和布局文件匹配的过程是由生成器完成的。
生成器(generator) 生成器实例 demo 自定义post生成器
1 2 3 4 5 6 7 hexo.extend .generator .register ('gen' , function (locals ){ return { path : 'gen/index.html' , data : locals.posts , layout : ['gen' ] } });
1 2 3 4 5 6 7 8 9 10 hexo.extend .generator .register ('post' , function (locals ){ return locals.posts .map (function (post ){ return { path : "book/" +post.path , data : post, layout : 'post' }; }); });
post默认生成器 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 import type { PostGenerator , PostSchema , SiteLocals } from '../../types' ;import type Document from 'warehouse/dist/document' ;function postGenerator (locals: SiteLocals ): PostGenerator [] { const posts = locals.posts .sort ('-date' ).toArray (); const { length } = posts; return posts.map ((post: Document<PostSchema>, i: number ) => { const { path, layout } = post; if (!layout || layout === 'false' ) { return { path, data : post.content }; } if (i) post.prev = posts[i - 1 ]; if (i < length - 1 ) post.next = posts[i + 1 ]; const layouts = ['post' , 'page' , 'index' ]; if (layout !== 'post' ) layouts.unshift (layout); post.__post = true ; return { path, layout : layouts, data : post }; }); } export = postGenerator;
综上,只要是_posts目录下的文章,且layout不为false,就会调用post生成器进行生成html。所以如果我们自定义自己的生成器,有些post页将会生成两次。
这种情况下就可以使用hexo-hide-posts
插件对post生成器
隐藏不需要的文章
hexo——优雅的隐藏文件
过程 page布局
butterfly的page汇总页默认显示banner图
但是每篇文章整一个图片有点困难。
模仿这位博主做无图汇总页面迷失在黄风岭 - 静かな森
修改内容如下(及其劣质的模仿):
page布局文件内容修改 hidden.pug innei.pug styl
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 //- 这里是决定不同的菜单页面显示不同的布局 case page.type when 'tags' include includes/page/tags.pug +commentLoad when 'link' include includes/page/flink.pug +commentLoad when 'categories' include includes/page/categories.pug +commentLoad when '404' include includes/page/404.pug when 'shuoshuo' include includes/page/shuoshuo.pug //- 下面是自定义的布局内容 when 'code' when 'diary' when 'book' when 'abstract' include includes/page/hidden.pug //- 如果layout是自定义的布局类型,那么使用hidden.pug布局文件 default include includes/page/default-page.pug +commentLoad
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 //- 隐藏页面布局(使用隐藏文章) if theme.tag_ui == 'index' include ../mixins/indexPostUI.pug +indexPostUI else include ../mixins/innei.pug #tag //- .innei_article-sort-title= _p('page.diary') - let hidden_posts = site.hidden_posts - const hide_posts_config = config.hide_posts - if (!hide_posts_config || !hide_posts_config.enable) { - hidden_posts = site.posts -} //- - console.log(page.type) - let sort_posts = getPostsByCategory(hidden_posts,page.type) +inneiLayout(sort_posts) include ../pagination.pug
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 //- 模仿innei的手记布局,有些文章实际上不需要显示图片 //- 和butterfly主题对比,只是少了图片,羞耻 //- https://innei.in/timeline?type=post mixin inneiLayout(posts) .innei_article-sort - let year - posts.forEach(article => { - const tempYear = date(article.date, 'YYYY') - const noCoverClass = article.cover === false || !theme.cover.archives_enable ? 'no-article-cover' : '' - const title = article.title || _p('no_title') if tempYear !== year - year = tempYear .innei_article-sort-item.year= year .innei_article-sort-item(class=noCoverClass) .innei_article-sort-item-info .innei_article-sort-item-time i.far.fa-calendar-alt time.post-meta-date-created(datetime=date_xml(article.date) title=_p('post.created') + ' ' + full_date(article.date))= date(article.date, 'MM/DD') a.innei_article-sort-item-title(href=url_for(article.path) title=title)= title - })
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 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 .innei_article-sort margin-left : 10px padding-left : 20px border-left : 2px solid lighten ($light -blue, 20 ) &-title position : relative margin-left : 10px padding-bottom : 10px padding-left : 30px font-size : 1.72em &:hover &:before border-color : var (--pseudo-hover) &:before position : absolute top : calc (((100% - 36px ) / 2 )) left : -9px z-index : 1 width : w = 10px height : h = w border : .5 * w solid $light -blue border-radius : w background : var (--card-bg) content : '' line-height : h transition : all .2s ease-in-out &:after position : absolute bottom : 0 left : 0 z-index : 0 width : 2px height : 1.5em background : lighten ($light -blue, 20 ) content : '' &-item position : relative display : flex align-items : center margin : 0 0 5px 10px transition : all .2s ease-in-out &:hover &:before border-color : var (--pseudo-hover) &:before $w = 6px position : absolute left : calc (-20px - 17px ) width : w = $w height : h = w border : .5 * w solid $light -blue border-radius : w background : var (--card-bg) content : '' transition : all .2s ease-in-out &.no-article-cover height : 80px .article-sort-item-info padding : 0 &.year font-size : 1.20em margin-bottom : 10px &:hover &:before border-color : $light -blue &:before border-color : var (--pseudo-hover) &-time color : var (--card-meta) font-size : 1.05em float :left time padding-left : 6px cursor : default &-title @extend .limit-more-line color : var (--font-color) font-size : 1.05em transition : all .3s -webkit-line-clamp: 2 float :left padding-left : 20px &:hover color : $text -hover text-decoration :underline; &-img overflow : hidden width : 100px height : 70px addBorderRadius () +maxWidth768 () width : 70px height : 70px :first-child @extend .imgHover &-info flex : 1
新增post页布局
新增了隐藏文章book, diary, code, abstract 四个布局,
如果隐藏文章没有定义布局或者定义的布局不在上述四个布局之内,
使用默认布局diary
hidden.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 26 27 28 'use strict' hexo.extend .generator .register ('hidden' , function (locals ) { return locals.hidden_posts .map (function (post ) { const { path, layout } = post; const layouts = ['book' , 'diary' , 'code' , 'abstract' ]; post.__post = true ; if (!layout || layout === 'false' || layouts.indexOf (layout) === -1 ) { console .log ("ERROR: No valid layout, use default layout [diary] for error post [%s]" , post.title ); post.layout = 'diary' ; } return { path, data : post, layout : layouts }; }); });
布局文件直接 copy post.pug,后面慢慢改
日记布局修改