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

本文涉及的产品
轻量应用服务器 2vCPU 4GiB,适用于网站搭建
轻量应用服务器 2vCPU 1GiB,适用于搭建电商独立站
轻量应用服务器 4vCPU 16GiB,适用于搭建游戏自建服
简介: Hugo博客搭建教程以及配置调优

正式开始

请全程在Windows上操作

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

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

$env:SCOOP='D:\Scoop'
$env:SCOOP_GLOBAL='D:\ScoopApps'
[Environment]::SetEnvironmentVariable('SCOOP', $env:SCOOP, 'User')
[Environment]::SetEnvironmentVariable('SCOOP_GLOBAL', $env:SCOOP_GLOBAL, 'Machine')

安装Scoop:

Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Scope CurrentUser
Invoke-RestMethod -Uri https://get.scoop.sh | Invoke-Expression

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

github原帖

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

irm get.scoop.sh -outfile 'install.ps1'
.\install.ps1 -RunAsAdmin [-OtherParameters ...]
# 如果你想要一行解决:
iex "& {
     $(irm get.scoop.sh)} -RunAsAdmin"

安装Hugo框架:

scoop install hugo

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

hugo new site myblog
cd myblog

安装PaperMod主题:

git clone https://github.com/adityatelange/hugo-PaperMod.git themes/PaperMod

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

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 写入:

---
title: 分类
layout: categories
---

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

---
title: 标签
layout: tags
---

创建 content\archives.md 写入:

---
title: 归档
layout: archives
---

创建 content\search.md 写入:

---
title: "搜索"
layout: "search"
---

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

archetypes\default.md 写入:

---
title: {
  { replace .File.ContentBaseName "-" " " | title }}
published: {
  { .Date }}
summary: "文章简介"
cover:
  image: "文章封面图。也支持HTTPS"
tags: [标签1, 标签2]
categories: '文章所处的分类'
draft: false 
lang: ''
---

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

hugo new posts/first.md

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

hugo server

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

根目录:./

输出目录:public

构建命令:hugo --gc

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


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

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()
相关文章
|
1月前
|
消息中间件 运维 监控
加一个JVM参数,让系统可用率从95%提高到99.995%
本文针对一个高并发(10W+ QPS)、低延迟(毫秒级返回)的系统因内存索引切换导致的不稳定问题,深入分析并优化了JVM参数配置。通过定位问题根源为GC压力大,尝试了多种优化手段:调整MaxTenuringThreshold、InitialTenuringThreshold、AlwaysTenure等参数让索引尽早晋升到老年代;探索PretenureSizeThreshold和G1HeapRegionSize实现索引直接分配到老年代;加速索引复制过程以及升级至JDK11使用ZGC。
368 82
加一个JVM参数,让系统可用率从95%提高到99.995%
|
22天前
|
存储 人工智能 Shell
PVE开源虚拟化常见配置
PVE开源虚拟化常见配置
180 12
PVE开源虚拟化常见配置
|
21天前
|
机器学习/深度学习 自然语言处理 算法框架/工具
实战 | Qwen2.5-VL模型目标检测(Grounding)任务领域微调教程
在目标检测领域,众多神经网络模型早已凭借其卓越的性能,实现了精准的目标检测与目标分割效果。然而,随着多模态模型的崛起,其在图像分析方面展现出的非凡能力,为该领域带来了新的机遇。多模态模型不仅能够深入理解图像内容,还能将这种理解转化为文本形式输出,极大地拓展了其应用场景。
1385 74
|
1月前
|
人工智能 自然语言处理 IDE
技术赋能新维度,灵码进化新突破:通义灵码2.5新功能尝鲜及深度评测
通义灵码是阿里云推出的基于通义大模型的智能编程助手,作为首款全栈智能辅助的国产编码工具,它为开发者提供“第二大脑”,并重构团队协作效能。2.5版本新增智能体模式,支持Qwen3系列模型,具备自主决策、工程感知和记忆能力,集成3000+MCP工具。其优势包括多模式对话体验、上下文增强、全流程工具链支持及个性化记忆功能,但仍存在上下文管理、权限控制和语言支持等方面的改进空间。此次更新标志着AI辅助开发进入全链路智能化新纪元,成为开发者真正的“结对编程伙伴”。
807 36
|
27天前
|
人工智能 安全 API
Higress MCP Server 安全再升级:API 认证为 AI 连接保驾护航
Higress MCP Server 新增了 API 认证功能,为 AI 连接提供安全保障。主要更新包括:1) 客户端到 MCP Server 的认证,支持 Key Auth、JWT Auth 和 OAuth2;2) MCP Server 到后端 API 的认证,增强第二阶段的安全性。新增功能如可重用认证方案、工具特定后端认证、透明凭证透传及灵活凭证管理,确保安全集成更多后端服务。通过 openapi-to-mcp 工具简化配置,减少手动工作量。企业版提供更高可用性保障,详情参见文档链接。
334 42
|
27天前
|
消息中间件 人工智能 自然语言处理
DeepWiki × LoongCollector:AI 重塑开源代码理解
本文探讨了开源项目LoongCollector的复杂性及其对开发者带来的挑战,介绍了DeepWiki作为AI驱动的智能文档生成工具如何解决这些问题。DeepWiki通过结构化文档、交互式流程图和核心数据结构解析,帮助开发者快速理解项目架构与逻辑。同时,其内置的AI对话助手可实时解答技术疑问,提供场景化指导,如问题排查、源码学习路径制定及开发指导。文章还展示了DeepWiki在优化LoongCollector插件开发、提升社区贡献效率方面的实际应用,并展望了AI重构开源协作范式的未来潜力。
401 43
|
16天前
|
存储 人工智能 Kubernetes
AI 场景深度优化!K8s 集群 OSSFS 2.0 存储卷全面升级,高效访问 OSS 数据
阿里云对象存储OSS是一款海量、安全、低成本、高可靠的云存储服务,是用户在云上存储的高性价比选择…
|
1月前
|
人工智能 安全 应用服务中间件
阿里巴巴 MCP 分布式落地实践:快速转换 HSF 到 MCP server
本文分享了阿里巴巴内部将大规模HSF服务快速转换为MCP Server的实践经验,通过Higress网关实现MCP协议卸载,无需修改代码即可接入MCP生态。文章分析了MCP生态面临的挑战,如协议快速迭代和SDK不稳定性,并详细介绍了操作步骤及组件功能。强调MCP虽非终极解决方案,但作为AI业务工程化的起点具有重要意义。最后总结指出,MCP只是AI原生应用发展的第一步,未来还有更多可能性值得探索。
707 48
|
21天前
|
人工智能 Kubernetes Java
回归开源,两位 Java 和 Go 程序员分享的开源贡献指引
Higress是一个基于Istio和Envoy的云原生API网关,支持AI功能扩展。它通过Go/Rust/JS编写的Wasm插件提供可扩展架构,并包含Node和Java的console模块。Higress起源于阿里巴巴,解决了Tengine配置重载及gRPC/Dubbo负载均衡问题,现已成为阿里云API网关的基础。本文介绍Higress的基本架构、功能(如AI网关、API管理、Ingress流量网关等)、部署方式以及如何参与开源贡献。此外,还提供了有效的开源贡献指南和社区交流信息。
256 34
|
9月前
|
Go 开发工具 git
CF+hugo部署要点随记
本文介绍了使用Hugo搭建静态博客的方法,Hugo是一款用Go语言编写的静态站点生成器。文中详细描述了在Windows环境下安装Go、Git和Hugo的步骤,并提供了快速启动指南。此外,还介绍了如何通过Git子模块引入主题,以及如何在本地创建和编辑文章。最后,给出了常用Markdown语法示例,帮助用户轻松撰写博客内容。
293 7

热门文章

最新文章