Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Hugo博客搭建教程以及配置调优

Hugo博客搭建教程以及配置调优

作者头像
慕阳MuYoung
发布于 2025-06-12 07:43:42
发布于 2025-06-12 07:43:42
12500
代码可运行
举报
文章被收录于专栏:慕阳博客慕阳博客
运行总次数:0
代码可运行

正式开始

请全程在Windows上操作

我们首先需要安装Scoop,这是一个适用于Windows的包管理器,个人认为非常好用

Scoop默认会安装到C盘,如果你想要换盘请按需更改

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
$env:SCOOP='D:\Scoop'
$env:SCOOP_GLOBAL='D:\ScoopApps'
[Environment]::SetEnvironmentVariable('SCOOP', $env:SCOOP, 'User')
[Environment]::SetEnvironmentVariable('SCOOP_GLOBAL', $env:SCOOP_GLOBAL, 'Machine')

安装Scoop:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

如果你以管理员的身份会安装失败,请切换为普通用户。若想强制以管理员身份安装Scoop请使用

github原帖

出于安全考虑,默认情况下已禁用管理员控制台下的安装。如果您知道自己在做什么并希望以管理员身份安装Scoop,请下载安装程序并在提升的控制台中手动执行它,使用 -RunAsAdmin 参数。以下是示例:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
irm get.scoop.sh -outfile 'install.ps1'
.\install.ps1 -RunAsAdmin [-OtherParameters ...]
# 如果你想要一行解决:
iex "& {$(irm get.scoop.sh)} -RunAsAdmin"

安装Hugo框架:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
scoop install hugo

然后选择一个你喜欢的文件夹创建你的站点。 myblog 即你的站点文件夹名称

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hugo new site myblog
cd myblog

安装PaperMod主题:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

站点根目录会有一个 hugo.toml。我推荐使用YAML。将文件重命名为 hugo.yaml。粘贴并更改以下内容

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
baseURL: "https://站点url"
title: "网站标题"
LanguageCode: "zh-CN"
theme: "PaperMod"

# 启用首页个人简介展示
params:
  # 是否启用评论。你需要自己配置,或者直接引入Giscus等评论系统
  comments: false
  # 是否显示代码复制按钮
  ShowCodeCopyButtons: true
  # 是否显示面包屑导航
  ShowBreadCrumbs: false
  # 是否显示阅读时间  
  ShowReadingTime: true
  # 是否显示分享按钮
  ShowShareButtons: true
  # 分享按钮配置
  # ShareButtons: ["linkedin", "twitter"]
  # 是否禁用主题切换按钮
  disableThemeToggle: false
  assets:
    favicon: "/你的/网站图标.jpg" # 需要在static文件夹放置对应的图片
    iconHeight: 35
  # 首页信息配置
  homeInfoParams:
    Title: "首页展示的标题"
    Content: >
      首页展示的文本

  # 设置网站头像和首页头像
  profileMode:
    enabled: false # 设为 true 将完全替换 homeInfoParams

  # 网站头像设置 (显示在导航栏)
  label:
    text: "左上角显示的文本"
    icon: "/你的/左上角显示的图片.jpg" # 这将显示在导航栏标题旁边。需要在static文件夹放置对应的图片
    iconHeight: 35

  # 社交图标 (显示在简介下方)
  socialIcons:
    - name: bilibili
      url: ""
    - name: github
      url: ""
    - name: telegram
      url: ""
    # 可以添加更多社交图标 https://github.com/adityatelange/hugo-PaperMod/wiki/Icons

# 顶部导航栏的快捷链接
menu:
  main:
    - identifier: categories
      name: 分类
      url: /categories/
      weight: 10
    - identifier: tags
      name: 标签
      url: /tags/
      weight: 20
    - identifier: archives
      name: 归档
      url: /archives/
      weight: 30
    - identifier: search
      name: 搜索
      url: /search/
      weight: 40
    # 可以添加更多导航链接。weight的值越高排序越靠后

# 如果要启用搜索功能,需要添加这个
outputs:
  home:
    - HTML
    - RSS
    - JSON # 必须,用于搜索功能

然后我们需要分别配置分类、标签、归档和搜索页

创建 content\categories\_index.md 写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
title: 分类
layout: categories
---

创建 content\tags\_index.md 写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
title: 标签
layout: tags
---

创建 content\archives.md 写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
title: 归档
layout: archives
---

创建 content\search.md 写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
title: "搜索"
layout: "search"
---

然后我们要更改默认的文章创建模板

archetypes\default.md 写入:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
---
title: {{ replace .File.ContentBaseName "-" " " | title }}
published: {{ .Date }}
summary: "文章简介"
cover:
  image: "文章封面图。也支持HTTPS"
tags: [标签1, 标签2]
categories: '文章所处的分类'
draft: false 
lang: ''
---

接下来我们就可以通过命令来创建文章,并开始写作了。注意,最终构建的文章URL是你的文章的文件名。比如:https://你的网站.com/posts/first 所以文章文件名尽量简短,这并不会影响你的文章标题

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hugo new posts/first.md

当我们写完一篇文章想要预览网站,可以使用

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
hugo server

当我们想要将站点发布到Vercel、Cloudflare Pages等静态网站托管平台可以将我们的 myblog 作为一个Git存储库提交到Github

根目录:./

输出目录:public

构建命令:hugo --gc

环境变量(适用于Vercel): Key:HUGO_VERSION Value:0.145.0


对象存储存图中间件代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import keyboard
import pyperclip
from PIL import ImageGrab, Image
import io
import boto3
from botocore.config import Config
import time
import uuid
import pyautogui
import os
from io import BytesIO
# 示例配置
# # R2 配置
# R2_CONFIG = {
#     'account_id': '11111111111111111',
#     'access_key_id': '11111111111111111',
#     'secret_access_key': '11111111111111111',
#     'bucket_name': '11111111111111111'
# }

# # OSS 配置
# OSS_CONFIG = {
#     'url': 'oss.onani.cn',
#     'prefix': '/fuwari-blog/img'
# }
#########################################################
# R2 配置
R2_CONFIG = {
    'account_id': '',
    'access_key_id': '',
    'secret_access_key': '',
    'bucket_name': ''
}

# OSS 配置
OSS_CONFIG = {
    'url': '',
    'prefix': ''
}
#########################################################
def init_r2_client():
    """初始化 R2 客户端"""
    return boto3.client(
        's3',
        endpoint_url=f'https://{R2_CONFIG["account_id"]}.r2.cloudflarestorage.com',
        aws_access_key_id=R2_CONFIG['access_key_id'],
        aws_secret_access_key=R2_CONFIG['secret_access_key'],
        config=Config(signature_version='s3v4'),
        region_name='auto'
    )

def get_image_from_clipboard():
    """从剪贴板获取图片"""
    try:
        image = ImageGrab.grabclipboard()
        if image is None:
            return None
            
        # 如果是列表(多个文件),取第一个
        if isinstance(image, list):
            if len(image) > 0:
                # 如果是图片文件路径,打开它
                try:
                    return Image.open(image[0])
                except Exception as e:
                    print(f"打开图片文件失败: {e}")
                    return None
            return None
            
        # 如果直接是 Image 对象
        if isinstance(image, Image.Image):
            return image
            
        return None
    except Exception as e:
        print(f"获取剪贴板图片失败: {e}")
        return None

def convert_to_webp(image):
    """将图片转换为 webp 格式"""
    if not image:
        return None
    
    try:
        buffer = BytesIO()
        # 确保图片是 RGB 模式
        if image.mode in ('RGBA', 'LA'):
            background = Image.new('RGB', image.size, (255, 255, 255))
            background.paste(image, mask=image.split()[-1])
            image = background
        elif image.mode != 'RGB':
            image = image.convert('RGB')
            
        image.save(buffer, format="WEBP", quality=80)
        return buffer.getvalue()
    except Exception as e:
        print(f"转换图片失败: {e}")
        return None

def upload_to_r2(image_data):
    """上传图片到 R2"""
    if not image_data:
        return None

    client = init_r2_client()
    
    # 生成基础文件名
    base_filename = f"{uuid.uuid4()}.webp"
    filename = base_filename
    
    try:
        # 检查文件是否已存在
        attempt = 1
        while True:
            try:
                # 尝试获取文件信息,如果文件存在会返回数据,不存在会抛出异常
                client.head_object(
                    Bucket=R2_CONFIG['bucket_name'],
                    Key=f"{OSS_CONFIG['prefix'].strip('/')}/{filename}"
                )
                # 如果文件存在,修改文件名
                name_without_ext = base_filename.rsplit('.', 1)[0]
                filename = f"{name_without_ext}_{attempt}.webp"
                attempt += 1
                print(f"文件名已存在,尝试重命名为: {filename}")
            except client.exceptions.ClientError as e:
                # 如果是 404 错误,说明文件不存在,可以使用这个文件名
                if e.response['Error']['Code'] == '404':
                    break
                raise e  # 其他错误则抛出
                
        # 上传文件
        client.put_object(
            Bucket=R2_CONFIG['bucket_name'],
            Key=f"{OSS_CONFIG['prefix'].strip('/')}/{filename}",
            Body=image_data,
            ContentType='image/webp'
        )
        return filename
    except Exception as e:
        print(f"上传失败: {e}")
        return None

def generate_markdown_link(filename):
    """生成 Markdown 图片链接"""
    if not filename:
        return None
    
    url = f"https://{OSS_CONFIG['url']}{OSS_CONFIG['prefix']}/{filename}"
    return f"![]({url})"

def type_markdown_link(markdown_link):
    """模拟键盘输入 Markdown 链接"""
    if not markdown_link:
        return
    
    pyperclip.copy(markdown_link)
    pyautogui.hotkey('ctrl', 'v')

def handle_upload():
    """处理图片上传的主函数"""
    print(f"\n[{time.strftime('%Y-%m-%d %H:%M:%S')}] 收到粘贴请求")
    
    print("正在检查剪贴板...")
    # 获取剪贴板图片
    image = get_image_from_clipboard()
    if not image:
        print("❌ 剪贴板中没有图片")
        return
    print("✅ 获取到剪贴板图片")

    # 转换为 webp
    print("正在转换为 WebP 格式...")
    image_data = convert_to_webp(image)
    if not image_data:
        print("❌ 图片转换失败")
        return
    print(f"✅ 转换完成,大小: {len(image_data)/1024:.2f}KB")

    # 上传到 R2
    print("正在上传到 R2...")
    filename = upload_to_r2(image_data)
    if not filename:
        print("❌ 上传失败")
        return
    print(f"✅ 上传成功,文件名: {filename}")

    # 生成并输入 Markdown 链接
    markdown_link = generate_markdown_link(filename)
    if markdown_link:
        print(f"生成的 URL: https://{OSS_CONFIG['url']}{OSS_CONFIG['prefix']}/{filename}")
        print(f"模拟键入: {markdown_link}")
        type_markdown_link(markdown_link)
        print("✅ 操作完成")

def main():
    """主函数"""
    print("=" * 50)
    print("R2 图片上传插件已启动")
    print(f"当前配置:")
    print(f"- OSS 域名: {OSS_CONFIG['url']}")
    print(f"- 存储路径: {OSS_CONFIG['prefix']}")
    print(f"- R2 存储桶: {R2_CONFIG['bucket_name']}")
    print("使用 Ctrl+Alt+V 上传剪贴板中的图片")
    print("=" * 50)
    
    # 注册快捷键
    keyboard.add_hotkey('ctrl+alt+v', handle_upload)
    
    # 保持程序运行
    keyboard.wait()

if __name__ == "__main__":
    main() 
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-03-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
在Picgo上配置Cloudflare-R2图床
图床就是将图片上传到相关服务商或者个人服务器,通过上传文件的网络地址进行远程访问。可以方便快速的将图片插入到文章中,方便后续图片二次使用、迁移、分享。
慕阳MuYoung
2025/06/12
1180
Ulysses一键发送文章到Day One
我是从2015年夏天开始用Ulysses的。这个编辑器的设计哲学是“所有的文字都放在一处”。这令我很欣喜,因为它非常适合我这种懒人。
王树义
2018/08/22
1.3K0
Ulysses一键发送文章到Day One
VS Code 与 HEXO 结合写博客
在 mac 机器上可以使用 mweb 来写博客,比较好用的地方就是可以直接把剪贴板的图片粘贴上来,缺点是 mac 键盘超难用并且不支持窗口内开启命令行。平时在家的时候都用 Ubuntu 台式机,博客使用 VS Code 编写,一直以来阻挡我的是图片的粘贴特别费劲,今天发现一个很好用的插件 pasteimage,可以直接将剪贴板图片粘贴到 markdown 使用,并且支持配置保存路径。
知一
2021/12/07
1.2K0
VS Code 与 HEXO 结合写博客
印象笔记下的MarkDown
印象笔记终于还是终于出了markdown语法编辑方式,苦苦等了几年的我们是一个什么样子的体验?
恒宇少年
2018/09/20
1.7K0
印象笔记下的MarkDown
[开发日志] Windows 剪贴板记录工具
正是基于这两点思考,我开发了Clipboard Recorder工具。它不仅能帮助用户直观地了解剪贴板的安全风险,也提供了完整的历史记录查询功能。
阿尔的代码屋
2025/01/02
1310
[开发日志] Windows 剪贴板记录工具
使用 Github Pages 和 Hugo 搭建个人博客教程
十一假期宅家无事,发现自己过去写了很多文章,却没有一个自己的博客,系统得管理自己的文章,所以准备将自己过去以及未来的文章都放到博客,以饷读者。另一方面,经过对 Serverless 博客、TCB 建站、虚拟机建站等一系列建站方式对比后,个人认为基于 Github Pages 最适合搭建个人技术博客,最重要的当然是免费,其次网上教程众多,可以快速建站,第三则是所有的博客直接托管在 github,也更符合个人习惯,最后则是自建个人博客可玩性和可扩展性好。
绯浅yousa
2021/01/05
7.5K0
hugo博客搭建之旅
一直以来都有搭建个人博客的想法,然而一直以来都没有开始行动。近来逛V站,又刷到了个人博客方面的内容,直接行动了。
六月河
2023/06/26
8380
Hugo搭建博客(一)— 基本设置
我在windows和ubuntu下安装过hugo,简要介绍下我的安装过程,其他方式可以参考官方文档 。
程序员酷森
2020/10/19
3.2K0
Hugo搭建博客(一)— 基本设置
vscode 配置插件 PicGo
如果你是用 markdown 写文章的话,会发现一个问题。插入图片,要么发布的时候手动一个个的粘贴,要么,就是放到其他bucket里面,然后用图床。恰好有这么一款工具,配合 vscode 得心应手。
叉叉敌
2020/02/17
1.7K0
PicGo图片上传+管理新体验
本体不再增加默认的图床支持。你可以自行开发第三方图床插件。详见 PicGo-Core。
Breeze.
2022/04/11
1.2K0
PicGo图片上传+管理新体验
统一博客系统变更日志
这篇文章是汇总历史发布过的,所有关于我的博客编写发布系统文章。文章以时间线倒序的方式罗列整理。
知一
2022/09/23
3660
统一博客系统变更日志
Hugo NexT主题升级记录
时隔 2 年的时间后,如今又再一次开始折腾自己的博客站点,看来是自己有点太躁动啦😂。在上海疫情期间也真有点压抑的,为了消除这份不安的情绪,决定参考 Hexo NexT 从零开始全面重构 NexT 主题,也在独自奋斗的2个多月断断续续时间里完成主体功能所有移植工作(其实一直想有人参与进来共建,直接跑到人家 Hexo NexT 用户群“呼喊”,但也是没有浪花泛起,只好是自己继续独立前行)。 这不乘着周末的时间,把自己的站点也是升级到最新开发的主题,同时也是为后续想升级旧版本 Hugo NexT 的用户打个样吧
凡梦星尘
2022/08/09
9070
Hugo NexT主题升级记录
如何一键批量上传图片到指定图床,并返回 Markdown 链接?
前些日子,我在 B 站做了一次直播,讲如何利用 Keyboard Maestro 快速采集输入临时笔记。很多小伙伴观看之后都表示很感兴趣,并且提了不少问题。如果你当天不巧没有赶上直播,可以看看讲解部分的回放。
王树义
2022/03/25
2.8K1
如何一键批量上传图片到指定图床,并返回 Markdown 链接?
[golang][hugo]使用Hugo搭建静态站点
hugo下载地址:https://github.com/gohugoio/hugo
landv
2019/11/30
1.6K0
文件上传的新高度,快捷键直接上传到minio
症状:TypeError: expected str, bytes or os.PathLike object, not list
一只牛博
2025/05/30
510
文件上传的新高度,快捷键直接上传到minio
一键自动化博客发布工具,用过的人都说好(掘金篇)
终于要讲解我们亲爱的掘金了。掘金是一个非常不错的平台。所以很多朋友会把博客发布到掘金上。
程序那些事
2024/05/16
1980
一键自动化博客发布工具,用过的人都说好(掘金篇)
PHP-常用方法
文件上传 $name = "picture"//文件名 $f_type = ".png"//文件类型 $tmp = $_FILES['file']['tmp_name']; $filepath = 'file/document/';//上传的路径 if(move_uploaded_file($tmp,$filepath.$name.$f_type)){ echo "上传成功"; }else{ echo "上传失败"; } 统计目录下文件数 $folderPath = "file/docume
偏有宸机
2020/11/04
1.5K0
前后端分离项目,如何优雅实现文件存储!
学习本文需要一些MinIO的基础知识,还不了解的小伙伴可以参考下:Github标星19K+Star,10分钟自建对象存储服务!
macrozheng
2020/02/10
3.2K1
还是编程新手?这10条 GitHub 秘籍送给你
本文转自 | 实验楼 10. 查看用户的全部 Commit 历史 在 Commits 页面 URL 后加上 ?author={user} 查看用户全部的提交。 https://github.com/
用户6543014
2019/10/25
1K0
还是编程新手?这10条 GitHub 秘籍送给你
MinIO的安装和SDK使用
下载地址:https://min.io/download?license=enterprise&platform=linux
码之有理
2024/10/08
4370
相关推荐
在Picgo上配置Cloudflare-R2图床
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验