hugo建站全指南 | 我的第一个博客网站

前言

建博客的初衷?

2020年八月的第一天,我还是像往常一样打开我的域名,本以为还是会像以前一样显示每日一图的界面,结果出现的却是破图,当即开始打开服务器进行一番检查,发现是一直在使用的词霸API接口挂掉了(结果两天后又恢复正常了囧),这样一来就意味着我的域名现在闲下来了😢 这时候,一个想法闪过我的脑海 ————

是时候开始做自己的博客网站了!

在这之前,由于平时比较忙,并且搭建博客需要投入一定的精力,加上已经有现成的博客园平台可以供自己记录博客,因此,考虑到时间成本以及学习成本,就一直搁置了博客网站这件事.

why hugo?

hugo-logo-wide

Hugo是由Go语言实现的静态网站生成器。通过 Hugo 你可以快速搭建你的静态网站,比如博客系统、文档介绍、公司主页、产品介绍等等。相对于其他静态网站生成器(例如hexo)来说,Hugo 具备如下特点:

  • 极快的页面编译生成速度。( ~1 ms 每页面)
  • 完全跨平台支持,可以运行在 Mac OS X, Linux, Windows, 以及更多!
  • 安装方便 Installation
  • 本地调试 Usage 时通过 LiveReload 自动即时刷新页面。
  • 完全的皮肤支持。
  • 可以部署在任何的支持 HTTP 的服务器上。

hugo的基本使用

基本环境 go、git、github
安装方法 官网下载对应版本的源码,添加到环境变量
生成博客 hugo new site 博客名
下载主题 git clone
设置主题 echo ‘theme = “cactus”’ » config.toml
启动博客 hugo server -w
新建文章 hugo new post/文章名.md
生成public目录 hugo -D

快速部署基本设置

博客的基本设置可以通过对应主题的GitHub帮助文档进行一步步设置,也可以走捷径,直接替换博客项目下的config.toml为主题文件中exampleSite下的config.toml文件,接着在config.toml中的对应位置修改自己的设置:

baseURL = "https://billie52707.cn"
languageCode = "en-us"
title = "人人都爱小雀斑's blogs"
theme = "cactus"
copyright = "billie" # cactus will use title if copyright is not set
disqusShortname = "example" # Used when comments is enabled. Cactus will use site title if not set
# googleAnalytics = "UA-1234-5"

文章添加标签和分类

以你现在看到的这篇文章为例,新建一篇文章之后,如果想加入标签,可以在每篇文章的页首这样设置:

title: "hugo建站 | 我的第一个博客网站"
date: 2020-08-04T18:42:17+08:00
categories:
- tec
tags:
- hugo

ps:注意-后面有一个空格

页脚信息的编辑

以我现在使用的cactus主题为例,页脚配置文件位于:cactus/layouts/partials/footer.html,编辑如下:

<footer id="footer">
  <div class="footer-left">
    Copyright  
    &copy; 
    {{ now.Format "2006" }} 
    <span>❤️{{ if .Site.Copyright }} {{ print .Site.Copyright }} {{ else }} {{ print .Site.Title }} {{ end }} | </span>  
    <span>粤ICP备20025795号-1 | </span>
    <span>Powered By Hugo | </span>
    <span id="busuanzi_container_site_pv">
        pv:<span id="busuanzi_value_site_pv"></span> | 
    </span>
    <span id="busuanzi_container_site_uv">
        uv: <span id="busuanzi_value_site_uv"></span> 
    </span>
  </div>
</footer>

网站流量统计

工具:不蒜子,一个通过仅仅两行代码实现的网页流量计数器

1、在/cactus/layouts/partials/head.html文件中引入不蒜子js文件

<!-- 不蒜子 -->
<script async src="//busuanzi.ibruce.info/busuanzi/2.3/busuanzi.pure.mini.js"></script>

2、在页面添加统计代码,在/cactus/layouts/partials/footer.html中添加如下代码

<span id="busuanzi_container_site_pv">
    本站访问量:<span id="busuanzi_value_site_pv"></span>次
</span>
&nbsp;
<span id="busuanzi_container_site_uv">
    您是本站第 <span id="busuanzi_value_site_uv"></span> 位访问者
</span>

3、设置文章阅读数,在/cactus/layouts/posts/single.html中,大概35行的位置,添加如下代码

<div class="article-tag">
            <i class="fa fa-eye"></i> 
            <span id="busuanzi_container_page_pv">
              <span id="busuanzi_value_page_pv">0</span>
            </span>
        </div>

具体显示效果可移步此文章页首标题处查看

4、设置文章字数和阅读时间,在/cactus/layouts/_default/single.html中添加以下代码

<h5 id="wc" style="font-size: 1rem;text-align: center;">{{ .FuzzyWordCount }} Words|Read in about {{ .ReadingTime }} Min|本文总阅读量<span id="busuanzi_value_page_pv"></span>次</h5>

首页添加每日一图

python+hugo+nginx | 实现博客主页每日一图

添加评论系统Valine

Valine - 一款快速、简洁且高效的无后端评论系统。

Valine 诞生于2017年8月7日,是一款基于Leancloud的快速、简洁且高效的无后端评论系统。

理论上支持但不限于静态博客,目前已有Hexo、Jekyll、Typecho等博客程序在使用Valine。

特性:

  • 快速
  • 安全
  • Emoji 😉
  • 无后端实现
  • MarkDown 全语法支持
  • 轻量易用(~15kb gzipped)
  • 文章阅读量统计 v1.2.0-beta1+

Tips:

  • 整个过程,是以cactus主题为例的,其它主题操作大同小异。
  • 配置之前应该先阅读Valine快速开始

Leancloud相关配置:

评论系统依赖于leancloud,所以需要先在leancloud中进行相关的准备工作。

  • 登录注册 LeanCloud
  • 登录成功后,进入后台点击左上角的创建应用
  • 创建好应用,进入应用,左边栏找到 设置 ,然后点击 应用Key,此时记录出现的 App IDApp Key,后面配置文件中会用到
  • 因为评论和文章阅读数统计依赖于存储,所以还需要建立两个新的存储 Class,左边栏找到并点击 存储,点击 创建Class
  • 创建两个存储Class,分别命名为: CounterComment
  • 为应用添加安全域名,左边栏点击 设置,找到 安全中心,点击后会看到 安全域名 设置框,输入博客使用的域名,点击保存即可

添加 Valine 参数项:

  # Valine.
  # You can get your appid and appkey from https://leancloud.cn
  # more info please open https://valine.js.org
  [params.valine]
    enable = true
    appId = '你的appId'
    appKey = '你的appKey'
    notify = false  # mail notifier , https://github.com/xCss/Valine/wiki
    verify = false # Verification code
    avatar = 'mm' 
    placeholder = '说点什么吧...'
    visitor = true

上面几项内容的含义,这里简单一说,具体还是要看 Valine官网中配置相关的内容

参数 用途
enable 这是用于主题中配置的,不是官方Valine的参数,true时控制开启此评论系统
appId 这是在 leancloud 后台应用中获取的,也就是上面提到的 App ID
appKey 这是在 leancloud 后台应用中获取的,也就是上面提到的 App Key
notify 用于控制是否开启邮件通知功能,具体参考邮件提醒配置
verify 用于控制是否开启评论验证码功能
avatar 用于配置评论项中用户头像样式,有多种选择:mm, identicon, monsterid, wavatar, retro, hide。详细参考:头像配置
placehoder 评论框的提示符
visitor 控制是否开启文章阅读数的统计功能i, 详情阅读文章阅读数统计

修改主题文件:

主要是修改主题中评论相关的布局文件 themes/even/layouts/partials/comments.html,按照 Valine快速开始 添加 Valine 相关代码,找到以下位置,大概55~81行的位置:

  <!-- gitment -->
  {{- if .Site.Params.gitment.enable -}}
  <div id="comments-gitment"></div>
  <!--这里省略了部分代码-->
  <noscript>Please enable JavaScript to view the <a href="https://github.com/imsun/gitment">comments powered by gitment.</a></noscript>
  {{- end }}

  <!--这个位置添加Valine相关代码-->

添加的 Valine 评论的代码如下:

  <!-- valine -->
  {{- if .Site.Params.valine.enable -}}
  <!-- id 将作为查询条件 -->
  <span id="{{ .URL | relURL }}" class="leancloud_visitors" data-flag-title="{{ .Title }}">
    <span class="post-meta-item-text">文章阅读量 </span>
    <span class="leancloud-visitors-count">1000000</span>
    <p></p>
  </span>
  <div id="vcomments"></div>
  <script src="//cdn1.lncld.net/static/js/3.0.4/av-min.js"></script>
  <script src='//unpkg.com/valine/dist/Valine.min.js'></script>
  <script type="text/javascript">
    new Valine({
        el: '#vcomments' ,
        appId: '{{ .Site.Params.valine.appId }}',
        appKey: '{{ .Site.Params.valine.appKey }}',
        notify: {{ .Site.Params.valine.notify }}, 
        verify: {{ .Site.Params.valine.verify }}, 
        avatar:'{{ .Site.Params.valine.avatar }}', 
        placeholder: '{{ .Site.Params.valine.placeholder }}',
        visitor: {{ .Site.Params.valine.visitor }}
    });
  </script>
  {{- end }}

可以看到上述代码中引用了配置文件中的相关参数,这样以后修改配置就不用修改代码了,只需要改配置文件 config.toml,另外注意到的是,我也添加了文章阅读数统计的显示内容。将配置文件中 valine 配置的 eanble 设置为 true

上传代码到GitHub

上传代码这部分我选择的方案是把相关git代码写进一个可执行文件下,然后后面更新博客的话运行这个可执行文件就行了,步骤如下:

  1. 在GitHub创建一个仓库,并命名为your_github_id.github.io,注意your_github_id一定要小写
  2. 在博客项目目录下新建文件deploy.sh
  3. 打开deploy.sh并编辑
hugo -D #打包成静态文件目录public

cd public #切换到public目录
git init
git remote rm origin

git remote add origin https://github.com/your_github_id/your_github_id.github.io.git #链接到你的GitHub博客项目

git add .
git commit -m "update"
echo "Pushing to github"
git pull origin master

git push -u origin +master

为你的博客添加一个域名(GithubPages)

上传代码到GitHub之后,在GitHub项目下新建一个’CNAME’文件,打开并编辑,在第一行写入你的域名(所以你要先有一个域名,并备案),比如我的就是billie52707.cn,这一步目的是做一个域名的关联,当你访问你的域名的时候,就会关联到你的博客项目来。

接着,以阿里云为例,在这之前,你的域名已经备案好了,登录阿里云,进入你的域名列表,在域名右侧点击解析,点击添加安全组,新手引导,在记录值输入你的博客项目GitHub pages的IP地址,IP地址可以通过终端输入ping your_github_id.github.io获取。

添加字数统计

作为一个静态网页生成器,Hugo 为使用者提供了很多与网页相关的模板变量,而与文章字数相关的模板变量有两个:

  • .FuzzyWordCount: 文章内容的大致单词数 (字数)
  • .WordCount: 文章内容的单词数 (字数)

我们可以看到 .FuzzyWordCount 提供的是一个大概的值 (整 100),比如 1 个字算 100 字,2 个字还算 100 字,201 个字算 200 字。这样统计出来的字数可能会比实际情况更多一点,虽然更有牌面但全都是整数未免也太假了。所以我还是决定使用 .WordCount

image-20200816082207539

参考用法,在html文件中任意位置添加:

{{ .FuzzyWordCount }} Words | Read in about {{ .ReadingTime }} Min

更多与模板变量相关信息请参考:Variables and Params

终极优化,部署博客到阿里云oss

部署博客有很多选择,国内外都有很多服务可以用,各有各的优缺点:

GithubPages 码云Pages Netlify Heroku 阿里云OSS
纯静态托管 否👍
CDN加速 是👍 是👍
访问速度 快👍 一般 一般 很快👍
支持404重定向 是👍 是👍 是👍 是👍
自定义重定向 是👍 是👍

具体选择哪个,根据个人对博客的需求进行选择。

  • 访问速度快:优先选择阿里云(国内CDN加速)、其次是码云(国内服务器)
  • 功能最强:Heroku(支持Node.js、PHP等后端)

鉴于本人较追求响应速度,因此毫不犹豫选择了部署到阿里云,下面是一些关于部署的简单过程:

部署思路

  1. 提交代码到GitHub
  2. 开通阿里云oss,创建bucket
  3. 通过GitHub Actions同步博客静态文件到阿里云oss

阿里云oss

1、对象存储oss

2、创建Bucket

  • 如果你还没有创建bucket,点击新建bucket。

  • 进入新建Bucket页面,并填写Bucket信息。

  • 填写Bucket名称,选择所属地域,设置读写权限公共读。 在填写完bucket信息后点击提交,创建bucket。

3、绑定域名

  • 点击进入你创建好的bucket,在左边一栏选择传输管理,点击域名管理,绑定你的域名

  • 绑定填写时记得勾选添加CNAME

4、上传文件

  • 点击红圈标注的上传文件,会弹出文件框列表,选择需要上传的文件进行上传。
  • 将你的博客项目下public文件里的所有文件上传

5、获取accesskeyid和accesssecret

  • 这相当于账号和密码,这样你就可以使用一些第三方工具进行上传
  • 鼠标移到你的阿里云头像,进入AccessKey管理,使用子用户AccessKey,创建用户,创建时选择编程访问
  • 记住提供的AccessKeydAccessSecret,后面会用到

通过GitHub Actions同步博客静态文件到阿里云oss(2020-11-19已失效)

1、.github/workflows/main.yml

  • 将拿到的 AccessKeys配置到GitHub项目的 Secrets

    登录GitHub,进入博客项目,Setting,Secrets,new secret,新建两个secrets,命名Name分别为ACCESS_KEY_IDACCESS_KEY_ID,填入相对应的值Value,即为上一步获取的两个值

  • 在本地博客项目下的public文件夹下新建文件:

mkdir .github/workflows && cd .github/workflows
touch main.yml
  • 编辑main.yml
# This is a basic workflow to help you get started with Actions

name: main

# Controls when the action will run. Triggers the workflow on push or pull request
# events but only for the master branch
on:
  push:
    branches: [ master ]
  pull_request:
    branches: [ master ]

# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
    - uses: actions/checkout@v1
    - uses: actions/setup-node@v1
      with:
        node-version: "12.x"
    - name: Build Blog
      run: |
        npm install
        npm install -g hexo-cli
        hexo generate
    - uses: manyuanrong/setup-ossutil@v1.0
      with:
        # endpoint 可以去oss控制台上查看
        endpoint: "oss-cn-beijing.aliyuncs.com"
        # 使用我们之前配置在secrets里面的accesskeys来配置ossutil
        access-key-id: ${{ secrets.ACCESS_KEY_ID }}
        access-key-secret: ${{ secrets.ACCESS_KEY_SECRET }}
    - name: Deply To OSS
    	# oss的路径参考你的阿里云对象存储的bucket名称
      run: ossutil cp ./ oss://billie-s-blog/ -rf

2、提交代码到GitHub

提交成功之后可进入项目下的Actions选项,查看任务日志,如果不出错,则已成功同步到阿里云oss image-20200816082017220

PicGO+阿里云oss 图床搭建

考虑到自己写博客的需要,以及方便管理等原因,需要寻找一个方便的图床用来存储图片

创建对象存储OSS、bucket

在阿里云里面开通对象存储只是表明你开通了对象存储的功能。而bucket (桶)才是真正用于存东西的容器

  1. 创建对象存储OSS
  2. OSS控制台创建bucket,注意:在读写权限那里选用“公共读”,这样才能使用链接直接访问我们所存储的图片。

配置PicGo

PicGo下载

  1. 切换到阿里云图床的配置页面,填写配置信息,keyid和keysecret就是上节提到的accesskey与secret。存储空间名指你用来当作图床的bucket名。 存储区域按照你创建时候的区域来填写。存储路径可以写img/,后面一定要加斜杠。 最后两项不用填写。

    image-20200816083128131

  2. 然后就可以使用picgo方便地上传图片了。上传完成之后会自动把格式化的图片链接放到你的粘贴板里~~这样就可以很快地向md里插入图片了

    image-20200816083200101

Typora配置图片自动上传

typora是首选的markdown编辑器,如果使用的是 Typora 作为 Markdown 编辑器,可以参考下面步骤配置图片自动上传到OSS中:

打开偏好设置 -> 图像 ,更改 插入图片时... 选择上传图片 。下面的上传服务设定,选择你的图床工具软件,点击验证图片上传选项

image-20200816084241007

出现这个就代表成功了image-20200816084337982

在后续的使用中,截图粘贴或添加图片到typora中,就会直接上传图片到阿里云oss,yes!

从http到https

从http到https

让Google和百度搜索到你的博客

Google Search Console

打开Google Search Console,点击 “SEARCH CONSOLE ” 进入,然后添加资源。

会要求下载一个html文件如google571325××××.html做验证,将这个文件保存到hugo站点根目录下的static子目录,更新站点内容让google search console可以访问到进行验证即可。

进入资源页面,点”索引”下的”站点地图”,在”添加新的站点地图”处输入当前hugo站点的sitemap,这个文件hugo会默认生成,就在根路径下,如https://billie52707.cn/sitemap.xml

百度搜索资源平台

打开 百度搜索资源平台 ,点击 链接提交,然后点”添加站点”。同样可以用文件验证的方式来进行网站验证。

进入”资源提交”下的”普通收录”,再点“sitemap”,在这里可以提交hugo网站的sitemap文件。

btw,百度不容许以子目录的方式提交子站点,和google不一样,只能在提交sitemap文件时,提交多个sitemap文件。这样也能勉强让百度收录。

支持插入echarts图表

  1. 在目录 ./themes/cactus/layouts/shortcodes下创建文件echarts.html,并编辑

    <div id="echarts{{ .Get `height` }}" style="width: 100%;height: {{.Get `height`}}px;margin: 0 auto"></div>
        <script src="https://cdn.bootcss.com/echarts/3.8.0/echarts.common.min.js"></script>
        <script type="text/javascript">
            // 基于准备好的dom,初始化echarts实例
            var myChart = echarts.init(document.getElementById('echarts{{ .Get `height` }}'));
            // 指定图表的配置项和数据
            var option = JSON.parse({{ .Inner }})
            // 使用刚指定的配置项和数据显示图表。
            myChart.setOption(option);
        </script>
    
  2. 在你的文章(md文件)任意处插入echarts的配置数据,注意echarts标签与左侧右侧的大括号之间没有空格,下方的演示代码需修改

    {{ <echarts height="500"> }}
            {"title":{"text":"ECharts 入门示例"},"tooltip":{},"legend":{"data":["销量"]},"xAxis":{"data":["衬衫","羊毛衫","雪纺衫","裤子","高跟鞋","袜子"]},"yAxis":{},"series":[{"name":"销量","type":"bar","data": [5, 20, 36, 10, 10, 20]}]}
    {{ </echarts> }}
    

示例1:

示例2:

示例3:

定制文章详情页的访问链接

方法1:编辑config.toml

参考官方文档:https://www.gohugo.org/doc/extras/permalinks/

在config.toml文件中编辑以下代码,如不编辑,则访问链接默认为文件路径+文章命名

permalinks:
  post: /:year/:month/:title/
  • :year the 4-digit year
  • :month the 2-digit month
  • :monthname the name of the month
  • :day the 2-digit day
  • :weekday the 1-digit day of the week (Sunday = 0)
  • :weekdayname the name of the day of the week
  • :yearday the 1- to 3-digit day of the year
  • :section the content’s section
  • :title the content’s title
  • :slug the content’s slug (or title if no slug)
  • :filename the content’s filename (without extension)

方法2:slug

还有一个办法是编辑文章头信息时加上slug: 路由

如下:image-20201106211630640

image-20201106211904637

全新板块:NCP(新冠疫情实时数据)

NCP | 新冠疫情的监测与趋势分析

image-20201207234437761

文章页添加标签词云

贴一张效果图先

image-20201121111804399

  1. themes\cactus\layouts\partials目录下新建词云文件tagcloud.html,并编辑

    <div id="theme-tagcloud" class="tagcloud-wrap">
        {{ $tags := $.Site.Taxonomies.tags.Alphabetical }}
        {{ $v1 := where $tags "Count" ">=" 1 }}
        {{ $v2 := where $v1 "Term" "not in" (slice  "tags" "rss" "weekly") }}
        {{ range $v2 }}
        {{ if .Term }}
        {{ $tagURL := printf "tags/%s" .Term | relURL }}
       
        {{$tagSize := 12}}
        {{if gt .Count 5}}
        {{ $tagSize = 16 }}
        {{end}}
       
        {{if gt .Count 10}}
        {{ $tagSize = 22 }}
        {{end}}
       
        {{if gt .Count 20}}
        {{ $tagSize = 24 }}
        {{end}}
       
        {{if gt .Count 30}}
        {{ $tagSize = 26 }}
        {{end}}
       
        {{if gt .Count 45}}
        {{ $tagSize = 28 }}
        {{end}}
       
        {{if gt .Count 65}}
        {{ $tagSize = 30 }}
        {{end}}
       
       
        <style> a {text-decorationnone}</style>
        <a href="{{ $tagURL }}" style="font-size:{{ $tagSize }}px; text-transform:capitalize;text-decoration: none!important;">
            {{ .Term }}<!-- <span class="badge">({{ .Count }})</span>  -->
        </a>
               
          
        {{ end }}
        {{ end }}
    </div>
    <style>
     .tagcloud-wrap{
        overflow: hidden;
    }
     .tagcloud-wrap a,.tagcloud-wrap a:hover {
        background-image: none;
        -webkit-text-size-adjust:none; 
        white-space:nowrap;
        line-height: 23px;
        margin-right: 10px;
        margin-bottom: 4px;
        float: left;  
    }
    </style>
    
  2. themes\cactus\layouts\_default\list.html文件中添加词云模块

    {{ partial "tagcloud.html" . }}
    

    image-20201121112709702

  3. 完事!上线🌹

插入B站视频

众所周知,B 站允许使用 <iframe> 标签将视频嵌入到别的网站上, Hugo 允许自定义 Shortcodes,我们可以利用 Shortcodes 将插入 B 站视频标准化,在保证安全的同时方便用户使用。

  1. themes\cactus\layouts\partials目录下新建文件bilibili.html,编辑如下

    <style>
     /*// 嵌入 BiliBili 视频*/
     #bilibili {
       width: 100%;
       height: 550px;
     }
     @media only screen and (min-device-width: 320px) and (max-device-width: 480px) {
       #bilibili {
         width: 100%;
         height: 250px;
       }
     }
    </style>
       
    {{ $videoID := index .Params 0 }}
    {{ $pageNum := index .Params 1 | default 1}}
       
    {{ if (findRE "^[bB][vV][0-9a-zA-Z]+$" $videoID) }}
    <div><iframe id="bilibili" src="//player.bilibili.com/player.html?bvid={{ $videoID }}&page={{ $pageNum }}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" loading="lazy" > </iframe></div>
    {{ else }}
    <div><iframe id="bilibili" src="//player.bilibili.com/player.html?aid={{ $videoID }}&page={{ $pageNum }}" scrolling="no" border="0" frameborder="no" framespacing="0" allowfullscreen="true" loading="lazy" > </iframe></div>
    {{ end }}
       
    
  2. 用法

    image-20201123193959533

站内搜索插件

https://jimmysong.io/hugo-handbook/steps/searching-plugin.html?q=

新模块"Most recent" - 记录今日新更新、有修改的的文章

  • 业务代码 - billie52707.py
  • 技术栈 - python、css

image-20210520162322159

移动端,将list.html文章列表的显示样式设为不换行显示:display:inline;

<style>
@media screen and (max-width: 500px) {
    #archive .post-list .post-item .meta{
		display: inline!important;
	}
}
</style>

后记

updated by 2021-05-20 16:00


8814 字