LICENSE Documentation

Official TypeScript developer resources and documentation for nelvko/LICENSE. Verified technical context for AI.

0 stars TypeScript TypeScript 1 file · ~223,662 tokens
RAW Doc

1. Project Overview & Quickstart (nelvko/LICENSE)

Technical Documentation: nelvko/LICENSE

ℹ️ Provenance: Multi-Tier Ingestion · CodeWiki Reference

LICENSE

Agent Skills & Rules

  • Discovered 21 agent rule(s) and prompt configurations.

--- METRICS ---

2. Official Technical Reference & Guides (nelvko/docs)

File: docs/contribution/issue.md


title: 问题反馈

:::info
如果您在使用过程中遇到了什么问题,您可以通过下面的方式反馈,但请尽量按照要求提出反馈。
:::

GitHub Issues

链接:https://github.com/halo-dev/halo/issues

如果你在使用过程中,遇到了一些 bug 或者需要添加某些新特性,请尽量在 GitHub Issues 进行反馈,这非常有助于我们跟踪解决此问题,您也可以很方便的接收到处理状态。

建议步骤:

  1. 在 Issues 列表 搜索相关问题,看看是否有其他人已经提到了此问题。
  2. 如果当前还没有人遇到您类似的问题,那么请点击右上角的 New issue 按钮创建新的 issue。
  3. 选择正确的反馈类型。
  4. 请尽可能详细的按照模板填写内容。
  5. 点击 Submit new issue 提交 issue。

Halo 官方社区

链接:https://bbs.halo.run

此平台主要目的用于与其他 Halo 用户进行交流。但如果您对 GitHub 不是很熟悉或者没有账号,您也可以在此平台进行反馈。


File: docs/contribution/pr.md


title: 代码贡献

欢迎关注并有想法参与 Halo 的开发,以下是关于如何参与到 Halo 项目的指南,仅供参考。

发现 Issue

所有的代码尽可能都有依据(Issue),不是凭空产生。

寻找一个 Good First Issue

这个步骤非常适合首次贡献者。

在 halo-dev 和 halo-sigs 组织下,有非常多的仓库。每个仓库下都有可能包含一些“首次贡献者”友好的 Issue,主要是为了给贡献者提供一个友好的体验。 该类 Issue
一般会用 good-first-issue 标签标记。标签 good-first-issue 表示该 Issue 不需要对 Halo 有深入的理解也能够参与。

请点击:good-first-issue
查看关于 Halo 的 Good First Issue。

认领 Issue

若对任何一个 Issue 感兴趣,请尝试在 Issue 进行回复,讨论解决 Issue 的思路。确定后可直接通过 /assign 或者 /assign @GitHub 用户名 认领这个
Issue。这样可避免两位贡献者在同一个问题上花时间。

代码贡献步骤

  1. Fork 此仓库

    点击 Halo 仓库主页右上角的 Fork 按钮即可。

  2. Clone 仓库到本地

    bash
    git clone https://github.com/{YOUR_USERNAME}/halo --recursive
    # 或者 git clone [email protected]:{YOUR_USERNAME}/halo.git --recursive
  3. 添加主仓库

    添加主仓库方便未来同步主仓库最新的 commits 以及创建新的分支。

    bash
    git remote add upstream https://github.com/halo-dev/halo.git
    # 或者 git remote add upstream [email protected]:halo-dev/halo.git
    git fetch upstream main
  4. 创建新的开发分支

    我们需要从主仓库的主分支创建一个新的开发分支。

    bash
    git checkout upstream/main
    git checkout -b {BRANCH_NAME}
  5. 提交代码

    bash
    git add .
    git commit -s -m "Fix a bug king"
    git push origin {BRANCH_NAME}
  6. 合并主分支

    在提交 Pull Request 之前,尽量保证当前分支和主分支的代码尽可能同步,这时需要我们手动操作。示例:

    bash
    git fetch upstream/main
    git merge upstream/main
    git push origin {BRANCH_NAME}

Pull Request

进入此阶段说明已经完成了代码的编写,测试和自测,并且准备好接受 Code Review。

创建 Pull Request

回到自己的仓库页面,选择 New pull request 按钮,创建 Pull request 到原仓库的 main 分支。
然后等待我们 Review 即可,如有 Change Request,再本地修改之后再次提交即可。

提交 Pull Request 的注意事项:

  • 提交 Pull Request 请充分自测。
  • 每个 Pull Request 尽量只解决一个 Issue,特殊情况除外。
  • 应尽可能多的添加单元测试,其他测试(集成测试和 E2E 测试)可看情况添加。
  • 不论需要解决的 Issue 发生在哪个版本,提交 Pull Request 的时候,请将主仓库的主分支设置为 main。例如:即使某个 Bug 于 Halo 2.0.x 被发现,但是提交 Pull Request 仍只针对
    main 分支,等待 Pull Request 合并之后,我们会通过 /cherrypick release-2.0 或者 /cherry-pick release-2.1 指令将此 Pull Request
    的修改应用到 release-2.0 和 release-2.1 分支上。

更新 commits

Code Review 阶段可能需要 Pull Request 作者重新修改代码,请直接在当前分支 commit 并 push 即可,无需关闭并重新提交 Pull Request。示例:

bash
git add .
git commit -s -m "Refactor some code according code review"
git push origin bug/king

同时,若已经进入 Code Review 阶段,请不要强制推送 commits 到当前分支。否则 Reviewers 需要从头开始 Code Review。

开发规范

请参考 https://docs.halo.run/developer-guide/core/code-style
,请确保所有代码格式化之后再提交。


File: docs/contribution/sponsor.md


title: 赞助我们

为什么需要赞助

我们花费了大量的精力来维护这个软件,并且也提供了不少资金来维护服务器,域名等。因此我们需要赞助来节省部分开发成本。你的赞助不仅仅会被我们用来支付一些开发成本(比如服务器,OSS,域名等),还会让我们有更多的信心和精力投入到这个开源项目的开发中。从而让项目保持更加健康的成长以及迭代。

赞助形式

:::info
你可以通过任何形式对我们赞助,不限于资金。
:::

资金赞助

通过我们的推广链接购买服务器

如果你当前还没有购买服务器,可以考虑通过以下链接购买,这会为我们带来一部分收益。


File: docs/developer-guide/core/build.md


title: 构建

:::info
在此之前,我们推荐你先阅读《准备工作》,检查本地环境是否满足要求。
:::

一般情况下,为了保证版本一致性和可维护性,我们并不推荐自行构建和二次开发。

克隆项目

如果你已经 Fork 了相关仓库,请将以下命令中的 halo-dev 替换为你的 GitHub 用户名。

bash
git clone https://github.com/halo-dev/halo

# 或者使用 ssh 的方式 clone(推荐)
# git clone [email protected]:halo-dev/halo.git

# 或者使用 GitHub CLI 克隆(推荐)
# gh repo clone halo-dev/halo 

# 或者使用 GitHub CLI Fork(推荐)
# gh repo fork halo-dev/halo

cd halo

# 切换到特定的分支或标签,请替换 ${branch_name}
git checkout ${branch_name}

构建 Fat Jar

构建之前需要修改 gradle.properties 中的 version 属性(推荐遵循 SemVer 规范),例如:version=2.13.0

bash
cd path/to/halo

下载预设插件(可选):

bash
# Windows
./gradlew.bat downloadPluginPresets

# macOS / Linux
./gradlew downloadPluginPresets

构建:

bash
# Windows
./gradlew.bat clean build -x check

# macOS / Linux
./gradlew clean build -x check

构建完成之后,在 Halo 项目下产生的 application/build/libs/halo-${version}.jar 即为构建完成的文件。

最终部署文档可参考:使用 JAR 文件部署。

构建 Docker 镜像

在此之前,请确认已经构建好了 Fat Jar。

bash
cd path/to/halo
bash
# 请替换 ${tag_name}
docker build -t halo-dev/halo:${tag_name} .
bash
# 插件构建完成的版本
docker images | grep halo

最终部署文档可参考:使用 Docker Compose 部署。


File: docs/developer-guide/core/code-style.md


title: 代码风格

Halo 添加了 checkstyle 插件,来保证每位提交者代码的风格保持一致,减少无效代码的修改。本篇文章主要讲解如何在 IDEA 中添加 CheckStyle 插件,并引入项目所提供的 checkstyle.xml 配置。

安装 CheckStyle-IDEA

  • 进入 IDEA 插件市场。
  • 搜索 CheckStyle-IDEA,点击安装即可。

配置 CheckStyle

  • 进入 CheckStyle 配置(File | Settings | Tools | Checkstyle)。
  • 选择 Checkstyle 版本:9.3(以文件 application/build.gradle 中指定的版本为准)。
  • 在配置文件中点击添加按钮,配置描述可随便填写(推荐 Halo Checks),选择 ./config/checkstyle/checkstyle.xml,点击下一步和完成。
  • 勾选刚刚创建的配置文件。

配置 Editor

  • 进入编辑器配置(File | Settings | Editor | Code Style)

  • 导入 checkstyle.xm 配置:

  • 选择 ./config/checkstyle/checkstyle.xml 配置文件,点击确定即可。

至此,有关代码风格检查工具和格式化配置已经完成。


File: docs/developer-guide/core/prepare.md


title: 准备工作

环境要求

名词解释

工作目录

指 Halo 所依赖的工作目录,在 Halo 运行的时候会在系统当前用户目录下产生一个 halo-next 的文件夹,绝对路径为 ~/halo-next。里面通常包含下列目录或文件:

  1. db:存放 H2 Database 的物理文件,如果你使用其他数据库,那么不会存在这个目录。
  2. themes:里面包含用户所安装的主题。
  3. plugins:里面包含用户所安装的插件。
  4. attachments:附件目录。
  5. logs:运行日志目录。

File: docs/developer-guide/core/run.md


title: 开发环境运行

:::info
在此之前,我们推荐你先阅读《准备工作》,检查本地环境是否满足要求。
:::

项目结构说明

目前如果需要完整的运行 Halo,总共需要三个部分:

  1. Halo 主项目(halo-dev/halo)
  2. UI,包括 Console 控制台和 UC 个人中心(托管在 Halo 主项目)
  3. 主题(Halo 主项目内已包含默认主题)

:::info 说明
从 Halo 2.13 开始,Halo 项目的 ui 目录同时包含了 Console(管理控制台)和 UC(个人中心),以下统称为 UI。

当前 Halo 主项目并不会将 UI 的构建资源托管到 Git 版本控制,所以在开发环境是需要同时运行 UI 项目的。当然,在我们的最终发布版本的时候会在 CI 中自动构建 UI 到 Halo 主项目。
:::

克隆项目

如果你已经 Fork 了相关仓库,请将以下命令中的 halo-dev 替换为你的 GitHub 用户名。

bash
git clone https://github.com/halo-dev/halo

# 或者使用 ssh 的方式 clone(推荐)
# git clone [email protected]:halo-dev/halo.git

# 或者使用 GitHub CLI 克隆(推荐)
# gh repo clone halo-dev/halo 

# 或者使用 GitHub CLI Fork(推荐)
# gh repo fork halo-dev/halo

运行 UI 服务

bash
cd path/to/halo

Linux / macOS 平台:

bash
./gradlew :ui:dev

Windows 平台:

bash
./gradlew.bat :ui:dev

最终控制台打印了如下信息即代表运行正常:

bash
VITE v4.2.3  ready in 638 ms

# Console 控制台服务
➜  Local:   http://localhost:3000/console/

# UC 个人中心服务
➜  Local:   http://localhost:4000/uc/

:::info 提示
请不要直接使用 UI 的运行端口(3000 / 4000)访问,会因为跨域问题导致无法正常登录,建议按照后续的步骤以 dev 的配置文件运行 Halo,在 dev 的配置文件中,我们默认代理了 UI 页面的访问地址,所以后续访问 UI 页面使用 http://localhost:8090/console 和 http://localhost:8090/uc 访问即可,代理的相关配置:

yaml
halo:
  console:
    proxy:
      endpoint: http://localhost:3000/
      enabled: true
  uc:
    proxy:
      endpoint: http://localhost:4000/
      enabled: true

:::

运行 Halo

  1. 在 IntelliJ IDEA 中打开 Halo 项目,等待 Gradle 初始化和依赖下载完成。

  2. 下载预设插件(可选)

    bash
    # Windows
    ./gradlew.bat downloadPluginPresets
    
    # macOS / Linux
    ./gradlew downloadPluginPresets
  3. 修改 IntelliJ IDEA 的运行配置

    • Windows

      将 Active Profiles 改为 dev,win,如图所示:

    • macOS / Linux

      将 Active Profiles 改为 dev,如图所示:

  4. 点击 IntelliJ IDEA 的运行按钮,等待项目启动完成。

  5. 或者使用 Gradle 运行

    bash
    # macOS / Linux
    ./gradlew bootRun --args="--spring.profiles.active=dev"
    
    # Windows
    gradlew.bat bootRun --args="--spring.profiles.active=dev,win"
  6. 最终提供以下访问地址:

    1. 网站首页:http://localhost:8090
    2. Console 控制台:http://localhost:8090/console
    3. UC 个人中心:http://localhost:8090/uc

File: docs/developer-guide/core/structure.md


title: 系统结构

Halo 博客系统分为以下四个部分:

项目名称 简介
halo 提供整个系统的服务,采用 Spring Boot 开发
halo-admin 负责后台管理的渲染,采用 Vue 开发,已集成在 Halo 运行包内,无需独立部署。
halo-comment 评论插件,采用 Vue 开发,在主题中运行方式引入构建好的 JavaScript 文件即可
halo-theme-* 主题项目集,采用 FreeMarker 模板引擎编写,需要包含一些特殊的配置才能够被 halo 所使用

自定义配置

为什么要提前讲自定义配置呢?是因为在这里让大家了解到 Halo 的配置方式,以及配置优先级,不至于未来运行项目的时候不知道如何优雅地修改配置。

Halo 配置目录优先级如下(从上到下优先级越来越小,上层的配置将会覆盖下层):

  • Halo 自定义配置
    • file:~/.halo/
    • file:~/.halo-dev/
  • Spring Boot 默认配置
    • file:./config/
    • file:./
    • classpath:/config/
    • classpath:/

参考: Application Property Files

在开发的时候,希望大家能够在 ~/halo-dev/application.yml 中进行添加自定义配置。当然后面也会讲到如何用运行参数 和 VM options 进行控制配置,届时可根据具体情况进行选择。

:::warning
开发的时候,我们不建议直接更改项目源码中的所包含的配置文件,包括 application.yml、application-dev.yml、application-test.yml 和 application-user.yml。
:::


File: docs/developer-guide/plugin/api-reference/ui/extension-points/interface/Attachment.md

ts
export interface Attachment {
  apiVersion: "storage.halo.run/v1alpha1"
  kind: "Attachment"
  metadata: {
    annotations: {}
    creationTimestamp: string
    labels: {}
    name: string                                // 附件的唯一标识
    version: number
  }
  spec: {
    displayName: string                         // 附件名称
    groupName: string                           // 附件分组
    mediaType: string                           // 附件类型
    ownerName: string                           // 附件上传者
    policyName: string                          // 附件存储策略
    size: number                                // 附件大小
    tags: Array<string>
  }
  status: {
    permalink: string                           // 附件固定访问地址
  }
}

File: docs/developer-guide/plugin/api-reference/ui/extension-points/interface/ListedPost.md

ts
export interface ListedPost {
  categories: Array<{                             // 文章的分类集合
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Category";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 分类的唯一标识
      version: number;
    };
    spec: {
      children: Array<string>;                    // 子分类
      cover: string;                              // 分类封面图
      description: string;                        // 分类描述
      displayName: string;                        // 分类名称
      priority: number;                           // 分类优先级
      slug: string;                               // 分类别名
      template: string;                           // 分类渲染模板
    };
    status: {
      permalink: string;                          // 分类的永久链接
      postCount: number;                          // 分类下的文章总数
      visiblePostCount: number;                   // 分类下可见的文章总数
    };
  }>;
  contributors: Array<{                           // 文章的贡献者集合
    avatar: string;                               // 贡献者头像
    displayName: string;                          // 贡献者名称
    name: string;                                 // 贡献者唯一标识
  }>;
  owner: {                                        // 文章的作者信息
    avatar: string;                               // 作者头像
    displayName: string;                          // 作者名称
    name: string;                                 // 作者唯一标识
  };
  post: {                                         // 文章信息
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Post";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 文章的唯一标识
      version: number;
    };
    spec: {
      allowComment: boolean;                      // 是否允许评论
      baseSnapshot: string;                       // 内容基础快照
      categories: Array<string>;                  // 文章所属分类
      cover: string;                              // 文章封面图
      deleted: boolean;                           // 是否已删除
      excerpt: {                                  // 文章摘要
        autoGenerate: boolean;                    // 是否自动生成
        raw: string;                              // 摘要内容
      };
      headSnapshot: string;                       // 内容最新快照
      htmlMetas: Array<{}>;
      owner: string;                              // 文章作者的唯一标识
      pinned: boolean;                            // 是否置顶
      priority: number;                           // 文章优先级
      publish: boolean;                           // 是否发布
      publishTime: string;                        // 发布时间
      releaseSnapshot: string;                    // 已发布的内容快照
      slug: string;                               // 文章别名
      tags: Array<string>;                        // 文章所属标签
      template: string;                           // 文章渲染模板
      title: string;                              // 文章标题
      visible: string;                            // 文章可见性
    };
    status: {
      commentsCount: number;                      // 文章评论总数
      conditions: Array<{
        lastTransitionTime: string;
        message: string;
        reason: string;
        status: string;
        type: string;
      }>;
      contributors: Array<string>;
      excerpt: string;                            // 最终的文章摘要,根据是否自动生成计算
      inProgress: boolean;                        // 是否有未发布的内容
      lastModifyTime: string;                     // 文章最后修改时间
      permalink: string;                          // 文章的永久链接
      phase: string;
    };
  };
  stats: {
    approvedComment: number;                      // 已审核的评论数
    totalComment: number;                         // 评论总数
    upvote: number;                               // 点赞数
    visit: number;                                // 访问数
  };
  tags: Array<{                                   // 文章的标签集合
    apiVersion: "content.halo.run/v1alpha1";
    kind: "Tag";
    metadata: {
      annotations: {};
      creationTimestamp: string;
      labels: {};
      name: string;                               // 标签的唯一标识
      version: number;
    };
    spec: {
      color: string;                              // 标签颜色
      cover: string;                              // 标签封面图
      displayName: string;                        // 标签名称
      slug: string;                               // 标签别名
    };
    status: {
      permalink: string;                          // 标签的永久链接
      postCount: number;                          // 标签下的文章总数
      visiblePostCount: number;                   // 标签下可见的文章总数
    };
  }>;
}

File: docs/developer-guide/plugin/api-reference/ui/extension-points/interface/OperationItem.md

ts title="operationitem"
export interface OperationItem<T> {
  priority: number;                 // 排序优先级
  component: Raw<Component>;        // 菜单项组件
  props?: Record<string, unknown>;  // 菜单项组件属性
  action?: (item?: T) => void;      // 菜单项点击事件
  label?: string;                   // 菜单项标题
  hidden?: boolean;                 // 菜单项是否隐藏
  permissions?: string[];           // 菜单项 UI 权限
  children?: OperationItem<T>[];    // 子菜单项
}

File: docs/developer-guide/plugin/api-reference/ui/extension-points/interface/Plugin.md

ts
export interface Plugin {
  apiVersion: "plugin.halo.run/v1alpha1"
  kind: "Plugin"
  metadata: {
    annotations: {}
    creationTimestamp: string         // 创建时间
    labels: {}
    name: string                      // 唯一标识
    version: number
  }
  spec: {
    author: {                         // 作者信息
      name: string
      website: string
    }
    configMapName: string             // 关联的 ConfigMap 模型,用于存储配置
    description: string               // 插件描述
    displayName: string               // 插件名称
    enabled: boolean
    homepage: string                  // 插件主页
    license: Array<{                  // 插件协议
      name: string
      url: string
    }>
    logo: string
    pluginDependencies: {}
    repo: string                      // 插件仓库地址
    requires: string                  // 所依赖的 Halo 版本
    settingName: string               // 关联的 Setting 模型,用于渲染配置表单
    version: string                   // 插件版本
  }
  status: {
    conditions: Array<{
      lastTransitionTime: string
      message: string
      reason: string
      status: string
      type: string
    }>
    entry: string
    lastProbeState: string
    lastStartTime: string
    loadLocation: string
    logo: string                      // 插件 Logo 地址
    phase: string
    stylesheet: string
  }
}