Hexo_Butterfly主题详解_配置文件_插件_修改_笔记


  • Hexo_Butterfly 主题详解 配置文件_ 插件 _ 修改_ 笔记

    我的博客折腾的差不多了,感觉有必要整理和总结一下,以笔记的形式写在这里了。里面有关于如何配置相关选项,我用到的插件,以及如何diy相关的东西。笔记里的配置文件有些直接来自官网。

    我用了butterfly这个主题,这个主题非常好看,而且也不感觉花里胡哨,设置里有很多东西可调,但是有些细节需要自己调一下,比如说页面标题颜色、有些页面太空旷,需要加张图什么的。我的原则是尽量不修改模板,这样更新主题的时候比较方便,不用merge,兼容性比较好。因此我的做法是,通过前端css的覆盖来调整样式,没法调整的用js方法来动态改变,包括评论系统也是这么动态加进来的。

    1. 常用插件安装

    npm install -g hexo-cli
    npm install hexo-deployer-rsync --save
    npm install hexo-deployer-sftp --save
    npm install hexo-asset-link --save # markdown显示图片用,图片要放在同名文件夹里
    npm install hexo-generator-category --save
    npm install hexo-generator-tag --save
    npm install hexo-hide-posts --save # 文章隐藏,但是可以通过链接访问
    npm install hexo-generator-search --save # 本地搜索
    npm install hexo-blog-encrypt --save #  加密文章
    npm install hexo-abbrlink --save # 自定义链接
    
    npm install hexo-wordcount --save # 字数统计
    npm install hexo-renderer-marked --save # 用于自己解析markdown
    npm install hexo-myadmin --save # 后台管理界面
    
    npm install hexo hexo-filter-nofollow --save # seo
    npm install hexo-generator-seo-friendly-sitemap --save
    npm install hexo-generator-baidu-sitemap --save
    npm install hexo-submit-urls-to-search-engine --save
    

    2. Hexo 结构

    ├── _config.yml
    ├── package.json
    ├── scaffolds # Hexo的模板是指在新建的文章文件中默认填充的内容
    ├── source # Markdown和HTML文件会被解析并放到 public 文件夹,而其他文件会被拷贝过去。
    | ├── _drafts # 除了_draft, _posts外,带下划线的不会被解析到public里
    | └── _posts # 博客文章存放位置
    | └── xxx # hexo new page xxx 生成的,里面可以是任意文件可路由到,_开头的貌似不行
    └── themes # 主题 文件夹。Hexo 会根据主题来生成静态页面。
    ├── _config.yml
    ├── languages
    ├── layout # 布局文件夹。用于存放主题的模板文件,swig,ejis等
    ├── scripts # 启动时加载
    └── source # 除了模板以外的 Asset,例如 CSS、JavaScript 文件等,与上面source挂在路径同

    • source中的Mardown和HTML文件都会被解析生成到public文件夹下,会自动递归解析子文件夹,

    • 网址url则是通过插件abbrlink和permalink生成。

    • 除了_draft, _posts外,带下划线的不会被解析到public里。

    3. Hexo CLI

    hexo init <folder>
    cd <folder>
    npm install
    
    hexo list <type> # version
    hexo new xxx # 新建一篇文章,title之后可以在markdown里改
    hexo new page xxx # 创建任意页面,在/source/xxx 路径下可有/xxx路由到
    hexo new page tags # 创建标签页,执行这行指令后才会生成对应的index.html下同
    hexo new page categories # 创建目录页,在/source文件内,需要自己添加type: "categories"
    hexo new draft <title> # 新建草稿
    hexo publish [layout] <filename> [-d] # hexo g 发表草稿。-d 文件生成后立即部署网站
    hexo g/generate # 移动静态文件 new page categories
    hexo s/server [-p port] [-g] [-s] # 搭建服务器, -g generate, -s 静态模式
    hexo d/deploy [-g] # 推送博客到远程仓库
    hexo clean # 清除缓存文件 (db.json) 和已生成的静态文件 (public)。
    

    4. _config.yml 配置文件

    (1) post Front-matter

    # 博客文章相关的内容,yml格式
    --- 
    title: hello_world
    hide: true # hexo-hide-posts 插件设置
    date: yyyy-mm-dd hh:mm:ss
    updated: # 更新日期
    tags: ["hello world", "initial page"]
    abbrlink: # 覆盖文章网址,hexo-abbrlink
    ---
    

    (2) original hexo config

    # Site
    title: ''
    subtitle: ''
    description: ""
    keywords: ''
    author: devseed
    language: en
    email: # 配置可以留空
    timezone: ''
    
    url: ''
    root: /
    permalink :title/ # 文章链接前缀, permalink: posts/:abbrlink/
    post_asset_folder: true # 提交资源文件夹
    relative_link: false # 用相对路径,一定要false,否则加载可能出错
    categories: # 目录
    date_format: YYYY-MM-DD HH:mm # 显示的时间格式
    theme: landscape
    
    # Directory
    source_dir: source
    public_dir: public
    tag_dir: tags
    archive_dir: archives
    category_dir: categories
    code_dir: downloads/code
    i18n_dir: :lang
    skip_render: "static/*" # 这个路径里的html, js等不会被加入代码渲染,保持原样
    
    # index 
    index_generator:
      path: ''
      per_page: 8
      order_by: -updated # update更新日期,date文章日期
    

    (3) hexo-deployer-sftp

    deploy:  # 所有路径必须是绝对路径,可有多个type
      - type: sftp
        host: <host>
        user: <user>
        pass: <password>
        remotePath: [remote path]
        port: [port]
        privateKey: [path/to/privateKey]
        passphrase: [passphrase]
        agent: [path/to/agent/socket]
    

    (4) hexo-hide-posts

    hide_posts: 
      filter: hide # Change the filter name to fit your need
      # Generators which you want to expose all posts (include hidden ones) to.
      # Common generators: index, tag, category, archive, sitemap, feed, etc.
      public_generators: []
      noindex: true   # Add "noindex" meta tag to prevent hidden posts from being indexed by search engines
    

    (5) hexo-generator-search

    search: 
      path: search.xml
      field: post
      content: true
    

    (6) hexo-abbrlink

    abbrlink: #abbrlink配置
      alg: crc16  # suanfa:crc16(default) and crc32
      rep: dec    # jinzhi:dec(default) and hex
    

    (7) hexo-myadmin

    admin: # pm2 start node_modules/.bin/hexo -- server
      username: myfavoritename
      password_hash: '' # bcrypt hash
      secret: yoursecret
    

    (8) seo

    nofollow: # 防止无关链接分散权重
      enable: true
      field: site
      exclude: # 友链部分加在此处
    
    baidusitemap:
      path: baidusitemap.xml
    
    sitemap:
      path: sitemap.xml
    

    5. butterfly

    (1) 安装

    git clone -b master https://github.com/jerryc127/hexo-theme-butterfly.git themes/Butterfly
    npm install hexo-renderer-pug hexo-renderer-stylus --save

    把主題文件夾中的 _config.yml 複製到 Hexo 根目錄裏,同時重新命名為 _config.butterfly.yml。
    文件根目录为source路径。

    (2) _config.butterfly.yml

    menu:
      Home: / || fas fa-home
      Archives: /archives/ || fas fa-archive
      Tags: /tags/ || fas fa-tags
      Categories: /categories/ || fas fa-folder-open
      
    favicon: /img/favicon.ico # Favicon(網站圖標)
    avatar: # Avatar (頭像)
      img: /img/favicon.ico
      effect: false
    index_img: /img/banner.png # The banner image of home page
    default_top_img: /img/banner.png 
    
    mathjax:
      enable: true 
      per_page: false # false时須在使用的 Markdown Front-matter 加上 mathjax: true
    
    local_search:
      enable: true
      
    wordcount:
      enable: true
      post_wordcount: true
      min2read: true
      total_wordcount: true
    
    social: # 此项会显示在author card里面
      fab fa-github: https://github.com/xxxxx || Github # "Font Awesome 5 Brands"
      fas fa-envelope: mailto:[email protected] || Email
    
    post_meta:
      page: # Home Page
        date_type: both # created or updated or both 主頁文章日期是創建日或者更新日或都顯示
        date_format: date # date/relative 顯示日期還是相對日期
        categories: true # true or false 主頁是否顯示分類
        tags: false # true or false 主頁是否顯示標籤
        label: true # true or false 顯示描述性文字
      post:
        date_type: both # created or updated or both 文章頁日期是創建日或者更新日或都顯示
        date_format: date # date/relative 顯示日期還是相對日期
        categories: true # true or false 文章頁是否顯示分類
        tags: true # true or false 文章頁是否顯示標籤
        label: true # true or false 顯示描述性文字
    
    cover: # display the cover or not (是否顯示文章封面)
      index_enable: true
      aside_enable: true
      archives_enable: true
      position: both # the position of cover in home page,  left/right/both
      default_cover: /img/default.png  # When cover not set, the default cover 
    
    subtitle:
      enable: true
      effect: true # Typewriter Effect (打字效果)
      loop: true # loop (循環打字)
      source: false
      sub: ["by devseed"]
      
    beautify:
      enable: true
      field: site # site/post
      title-prefix-icon: '\f0c1'
      title-prefix-icon-color: "#F47466"
    
    background: rgba(183, 183, 254, 255)
    index_site_info_top: # eg: 300px/300em/300rem/10% (主頁標題距離頂部距離)
    index_top_img_height: # eg: 300px/300em/300rem (主頁top_img高度)
    
    aside:
      enable: true
      hide: true
      button: true
      mobile: true # display on mobile
      position: left # left or right
      card_author:
        enable: true
        description:
        button:
          icon: fab fa-github
          text: Follow Me
          link: https://github.com/yurisizuku
      card_announcement:
        enable: false
        content: This is my Blog
      card_recent_post:
        ...
    	
    footer:
      owner:
        enable: true
        since: 2020
      custom_text:
      copyright: true # Copyright of theme and framework
      
    lazyload: # 图片延迟加载
      enable: true
      post: /img/loading.gif
      
    inject: # 改变原有js/css/meta
      head:
        - <link rel="stylesheet" href="/hook/hook_style.css">
    
      bottom:
        - <script src="/hook/hook_style.js"></script>
        - <script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
        - <script src="https://cdn.jsdelivr.net/npm/[email protected]/marked.min.js"></script>
        - <script src="https://cdn.jsdelivr.net/gh/highlightjs/[email protected]/build/highlight.js"></script>
        - <script src="https://cdn.jsdelivr.net/npm/highlightjs-line-numbers[email protected]/dist/highlightjs-line-numbers.min.js"></script>
    

    (3) POST Front-matter

    ---
    top_img: ./hello_world/flowers.jpg # 要填写生成的网址上的路径,与markdown里的图片不同
    cover: ./hello_world/flowers.jpg 
    toc:  【可選】是否显示toc目录 (除非特定文章设置,可以不写)
    toc_number: # 是否显示toc目录数字 (除非特定文章设置,可以不写)
    sticky: 1 【可選】 置顶
    hide: true # 需要hexo-generator-indexed插件
    description:【可選】文章描述
    aside: 【可選】显示侧边栏
    comments: 【可選】顯示文章評論模塊(默認 true)
    ---
    

    (4) PAGE Front-matter

    ---
    title	【必需】頁面標題
    date	【必需】頁面創建日期
    type	【必需】tags、catagories、link
    updated	【可選】頁面更新日期
    description	【可選】頁面描述
    keywords	【可選】頁面關鍵字
    comments	【可選】顯示頁面評論模塊(默認 true)
    aside: 【可選】显示侧边栏
    top_img	【可選】頁面頂部圖片
    ---
    

    (5) fancybox 增加下载按钮(js文件)

    //http://fancyapps.com/fancybox/3/docs/
    $('[data-fancybox]').fancybox({
    	protect: false,
    	buttons : [
    		'download',
    		"slideShow",
    		'zoom',
    		'thumbs',
    		'close',]
    });
    
    $('#acg_image').append('<a data-fancybox="group" class="fancybox"><img class="fade-in"/></a>'); //动态生成fancybox块
    

    6. HOOK

    在修改butterfly配置信息里没有的内容时(比如说标题颜色),为了不修改原来框架,采取

    • 覆盖的方式改css样式(ctrl+f12审查来查找元素)
    • js动态加入hook的方式来改布局(比如说插入图片,动态增加部件,动态调整等)。

    为了方便管理,将hook内容(包括MiniComment)放到./source/hook中,生成的文件则到/public/hook中。这里有一点需要注意,就是如果用了cdn要清一下缓存,否则js和css文件可能不会立即生效。

    hook_style.js

    function remove_banner(){
      var page_header = $('#page-header');
      if(page_header.length > 0)
        page_header[0].style.background = "transparent";
    }
    
    function add_tag_img(imgsrc){
      var tag = $('.tag-cloud-list');
      tag.after('<div><img src="' + imgsrc + '"/></div>');
    }
    
    function add_catogory_img(imgsrc){
      var catogory = $('.category-lists');
      catogory.after('<div><img src="' + imgsrc + '"/></div>');
    }
    
    function add_archive_img(imgsrc){
      if($('#archive').length >= 1){
        $('#pagination').prepend('<div><img src="' + imgsrc + '"/></div>');
      } 
    }
    
    function add_home_img(imgsrc, least, max){
      if($('.recent-post-item').length <= max 
         && $('.recent-post-item').length >=least){
        $('#pagination').prepend('<div><img src="' + imgsrc + '"/></div>');
      }
    }
    
    function add_mini_comment(){ // 加载MiniComment
      var article_title = $('meta[property="og:title"]').attr('content');
      if ($('meta[article_title]').length <= 0 ){
        $($('meta')[0]).after('<meta article_title="">');
      }
      switch(article_title.toLowerCase()){
        case "home":
        case "archives":
        case "tags":
        case "catagories":
        case "about": break;
        case "comments":
          $('meta[article_title]').attr('article_title', "Comments");
          $('#page').append('<div id="mini_comment"></div>');
          $('div#mini_comment').load("/hook/ui_comment.xhtml");
          break;
        default:
          $('meta[article_title]').attr('article_title',  article_title);
          $('#post').append('<div id="mini_comment"></div>');
          $('div#mini_comment').load("/hook/ui_comment.xhtml");
          break;
      }
    }
    
    remove_banner()
    add_tag_img("hhttps://static.acgsoso.com/uploads/2020/10/32335eebe508ee49c3895b833ae7e0fd.jpg");
    add_catogory_img("https://static.acgsoso.com/uploads/2020/10/32335eebe508ee49c3895b833ae7e0fd.jpg");
    add_archive_img("https://static.acgsoso.com/uploads/2020/10/32335eebe508ee49c3895b833ae7e0fd.jpg");
    add_home_img("https://static.acgsoso.com/uploads/2020/10/32335eebe508ee49c3895b833ae7e0fd.jpg", 1, 2);
    add_home_img("https://static.acgsoso.com/uploads/2020/02/567df8ed23cd6f7da62b22589f8af589.jpg", 3, 4);
    add_mini_comment();
    

    hook_style.css

    #nav #site-name { /*左上角网站名*/
        /*text-shadow: 0.05rem 0.05rem 0.1rem #49b1f5;color: #2b36e29c;*/
        text-shadow: 0.05rem 0.05rem 0.1rem #ffffff00;
        font-weight: bold;
        cursor: pointer;
        color: #1b84c8;
    }
    
    #nav .site-page { /*网页导航标题栏*/
        position: relative;
        /*padding-bottom: 0.3rem;*/
        text-shadow: 0.01rem 0.01rem 0.01rem #ffffff11;
        font-size: 0.78em;
        font-weight: bold;
        cursor: pointer;
        color: #1b84c8;
    }
    
    #nav .menus_items .menus_item .menus_item_child li a { /*网页导航标题栏,二级菜单*/
        color: #1b84c8;
    }
    
    #nav .site-page:hover{ /*网页导航标题栏,悬浮颜色*/
        color: #49b1f5;
    }
    
    #nav.show { /*顶部导航*/
        height: 1.8em;
        line-height: 1rem;
        background: #ffffff64;
        opacity: 1;
        filter: blur(0.1px);
    }
    
    #nav.visible { /*导航栏悬浮框颜色*/
        padding-top: 0.4em;
        height: 2.2em;
        line-height: 1rem;
        align-content: center;
        --font-color: #1b84c8;
    }
    
    #page-header{ /*取消banner部分图*/
        background: transparent;
    }
    
    #page-header #site-title { /*网页标题正中央显示*/
        margin: 0;
        color: #4267c1ba;
    }
    
    #page-header #site-subtitle {  /*网页副标题*/
        font-size: 1.72em;
        color: #4267c1ba;
    }
    
    #nav { /*导航栏字体大小*/
        font-size: 1.6em;
    }
    
    #page-header.post-bg:before { /*取消各块baner*/
        position: absolute;
        top: 0;
        left: 0;
        display: block;
        width: 100%;
        height: 100%;
        background: transparent;
    }
    
    #page-header.not-index-bg { /*各块banner*/
        height: 24em;
    }
    
    #page-header.post-bg { /*博客文章标题信息框*/
        height: 24em;
    }
    
    #page-header #post-info { /*博客文章标题信息框*/
        position: absolute;
        bottom:1rem;
        padding: 0.7%;
        width: 40%;
        text-align: center;
        background: #43a1ddbd;
        align-content: center;
        left: 10%;
    }
    
    #post-info .post-title { /*博客文章标题大小*/
        margin-bottom: 0.4rem;
        font-size: 1.6em;
        font-weight: normal;
        color: var(--white);
        line-height: 1.5;
    }
    
    #page .category-lists ul li { /*分类页*/
        font-size: x-large;
    }
    
    #pagination .page-number { /*底部页码*/
        display: inline-block;
        margin: 0 0.2rem;
        min-width: 1.2rem;
        height: 1.2rem;
        text-align: center;
        line-height: 1.2rem;
        cursor: pointer;
        font-weight: 900;
        color: blueviolet;
    }
    
    #footer-wrap { /*脚注*/
        position: relative;
        padding: 0.8rem 1rem;
        color: rgba(255,255,255,0.9);
        text-align: center;
    }
    
    #recent-posts > .recent-post-item {  /*主页文章标题框大小*/
        height: 16em;
    }
    
    #pagination img.prev-cover, #pagination img.next-cover { /*预览图片透明度*/
        position: absolute;
        width: 100%;
        height: 100%;
        opacity: 0.9;
    }
    
    .relatedPosts > .relatedPosts-list .cover { /*最近添加文章预览图片透明度*/
        width: 100%;
        height: 100%;
        opacity: 0.9;
    }
    

    7. Backup

    经常备份也很重要,虽然每次手动打包不难,但是每次都要进行还是有些麻烦的,因为要去除node_modules,这里面小文件太多了。因此写了个脚本,将脚本放到hexo根目录,执行即可备份到copytodir,windows下用git bash即可运行。

    # !/bin/bash
    backupdir="./blogname[$(date +%y%m%d)]"
    copytodir=""
    echo  "$backupdir"
    mkdir "$backupdir"
    for file in `ls ./` ;do
        if [ "$file"  == "node_modules" ];then continue;fi;
        if [ "$file"  == "db.json" ];then continue;fi;
        if [ "$file"  == "public" ];then continue;fi;
        if [ "$file"  == "${backupdir##*/}" ];then continue;fi;
        echo $file
        cp -R "$file" "$backupdir"
    done
    $(7z a "${backupdir##*/}.7z" "$backupdir" -mx9)
    rm -rf $backupdir
    mv "${backupdir##*/}.7z" "$copytodir"
    
yurisbbs by @devseed since 2020, powered by nodebb.