当前位置: 首页 > 工具软件 > Icarus > 使用案例 >

Icarus主题美化

堵茂勋
2023-12-01

Icarus用户指南 - 主题美化

Icarus的主题样式编码文件为themes/icarus/layout/layout.jsx
此文件定义了站点全局的样式设置。本文详细介绍了本主题针对文章分类的详细配置说明。


自定义 Icarus 主题

主题默认是三列排列,第一列是个人信息,第二列是文章的简介或者内容,第三列是标签云等组件。 在首页的时候阅读体验也很好,但是在文章页面查看全文的时候就感觉文章内容显示有些太少。 于是打算在文章页面隐藏掉右边的侧边栏。 我想应该是我用的icarus主题版本是 3+,网上都是 2+版本的教程,没有找到对应教程。 于是就自己阅读源码自己解决了问题。 默认配置也基本能用了,但是有一个痛点就是,阅读模式文章宽度太短了,还是根据个人习惯做下配置。

解决方案

1. 首先找到了控制侧边栏的代码文件在

../themes/icarus/layout/layout.jsx

源码为(版本差别,大同小异):

const { Component } = require('inferno');
const classname = require('hexo-component-inferno/lib/util/classname');
const Head = require('./common/head');
const Navbar = require('./common/navbar');
const Widgets = require('./common/widgets');
const Footer = require('./common/footer');
const Scripts = require('./common/scripts');
const Search = require('./common/search');

module.exports = class extends Component {
    render() {
        const { env, site, config, page, helper, body } = this.props;

        const language = page.lang || page.language || config.language;
        const columnCount = Widgets.getColumnCount(config.widgets);

        return <html lang={language ? language.substr(0, 2) : ''}>
            <Head env={env} site={site} config={config} helper={helper} page={page} />
            <body class={`is-${columnCount}-column`}>
                <Navbar config={config} helper={helper} page={page} />
                <section class="section">
                    <div class="container">
                        <div class="columns">
                            <div class={classname({
                                column: true,
                                'order-2': true,
                                'column-main': true,
                                'is-12': columnCount === 1,
                                'is-8-tablet is-8-desktop is-8-widescreen': columnCount === 2,
                                'is-8-tablet is-8-desktop is-6-widescreen': columnCount === 3
                            })} dangerouslySetInnerHTML={{ __html: body }}></div>
                            <Widgets site={site} config={config} helper={helper} page={page} position={'left'} />
                            <Widgets site={site} config={config} helper={helper} page={page} position={'right'} />
                        </div>
                    </div>
                </section>
                <Footer config={config} helper={helper} />
                <Scripts site={site} config={config} helper={helper} page={page} />
                <Search config={config} helper={helper} />
            </body>
        </html>;
    }
};

三栏分别为:(从第24行开始)

  • <div class={classname({
          column: true,
          'order-2': true,
          'column-main': true,
          'is-12': columnCount === 1,
          'is-8-tablet is-8-desktop is-8-widescreen': columnCount === 2,
          'is-8-tablet is-8-desktop is-6-widescreen': columnCount === 3
      })} dangerouslySetInnerHTML={{ __html: body }}></div>  // 中
    
  • <Widgets site={site} config={config} helper={helper} page={page} position={'left'} />  // 左
    
  • <Widgets site={site} config={config} helper={helper} page={page} position={'right'} />  //右
    
2. 那能不能逻辑改为只有主页才显示右边侧栏呢?

我从源码中分析到,函数返回return的就是样式页面。
既然找到了这3栏,我可以通过改变返回值,就可以达到控制主体样式的目的。

所以加一个判断语句即可:

if(page.path==='index.html'){   // index.html即主页面
  // 返回3栏
  return '...';
}
else{
  // 返回2栏,改变宽度即可
  return '...';
}

上面代码只会在主页面显示3栏,后续博主我在使用的过程中发现有且只有主页面是3栏;换页、分类页等页面就会变成2栏! 因为我们的代码只为主页面返回3栏!

后来在读源码后,找到了解决方法:
../themes/icarus/layout/layout.jsx 文件中第16行添加如下代码:

  console.log("Page", page);
  console.log("Page.path: ", page.path);

这样就可以查看页面具体信息;
控制台执行hexo g -d后,会出现以下信息;
由于每个page信息可能会很多,尤其是博客文章内容过多,就会使page包含的信息过多,会使控制台信息溢出;所以我只选择其中一个较短的信息展示如下:

2.1 page信息

Page:  { base: 'tags/Hexo/',
  total: 1,
  current: 1,
  current_url: 'tags/Hexo/',
  posts: _Query { data: [ [_Document], [_Document] ], length: 2 },
  prev: 0,
  prev_link: '',
  next: 0,
  next_link: '',
  tag: 'Hexo',
  path: 'tags/Hexo/index.html',
  lang: 'en',
  canonical_path: 'tags/Hexo/index.html' }

2.2 page.path信息

ubuntu~/github/mysticalguest.github.io$ hexo g -d
Inferno is in development mode.
INFO  =======================================
 ██╗ ██████╗ █████╗ ██████╗ ██╗   ██╗███████╗
 ██║██╔════╝██╔══██╗██╔══██╗██║   ██║██╔════╝
 ██║██║     ███████║██████╔╝██║   ██║███████╗
 ██║██║     ██╔══██║██╔══██╗██║   ██║╚════██║
 ██║╚██████╗██║  ██║██║  ██║╚██████╔╝███████║
 ╚═╝ ╚═════╝╚═╝  ╚═╝╚═╝  ╚═╝ ╚═════╝ ╚══════╝
=============================================
INFO  === Checking package dependencies ===
INFO  === Checking the configuration file ===
INFO  === Registering Hexo extensions ===
INFO  Start processing
INFO  Files loaded in 6.76 s
Page.path:  2020/06/18/ICARUS主题美化/
Page.path:  2020/06/17/数据结构进阶实训八/
Page.path:  2020/06/17/数据结构进阶实训五/
Page.path:  2020/06/17/数据结构进阶实训二/
Page.path:  2020/06/17/数据结构进阶实训一/
Page.path:  2020/06/17/数据结构进阶实训六/
Page.path:  2020/06/17/数据结构进阶实训七/
Page.path:  2020/06/16/Java笔记文档2/
Page.path:  2020/06/16/Java笔记文档1/
Page.path:  2020/06/15/数据结构进阶实训三/
Page.path:  2020/06/15/数据结构进阶实训四/
Page.path:  2020/06/14/hello-world/
Page.path:  archives/index.html
Page.path:  archives/page/2/index.html
Page.path:  archives/2020/index.html
Page.path:  archives/2020/page/2/index.html
Page.path:  archives/2020/06/index.html
Page.path:  archives/2020/06/page/2/index.html
Page.path:  categories/配置/index.html
Page.path:  categories/Document-Compile/index.html
Page.path:  categories/主题/index.html
Page.path:  categories/算法/index.html
Page.path:  index.html
Page.path:  page/2/index.html
Page.path:  tags/Hexo/index.html
Page.path:  tags/Java/index.html
Page.path:  tags/C/index.html
Page.path:  categories/index.html
Page.path:  tags/index.html
INFO  0 files generated in 3.37 s
INFO  Deploying: git
INFO  Clearing .deploy_git folder...
INFO  Copying files from public folder...
INFO  Copying files from extend dirs...
位于分支 master
无文件要提交,干净的工作区
分支 'master' 设置为跟踪来自 'git@github.com:*/*.git' 的远程分支 'master'。
Everything up-to-date
INFO  Deploy done: git

从控制台打印出的信息,可以明显看出每个页面的详细路径信息
所以我们想要那些页面3栏都可以;

  var path = /\Sindex.html/;
        
  if(page.path==='index.html' || path.test(page.path)){
  	// 返回3栏
    return '...';
  }
  else{
    // 返回2栏,改变宽度即可
    return '...';
  }

这里我利用正则表达式,将非博客文章页面都设为3栏显示,大家可根据自己喜好自行对想要的页面设置指定栏数。


3. 其他修改逻辑

+表示添加代码,没有标记表示代码不做修改

// 从16行开始修改代码
+ if(page.path==='index.html'){

  return <html lang={language ? language.substr(0, 2) : ''}>
      <Head env={env} site={site} config={config} helper={helper} page={page} />
      <body class={`is-${columnCount}-column`}>
          <Navbar config={config} helper={helper} page={page} />
          <section class="section">
              <div class="container">
                  <div class="columns">
                      <div class={classname({
                          column: true,
                          'order-2': true,
                          'column-main': true,
                          'is-12': columnCount === 1,
                          'is-8-tablet is-8-desktop is-8-widescreen': columnCount === 2,
                          'is-8-tablet is-8-desktop is-6-widescreen': columnCount === 3
                      })} dangerouslySetInnerHTML={{ __html: body }}></div>
                      <Widgets site={site} config={config} helper={helper} page={page} position={'left'} />
                      <Widgets site={site} config={config} helper={helper} page={page} position={'right'} />
                  </div>
              </div>
          </section>
          <Footer config={config} helper={helper} />
          <Scripts site={site} config={config} helper={helper} page={page} />
          <Search config={config} helper={helper} />
      </body>
  </html>;
+ }
+ else{
+ return <html lang={language ? language.substr(0, 2) : ''}>
+     <Head env={env} site={site} config={config} helper={helper} page={page} />
+     <body class={`is-${columnCount}-column`}>
+         <Navbar config={config} helper={helper} page={page} />
+         <section class="section">
+             <div class="container">
+                 <div class="columns">
+                     <div class={classname({
+                         column: true,
+                         'order-2': true,
+                         'column-main': true,
+                         'is-12': columnCount === 1,
+                         'is-8-tablet is-8-desktop is-10-widescreen': columnCount === 2
+                     })} dangerouslySetInnerHTML={{ __html: body }}></div>
+                     <Widgets site={site} config={config} helper={helper} page={page} position={'left'}/>
+                 </div>
+             </div>
+         </section>
+         <Footer config={config} helper={helper} />
+         <Scripts site={site} config={config} helper={helper} page={page} />
+         <Search config={config} helper={helper} />
+     </body>
+ </html>;
+ }

好啦,大工告成!

其中只有两处代码改动较大,让我们来看看吧!

我们只是修改了栏数,但每一栏的宽度没有改变,这里更关注的是文章栏的宽度。
具体修改代码下:

// 渲染相应栏的标签,只添加‘中’和‘左’
// 根据自己的喜好可以选择任意组合,‘中’和‘右’也可以
// 第45行
'is-8-tablet is-8-desktop is-10-widescreen': columnCount === 2

即将原来的 is-8-widescreen修改为is-10-widescreen


4. 下面详细解释一下代码

icarus 可以设置资料、toc、归档等等插件在文章的左侧或者右侧。也就是说,包括插件和文章在内,列数在1~3列不等:

无插件的时候,为1列;
插件统一在左侧或右侧时,为2列;
插件左、右侧都有时,为3列。
Bulma 引擎将屏幕横向分为12份,所有元素按照自己的需求使用即可。

通过 layoutwidget.jsx 文件,我们可以看到,对于插件而言:

如果屏幕分为2列,则插件的宽度为 is-4-widescreen,也即是4/12=33.33%的宽度;

如果屏幕分为3列,则插件的宽度为 is-3-widescreen,也即是3/12=25%的宽度,两列插件占了50%宽。

同样的,layout.jsx 文件针对文章也做了宽度限制:

如果屏幕分为1列,则文章的宽度为 is-12,也即是12/12=100%的宽度;

如果屏幕分为2列,则文章的宽度为 is-8-widescreen,也即是8/12=66.66%的宽度;

如果屏幕分为3列,则文章的宽度为 is-6-widescreen,也即是6/12=50%的宽度。

那么调整插件宽度的方法也就差不多想出来啦!


我的博客

GitHub博客
Gitee博客

 类似资料: