效果
通过 hexo new page Pagename创建页面时,需要在Blog/source/Pagename/index.md的Post Front-matter中添加type: “categories”等字样,这其实就是在告诉主题,这个页面是特殊的页面。打开[blogroot]/themes/butterfly/layout/page.pug文件,会看到如下内容
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 extends includes/layout.pug block content - const noCardLayout = ['shuoshuo', '404'].includes(page.type) ? 'nc' : '' - var commentsJsLoad = false mixin commentLoad if page.comments !== false && theme.comments.use - commentsJsLoad = true !=partial('includes/third-party/comments/index', {}, {cache: true}) #page(class=noCardLayout) if top_img === false && page.title .page-title= page.title 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 default include includes/page/default-page.pug +commentLoad
可以看到,当一个页面被识别为特殊类型,即when 'categories',就会进入对应的页面。添加新的页面类型就是构建这个特殊页面,即xxx.pug,并添加相应的样式
开始构建 创建页面文件 在[blogroot]/themes/butterfly/layout/includes/page文件下新建navigation.pug文件,并添加如下内容
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 #article-container.navigation-widget if site.data.navigation each i in site.data.navigation - var style = i.flink_style || 'volantis' .flink(class=style) if i.class_name h2!= i.class_name if i.class_desc .flink-desc!= i.class_desc if style === 'volantis' .site-card-group each item in i.link_list a.site-card(target='_blank' rel='noopener' href=url_for(item.link)) .img - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link if theme.lazyload.enable img(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' ) else img(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) .info if theme.lazyload.enable img(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) else img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) span.title= item.name span.desc(title=item.descr)= item.descr else if style === 'flexcard' .flink-list each item in i.link_list a.flink-list-card(href=url_for(item.link) target='_blank' data-title=item.descr) .wrapper.cover - var siteshot = item.siteshot ? url_for(item.siteshot) : 'https://image.thum.io/get/width/400/crop/800/allowJPG/wait/20/noanimate/' + item.link if theme.lazyload.enable img.cover.fadeIn(data-lazy-src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.post_page) + `'` alt='' ) else img.cover.fadeIn(src=siteshot onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) .info if theme.lazyload.enable img.flink-avatar(data-lazy-src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) else img(src=url_for(item.avatar) onerror=`this.onerror=null;this.src='` + url_for(theme.error_img.flink) + `'` alt='' ) span.flink-sitename= item.name != page.content
这就是新添加的navigation类型页面的模板
创建样式文件 在[blogroot]/themes/butterfly/source/css/_page中新建navigation.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 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 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 .navigation-widget .flink .flink-desc margin 0.2rem 0 0.5rem .flink-list overflow auto text-align center padding 0 margin 1rem -6px 0 -6px .flink-list-item position relative float left overflow hidden margin 6px 6px border-radius 12px border var (--style-border) box-shadow var (--Jay-shadow-border) transition 0.3s ease-in-out .flink-list-item a display flex border none color var (--Jay-fontcolor) text-decoration none &:hover background none .flink-list-item a img border-radius 32px margin 15px 20px 15px 15px min-width 60px min-height 60px transition 0.3s background var (--Jay-background) pointer-events none .flink-list-item :hover a img width 0 height 0 opacity 0 margin 0.5rem min-width 0 min-height 0 transition 0.6s .flink-item-info max-width 136px overflow hidden .flink-list-item :hover .flink-item-info max-width 100% .flink-item-name text-align left font-size 19px font-weight 700 white-space nowrap overflow hidden text-overflow ellipsis color var (--Jay-fontcolor) .flink-list-item :hover a .flink-item-name color var (--Jay-white) .flink-item-desc white-space normal padding 5px 10px 16px 0 color var (--Jay-fontcolor) text-align left height 40px text-overflow ellipsis opacity 0.7 display -webkit-box overflow hidden -webkit-box-orient vertical -webkit-line-clamp 2 .flink-list-item :hover a .flink-item-desc color var (--Jay-white) overflow inherit width 100% .flink .volantis .site-card-group display flex flex-wrap wrap justify-content flex-start margin -0.5 * 16px align-items stretch .site-card margin 16px * 0.5 width calc (100% / 4 - 16px ) @media screen and (min-width : 2048px ) width calc(100% / 5 - 16px ) @media screen and (max-width : 768px ) width calc(100% / 3 - 16px ) @media screen and (max-width : 500px ) width calc(100% / 2 - 16px ) display block line-height 1.4 height 100% .img width 100% height 120px overflow hidden border-radius 6px box-shadow 0 1px 2px rgba(0 ,0 ,0 ,0.2 ) background #f6f6f6 img width 100% height 100% object-fit cover transition transform 2s ease .info margin-top 8px img width 32px height 32px border-radius 16px float left margin-right 8px margin-top 2px span display block .title font-weight 600 font-size $fontsize-list color #444 display -webkit-box -webkit-box-orient vertical overflow hidden -webkit-line-clamp 1 .desc font-size $fontsize-footnote line-height 1.2 color #888 display -webkit-box -webkit-box-orient vertical overflow hidden -webkit-line-clamp 2 &:hover .img box-shadow 0 4px 8px rgba(0 ,0 ,0 ,0.1 ) .info .title color #ff5722 // ======================= // flexcard 风格 // ======================= .flink.flexcard .flink-list & > a width calc(25% - 15px ) height 130px position relative display block margin 15px 7px float left overflow hidden border-radius 10px transition all 0.3s ease, transform 0.6s cubic-bezier(.6 ,.2 ,.1 ,1 ) box-shadow 0 14px 38px rgba(0 ,0 ,0 ,.08 ),0 3px 8px rgba(0 ,0 ,0 ,.06 ) &:hover .info transform translateY(-100% ) .wrapper img transform scale(1.2 ) &:before position fixed width inherit margin auto left 0 right 0 top 10% border-radius 10px text-align center z-index 100 content attr(data-title) font-size 20px color #fff padding 10px background-color rgba($theme-color,0.8 ) .cover width 100% transition transform 0.5s ease-out .wrapper position relative .fadeIn animation coverIn 0.8s ease-out forwards img height 130px .info display flex flex-direction column justify-content center align-items center width 100% height 100% overflow hidden border-radius 3px background-color hsla(0 ,0% ,100% ,0.7 ) transition transform 0.5s cubic-bezier(.6 ,.2 ,.1 ,1 ) img width 66px height 66px border-radius 50% box-shadow 0 0 10px rgba(0 ,0 ,0 ,0.3 ) position relative top 22px span padding 20px 10% 60px 10% font-size 16px width 100% text-align center background-color hsla(0 ,0% ,100% ,0.7 ) color var(--font-color) white-space nowrap overflow hidden text-overflow ellipsis @media screen and (max-width :1024px ) .flink-list > a width calc(33.33333% - 15px ) @media screen and (max-width :600px ) .flink-list > a width calc(50% - 15px )
引入新的页面类型 正如前面所说,需要引入才会被主题识别,修改[blogroot]/themes/butterfly/layout/page.pug文件,在相应位置添加
when 'navigation' include includes/page/navigation.pug
修改后的内容,如下所示
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 extends includes/layout.pug block content - const noCardLayout = ['shuoshuo', '404'].includes(page.type) ? 'nc' : '' - var commentsJsLoad = false mixin commentLoad if page.comments !== false && theme.comments.use - commentsJsLoad = true !=partial('includes/third-party/comments/index', {}, {cache: true}) #page(class=noCardLayout) if top_img === false && page.title .page-title= page.title 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 'navigation' include includes/page/navigation.pug default include includes/page/default-page.pug +commentLoad
到此为止新建页面类型已经完成了,自定义的部分主要集中在navigation.pug和navigation.styl中,分别对应页面布局及数据交互 和页面样式
接下来介绍的是这个页面类型的配置方法
navigation类型页面的配置方法 创建navigation页面 在博客的根目录运行
1 hexo new page navigation
运行后会在[blogroot]/source/下生成navigation文件夹,打开navigation文件夹下的index.md文件,按照如下格式添加内容
1 2 3 4 5 6 --- title: 导航 date: 2024-09-06 13:37:37 aside: false type: 'navigation' ---
为页面添加内容 最后添加页面的内容,即要展示的网页。新建[blogroot]/source/_data/navigation.yml文件(若无data文件夹,新建data文件夹即可),按照如下格式添加内容
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 - class_name: 设计素材 class_desc: 为你的设计添加色彩 flink_style: random: false link_list: - name: Font Awesome link: https://fontawesome.com avatar: https://www.faviconextractor.com/favicon/fontawesome.com descr: icon网站 siteshot: - name: iconfont link: https://www.iconfont.cn avatar: https://www.faviconextractor.com/favicon/www.iconfont.cn?larger=true descr: icon网站 siteshot: - class_name: 实用工具 class_desc: 非常nice的在线工具 flink_style: random: false link_list: - name: TinyPNG link: https://tinify.cn avatar: https://www.faviconextractor.com/favicon/tinify.cn descr: 图片压缩网站 siteshot: - name: Favicon Extractor link: https://www.faviconextractor.com avatar: https://www.faviconextractor.com/favicon/faviconextractor.com descr: 网站图标获取 siteshot: - class_name: 资源网站 class_desc: 帮助构建博客的资源网站 flink_style: random: false link_list: - name: Staticfile CDN link: https://www.staticfile.net avatar: https://www.faviconextractor.com/favicon/www.staticfile.net descr: CDN服务网站 siteshot:
class_name 和 class_desc 支持 html 格式,如不需要,也可以留空
siteshot 是站点缩略图的链接,留空自动获取站点的缩略图
flink_style 设置站点卡片的样式( volantis 或 flexcard ),不设置默认为 volantis,本文的开头展示了两种样式的效果