本文是基于icarus 2.x的版本,icarus从3.0开始使用jsx重写了,查看
最新版本。
本博客所选取的主题是 Icarus ,并做了一些个性化的修改,很多修改都可以直观的看到。详细的差异可以查看 diff,这里记录一些主要的改动。
注: 可以通过变量 page.layout
来判断当前页面类型,'post'
表示当前是文章页面,具体可参考 hexo 文档。
布局
文章页面两栏布局
主题默认是三栏布局,并且显示了很多的 widget
,但在阅读文章时显得有些拥挤。因此在文章页面,修改为两栏布局,并显示特定的 widget
。
diff:includes/helpers/layout.js1 2 3 4 5 6 7 8 9 10
| const widgets = hexo.extend.helper.get('get_config').bind(this)('widgets'); - return widgets.filter(widget => widget.hasOwnProperty('position') && widget.position === position); + if (this.page.layout !== 'post') { + return widgets.filter(widget => widget.hasOwnProperty('position') && widget.position === position); + } + if (position === 'left') { + return widgets.filter(widget => widget.hasOwnProperty('position') && (widget.type === 'toc' || widget.type === 'profile')); + } else { + return [] + }
|
可以参考上述代码,即可实现不同页面不同 widget
。
但两栏整体宽度跟三栏不同。因此强制指定为三栏布局,并且修改相应的宽度,这样所有的页面侧边栏宽度保持一致。
diff:layout/common/widget.ejs1 2 3 4 5 6
| <% function side_column_class() { switch (column_count()) { case 2: - return 'is-4-tablet is-4-desktop is-4-widescreen'; + return 'is-4-tablet is-4-desktop is-3-widescreen'; case 3:
|
diff:layout/layout.ejs1 2 3 4 5 6 7 8 9 10
| -<body class="is-<%= column_count() %>-column"> +<body class="is-3-column"> <%- partial('common/navbar', { page }) %> <% function main_column_class() { switch (column_count()) { case 1: return 'is-12'; case 2: - return 'is-8-tablet is-8-desktop is-8-widescreen'; + return 'is-8-tablet is-8-desktop is-9-widescreen';
|
并修改在不同屏幕小大下的宽度
diff:source/css/style.styl1 2 3 4 5 6 7 8 9 10 11 12 13
| .is-2-column .container max-width: screen-desktop - 2 * gap width: screen-desktop - 2 * gap + .is-3-column .container + max-width: screen-widescreen - gap + width: screen-widescreen - gap @media screen and (min-width: screen-fullhd) + .is-3-column .container + max-width: screen-fullhd - 2 * gap + width: screen-fullhd - 2 * gap .is-2-column .container max-width: screen-widescreen - 2 * gap width: screen-widescreen - 2 * gap
|
优化文章标题布局
标题移动到文章信息上方,增加更新时间,并增加了icon。
diff:layout/common/article.ejs1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <div class="card-content article <%= post.hasOwnProperty('direction') ? post.direction : '' %>"> + <h1 class="title is-size-3 is-size-4-mobile has-text-weight-normal"> + <% if (index) { %> + <a class="has-link-black-ter" href="<%- url_for(post.link ? post.link : post.path) %>"><i class="fas fa-angle-double-right"></i><%= post.title %></a> + <% } else { %> + <i class="fas fa-angle-double-right"></i><%= post.title %> + <% } %> + </h1> <% if (post.layout != 'page') { %> <div class="level article-meta is-size-7 is-uppercase is-mobile is-overflow-x-auto"> <div class="level-left"> - <time class="level-item has-text-grey" datetime="<%= date_xml(post.date) %>"><%= date(post.date) %></time> + <time class="level-item has-text-grey" datetime="<%= date_xml(post.date) %>"><i class="far fa-calendar-alt"> </i><%= date(post.date) %></time> + <% if (post.updated && post.updated > post.date) { %> + <time class="level-item has-text-grey is-hidden-mobile" datetime="<%= date_xml(post.updated) %>"><i class="far fa-calendar-check"> </i><%= date(post.updated) %></time> + <% } %> <% if (post.categories && post.categories.length) { %>
|
其中创建时间使用日期。
diff:source/js/main.js1 2 3 4 5
| - if (typeof(moment) === 'function') { - $('.article-meta time').each(function () { - $(this).text(moment($(this).attr('datetime')).fromNow()); - }); - }
|
优化文章结尾布局
在文章结尾增加一个 hr
,并修改 tags
展示。在预览时也显示 tags
,并且将 Read More
按钮放置在右边。
diff:layout/common/article.ejs1 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
| <% if (!index && post.tags && post.tags.length) { %> + <hr style="height:1px;margin:1rem 0"/> <div class="level is-size-7 is-uppercase"> <div class="level-start"> <div class="level-item"> - <span class="is-size-6 has-text-grey has-mr-7">#</span> + <i class="fas fa-tags has-text-grey"></i> <%- list_tags(post.tags, { class: 'has-link-grey ', show_count: false, - style: 'link' + style: 'link', + separator: ', ' }) %> </div> </div> </div> <% } %> <% if (index && post.excerpt) { %> - <div class="level is-mobile"> + <hr style="height:1px;margin:1rem 0"/> + <div class="level is-mobile is-flex"> + <div class="level-start"> + <% if (post.tags && post.tags.length) { %> + <div class="level-item is-size-7 is-uppercase"> + <i class="fas fa-tags has-text-grey"></i> + <%- list_tags(post.tags, { + class: 'has-link-grey ', + show_count: false, + style: 'link', + separator: ', ' + }) %> + </div> + <% } %> + </div> <div class="level-start">
|
优化个人信息布局
减少头像大小,头像下方计数的地方增加链接,follow前增加icon。
diff:layout/widget/profile.ejs1 2 3 4 5 6 7
| - <nav class="level is-mobile"> + <nav class="level menu-list is-mobile" style="margin-bottom:1rem"> <div class="level-item has-text-centered is-marginless"> - <div> + <a href="<%- url_for('/archives/') %>"> <p class="heading"> ......
|
优化移动端显示
在移动端,隐藏 archive
和 tagcloud
。
diff:layout/widget/archive.ejs1 2
| -<div class="card widget"> +<div class="card widget is-hidden-mobile">
|
diff:layout/widget/tagcloud.ejs1 2
| -<div class="card widget"> +<div class="card widget is-hidden-mobile">
|
目录粘性布局
增加 column-left is-sticky
类。
diff:layout/widget/toc.ejs1 2
| -<div class="card widget" id="toc"> +<div class="card widget column-left is-sticky" id="toc">
|
功能
增加版权说明
diff:layout/common/article.ejs1 2 3 4 5 6 7 8 9 10 11 12 13 14
| <div class="content"> <%- index && post.excerpt ? post.excerpt : post.content %> </div> + <% if (!index && post.layout === 'post' && post.copyright !== false) { %> + <ul class="post-copyright"> + <li><strong>本文标题:</strong><a href="<%= post.permalink %>"><%= page.title %></a></li> + <li><strong>本文作者:</strong><a href="<%= theme.url %>"><%= theme.author %></a></li> + <li><strong>本文链接:</strong><a href="<%= post.permalink %>"><%= post.permalink %></a></li> + <li><strong>发布时间:</strong><%= post.date.format("YYYY-MM-DD") %></li> + <li><strong>版权声明:</strong>本博客所有文章除特别声明外,均采用 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/deed.zh" rel="external nofollow" target="_blank">CC BY-NC-SA 4.0</a> 许可协议。转载请注明出处! + </li> + </ul> + <% } %> <% if (!index && post.tags && post.tags.length) { %>
|
并增加样式
diff:source/css/style.styl1 2 3 4 5 6 7 8
| +.post-copyright + font-size: 1rem + letter-spacing: 0.02rem + word-break: break-all + margin: 2.5rem 0 0 + padding: 1rem 1rem + border-left: 3px solid #FF1700 + background-color: #F9F9F9
|
增加标题自动计数
diff:source/css/style.styl1 2 3 4 5 6 7
| +.article {counter-reset:section} +.article h2{counter-reset:sub-section} +.article h3{counter-reset:composite} +.article h4{counter-reset:detail} +.article h2:before{content:counter(section) " ";counter-increment:section} +.article h3:before{content:counter(section) "." counter(sub-section) " ";counter-increment:sub-section} +.article h4:before{content:counter(section) "." counter(sub-section) "." counter(composite) " ";counter-increment:composite}
|
默认显示目录
正常开启目录需要在 meta
信息中加入 toc: true
开启,但绝大部分文章都是有目录的,因此修改为默认开启。因为有多个地方引用了 get_config('toc')
并且需要判断当前页面,改起来稍微麻烦一些,因此直接修改了 get_config
方法。
diff:includes/helpers/config.js1 2 3 4 5 6 7
| return defaultValue; } else { const property = readProperty(specs, configName); - return property === null ? null : property[descriptors.defaultValue]; + const result = property === null ? null : property[descriptors.defaultValue]; + return (configName === 'toc' && this.page.layout === 'post' && result === null) ? true : result; }
|
默认情况下一个icon对应一个链接,但例如 CC BY-NC-SA 4.0
需要四个图标一组。因此修改代码,使得配置 link.icon
可以是一个数组,效果可以参考页面底部。
diff:layout/common/footer.ejs1 2 3 4
| <% } else { %> - <i class="<%= link.icon %>"></i> + <% for (let icon of (Array.isArray(link.icon) ? link.icon : [link.icon])) { %><i class="<%= icon %>"></i> <% } %> <% } %>
|
diff:includes/specs/icon_link.spec.js1 2 3 4 5
| icon: { [required]: true, - [type]: 'string', + [type]: ['string', 'array'], [doc]: 'Link icon class names'
|
_config.yml
中配置如下
_config.yml1 2 3 4 5 6 7 8 9
| footer: links: CC BY-NC-SA 4.0: icon: - fab fa-creative-commons - fab fa-creative-commons-by - fab fa-creative-commons-nc - fab fa-creative-commons-sa url: 'https://creativecommons.org/licenses/by-nc-sa/4.0/'
|
可以配置文章开头是否显示图片
Icarus
支持文章设置一个图片,在文章开头、最近的文章、时间线等地方显示。但有些图放大之后会显得很不协调,因此修改以支持自定义是否显示。修改 has_thumbnail
方法,增加参数 isArticle
参数,默认 false
,并在文章页面修改调用参数。
diff:includes/helpers/page.js1 2 3 4 5 6 7 8 9 10 11
| - hexo.extend.helper.register('has_thumbnail', function (post) { + hexo.extend.helper.register('has_thumbnail', function (post, isArticle = false) { const getConfig = hexo.extend.helper.get('get_config').bind(this); const allowThumbnail = getConfig('article.thumbnail', true); if (!allowThumbnail) { return false; } + if (isArticle && post['article-thumbnail'] === false){ + return false; + } return post.hasOwnProperty('thumbnail') && post.thumbnail;
|
diff:layout/common/article.ejs1 2 3 4
| <div class="card"> - <% if (has_thumbnail(post)) { %> + <% if (has_thumbnail(post, true)) { %> <div class="card-image">
|
这样修改之后,如果文章 meta
信息中包含 article-thumbnail: false
,就可以取消图片的显示。
样式
修改 logo 和 favicon
用 Python 设计 Logo,并微调样式。
按钮背景颜色增加渐变
diff:source/css/style.styl1 2 3 4 5 6
| .menu-list li ul margin-right: 0 + .menu-list a + transition: background-color 0.3s ease-in-out .menu-list a.level display: flex
|
card 增加浮动效果
:hover
时增大阴影,并增加动画属性 ease-in-out
。
diff:source/css/style.styl1 2 3 4 5
| .card border-radius: 4px box-shadow: 0 4px 10px rgba(0,0,0,0.05), 0 0 1px rgba(0,0,0,0.1) + &:hover + box-shadow: 0 6px 15px rgba(0,0,0,0.15), 0 0 1px rgba(0,0,0,0.1)
|
diff:source/js/animation.js1 2 3
| element.style.transform = ''; - element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out'; + element.style.transition = 'opacity 0.3s ease-out, transform 0.3s ease-out, box-shadow 0.3s ease-in-out';
|
更新
2020-02-16
合并了 2.7.0 版本,冲突不算太多,有两个点需要注意一下。
icarus
的配置里面,plugins.clipboard
需要移除,相关的配置移动到 article.highlight.clipboard
。
_config.yml1 2 3 4 5 6 7 8 9 10
| article: highlight: theme: github-gist clipboard: true fold: unfolded
|
如果之前 links widget 没有配置链接,可能会遇到编译错误,需要增加一下判断。
diff:layout/widget/links.locals.js1 2 3 4 5
| const links = get_config_from_obj(locals.widget, 'links'); - if (Object.keys(links).length == 0) { + if (!links || Object.keys(links).length == 0) { return null; }
|
总结
这里只列举了部分改动,详细的差异可以查看 diff。
本文会持续更新,保持跟最新的博客效果一致,希望能给你自定义主题一些帮助。
如果有其他想法或者意见,可以在下方留言。
😊