自定义 Gitea
自定义 Gitea 通常通过 CustomPath 目录完成。默认情况下,它是工作目录(WorkPath)下的
custom 目录,但如果您的安装方式做了不同设置,也可能位于其他位置。
这是覆盖配置项、模板等内容的核心位置。您可以通过 gitea help 查看 CustomPath,也可以在
站点管理 页面的 Configuration 选项卡中找到该路径。您还可以通过设置 GITEA_CUSTOM
环境变量,或在 gitea 二进制上使用 --custom-path 选项来覆盖 CustomPath。
(命令行选项会覆盖环境变量。)
如果 Gitea 以二进制方式部署,所有默认路径都相对于 Gitea 二进制文件。
如果通过发行版安装,这些路径通常会按照 Linux 文件系统标准进行调整。Gitea 会尝试创建所需目录,
包括 custom/。某些发行版可能会通过 /etc/gitea/ 为 custom 提供一个符号链接。
应用配置可以在 CustomConf 文件中找到,默认路径为 $GITEA_CUSTOM/conf/app.ini,
但如果您的安装方式修改了配置,也可能位于其他位置。
同样,您可以通过 gitea help 查看该变量,也可以使用 gitea 二进制的 --config 选项覆盖它。
如果在检查 gitea help 后仍找不到 CustomPath 目录,请检查 GITEA_CUSTOM 环境变量;
它可以用来将默认路径覆盖为其他位置。例如,GITEA_CUSTOM 可能由 init 脚本设置。
您也可以在站点管理页面的 “Configuration” 选项卡下检查该值是否已设置。
提供自定义公共文件
Section titled “提供自定义公共文件”要让 Gitea 提供自定义公共文件(例如页面和图片),请将 $GITEA_CUSTOM/public/
目录作为 webroot。Gitea 会跟随符号链接。
当前仅提供以下文件:
public/robots.txtpublic/.well-known/目录中的文件public/assets/目录中的文件
例如,存放在 $GITEA_CUSTOM/public/assets/ 中的 image.png 文件,可以通过
http://gitea.domain.tld/assets/image.png 访问。
修改 Logo
Section titled “修改 Logo”如果要构建自定义 logo 和/或 favicon,请克隆 Gitea 源码仓库,替换 assets/logo.svg
和/或 assets/favicon.svg,然后运行 make generate-images。assets/favicon.svg
仅用于 favicon。执行后会更新以下输出文件,随后您可以将它们放到服务器上的
$GITEA_CUSTOM/public/assets/img 中:
public/assets/img/logo.svg- 用于站点图标、应用图标public/assets/img/logo.png- 用于 Open Graphpublic/assets/img/avatar_default.png- 用作默认头像图片public/assets/img/apple-touch-icon.png- 用于 iOS 设备书签public/assets/img/favicon.svg- 用于 faviconpublic/assets/img/favicon.png- 用作不支持 SVG favicon 的浏览器回退图标
如果源图片不是矢量格式,您可以尝试使用诸如这个工具 将光栅图像转换为矢量图。
自定义 Gitea 页面和资源
Section titled “自定义 Gitea 页面和资源”Gitea 可执行文件内置了运行所需的全部资源:模板、图片、样式表和翻译。您可以在 custom
目录下放置与原路径一致的替换文件来覆盖其中任意资源。例如,要替换 C++ 仓库默认提供的
.gitignore,我们需要替换 options/gitignore/C++。为此,您必须将替换文件放到
$GITEA_CUSTOM/options/gitignore/C++(CustomPath 目录位置见本文开头说明)。
Gitea 的每一个页面都可以修改。动态内容通过 go template
生成,您可以通过在 $GITEA_CUSTOM/templates 目录下放置替换文件进行修改。
要获取任意内嵌文件(包括模板),可以使用gitea embedded 工具。
另外,也可以在 Gitea 源码仓库的 templates
目录中找到它们。(注意:示例链接指向 main 分支,请确保所使用的模板与您当前的发布版本兼容。)
请注意,任何包含在 {{ 和 }} 中的语句都是 Gitea 的模板语法,
如果您没有完全理解这些组件,就不应修改它们。
自定义首页 / 主页
Section titled “自定义首页 / 主页”将与您所使用 Gitea 版本对应的 home.tmpl
从 templates 目录复制到 $GITEA_CUSTOM/templates。
随后按您的需要编辑即可。
不要忘记重启 Gitea 以应用更改。
添加链接和页签
Section titled “添加链接和页签”如果您只是想为顶部导航栏或页脚添加额外链接,或者为仓库视图添加额外页签,
可以将它们分别放入 $GITEA_CUSTOM/templates/custom/ 目录中的
extra_links.tmpl(添加到导航栏的链接)、extra_links_footer.tmpl
(添加到页脚左侧的链接)和 extra_tabs.tmpl。
例如,假设您在德国,需要添加法律上通常要求提供的 “Impressum”/关于页面,用来说明谁对站点内容负责:
只需将该页面放到 $GITEA_CUSTOM/public/assets/ 目录中
(例如 $GITEA_CUSTOM/public/assets/impressum.html),再在
$GITEA_CUSTOM/templates/custom/extra_links.tmpl 或
$GITEA_CUSTOM/templates/custom/extra_links_footer.tmpl 中加入指向它的链接即可。
为了匹配当前样式,该链接应使用类名 item,并且您可以使用 {{AppSubUrl}} 获取基础 URL:
<a class="item" href="{{AppSubUrl}}/assets/impressum.html">Impressum</a>
更多信息请参见添加法律页面。
您也可以用同样的方式添加新页签,将其放入 extra_tabs.tmpl 中。
与其他页签样式匹配所需的精确 HTML 位于文件 templates/repo/header.tmpl
(GitHub 源码)。
页面中的其他插入内容
Section titled “页面中的其他插入内容”除了 extra_links.tmpl 和 extra_tabs.tmpl 之外,您还可以在
$GITEA_CUSTOM/templates/custom/ 目录中放置其他有用的模板:
header.tmpl,位于<head>结束标签之前,例如可用于添加自定义 CSS 文件。body_outer_pre.tmpl,位于<body>起始标签之后。body_inner_pre.tmpl,位于顶部导航栏之前,但已处于主容器<div class="full height">内部。body_inner_post.tmpl,位于主容器结束之前。body_outer_post.tmpl,位于底部<footer>元素之前。footer.tmpl,位于<body>结束标签之前,是放置额外 JavaScript 的合适位置。
使用 Gitea 变量
Section titled “使用 Gitea 变量”您可以在自定义模板中使用各种 Gitea 变量。
首先,临时 启用开发模式:在 app.ini 中将 RUN_MODE = prod 改为 RUN_MODE = dev。
然后在任意模板中添加 {{ $ | DumpVar }},重启 Gitea 并刷新对应页面;
这样会输出所有可用变量。
找到所需数据后,使用对应变量即可;例如,如果您需要仓库名称,可以使用 {{.Repository.Name}}。
如果您需要对这些数据做一些转换,而您又不熟悉 Go,一种简单的变通办法是先将数据放入 DOM, 再添加一小段 JavaScript 脚本来处理它。
示例:PlantUML
Section titled “示例:PlantUML”您可以通过 PlantUML 服务器为 Gitea 的 Markdown 添加 PlantUML 支持。
数据会被编码后发送到 PlantUML 服务器,再由服务器生成图片。官方在
http://www.plantuml.com/plantuml 提供了一个在线演示服务器,但如果您(或您的用户)拥有敏感数据,
则可以改为自建一个 PlantUML 服务器。要启用 PlantUML 渲染,
请从 https://gitea.com/davidsvantesson/plantuml-code-highlight 复制 JavaScript 文件,
并将其放入 $GITEA_CUSTOM/public/assets/ 目录。然后将以下内容添加到 $GITEA_CUSTOM/templates/custom/footer.tmpl:
<script> $(async () => { if (!$('.language-plantuml').length) return; await Promise.all([ $.getScript('https://your-gitea-server.com/assets/deflate.js'), $.getScript('https://your-gitea-server.com/assets/encode.js'), $.getScript('https://your-gitea-server.com/assets/plantuml_codeblock_parse.js'), ]); // Replace call with address to your plantuml server parsePlantumlCodeBlocks("https://www.plantuml.com/plantuml"); });</script>随后,您就可以在 Markdown 中添加如下代码块:
Alice -> Bob: Authentication RequestBob --> Alice: Authentication Response
Alice -> Bob: Another authentication RequestAlice <-- Bob: Another authentication Response该脚本会检测 class="language-plantuml" 的标签,不过您也可以通过为
parsePlantumlCodeBlocks 提供第二个参数来修改这一行为。
示例:使用 Online 3D Viewer 预览 CAD 文件
Section titled “示例:使用 Online 3D Viewer 预览 CAD 文件”您可以在自己的 Gitea 实例中实现 CAD 文件预览。这个实现使用的是
Online 3D Viewer。
支持以下 3D 文件格式:
3dm, 3ds, 3mf, amf, bim, brep, dae, fbx, fcstd, glb,
gltf, ifc, igs, iges, stp, step, stl, obj, off, ply, wrl
(.gltf 文件仅支持 v2)
第 1 部分:添加模板
Section titled “第 1 部分:添加模板”我们需要在 $GITEA_CUSTOM 中添加模板。
该模板需要保存到 $GITEA_CUSTOM/templates/custom/ 中。
在这里创建 footer.tmpl 文件,并向其中添加以下内容:
nano $GITEA_CUSTOM/templates/custom/footer.tmpl<script> function onPageChange() { // Supported 3D file types const fileTypes = ['3dm', '3ds', '3mf', 'amf', 'bim', 'brep', 'dae', 'fbx', 'fcstd', 'glb', 'gltf', 'ifc', 'igs', 'iges', 'stp', 'step', 'stl', 'obj', 'off', 'ply', 'wrl'];
// Select matching link const links = Array.from(document.querySelectorAll('a.ui.mini.basic.button')); const link3D = links.find(link => { const href = link.href.toLowerCase(); return href.includes('/raw/') && fileTypes.some(ext => href.endsWith(`.${ext}`)); });
if (link3D) { const existingScript = document.querySelector('script[src="/assets/o3dv/o3dv.min.js"]');
const initializeViewer = () => { const fileUrl = link3D.getAttribute('href');
const fileView = document.querySelector('.file-view');
if (!fileView) return;
// Remove only the old viewer container if it exists const oldView3D = document.getElementById('view-3d'); if (oldView3D) { oldView3D.remove(); // safely remove old viewer container div } else { // No #view-3d, so remove all children inside .file-view while (fileView.firstChild) { fileView.removeChild(fileView.firstChild); } }
// Create a new container for the viewer const newView3D = document.createElement('div'); newView3D.id = 'view-3d'; newView3D.style.padding = '0'; newView3D.style.margin = '0'; newView3D.style.flexGrow = '1'; newView3D.style.minHeight = '0'; newView3D.style.width = '100%';
const header = document.querySelector('header'); const headerHeight = header ? header.offsetHeight : 0;
newView3D.style.height = `calc(100vh - ${headerHeight}px)`;
// Append the new container inside fileView fileView.appendChild(newView3D);
const parentDiv = document.getElementById('view-3d'); if (parentDiv) { const viewer = new OV.EmbeddedViewer(parentDiv, { backgroundColor: new OV.RGBAColor(59, 68, 76, 0), defaultColor: new OV.RGBColor(200, 200, 200), edgeSettings: new OV.EdgeSettings(false, new OV.RGBColor(0, 0, 0), 1), environmentSettings: new OV.EnvironmentSettings([ '/assets/o3dv/envmaps/fishermans_bastion/negx.jpg', '/assets/o3dv/envmaps/fishermans_bastion/posx.jpg', '/assets/o3dv/envmaps/fishermans_bastion/posy.jpg', '/assets/o3dv/envmaps/fishermans_bastion/negy.jpg', '/assets/o3dv/envmaps/fishermans_bastion/posz.jpg', '/assets/o3dv/envmaps/fishermans_bastion/negz.jpg' ], false) });
viewer.LoadModelFromUrlList([fileUrl]); } };
if (typeof OV === 'undefined') { if (!existingScript) { const script = document.createElement('script'); script.onload = initializeViewer; script.src = '/assets/o3dv/o3dv.min.js'; document.head.appendChild(script); } else { // Script is loading but OV not yet ready — wait for it existingScript.addEventListener('load', initializeViewer); } } else { // OV already loaded initializeViewer(); } } };
// Run when the page is fully loaded document.addEventListener('DOMContentLoaded', onPageChange);
const targetSelector = 'a.ui.mini.basic.button[href*="/raw/"]'; let lastHref = null; let timeoutId = null;
const checkAndRun = () => { const rawLink = document.querySelector(targetSelector); if (!rawLink) return;
const currentHref = rawLink.getAttribute('href'); if (currentHref !== lastHref) { lastHref = currentHref;
const fileName = currentHref.split('/').pop(); console.log('New Raw file link detected after delay:', fileName);
onPageChange(); } };
const observer = new MutationObserver(() => { // Delay execution by 300ms after last mutation clearTimeout(timeoutId); timeoutId = setTimeout(checkAndRun, 300); });
observer.observe(document.body, { childList: true, subtree: true, });</script>第 2 部分:添加公共文件
Section titled “第 2 部分:添加公共文件”现在我们需要下载最新版本的 O3DV。进入 $GITEA_CUSTOM/public/assets/。
使用以下命令创建目录(并进入该目录):
mkdir o3dvcd o3dv从 GitHub 复制最新发行版压缩包链接
(当前示例版本为 v0.18.0)。
然后使用例如 wget 或 curl 下载该文件:
wget https://github.com/kovacsv/Online3DViewer/releases/download/0.18.0/o3dv.zip或者
curl -L -O https://github.com/kovacsv/Online3DViewer/releases/download/0.18.0/o3dv.zip再使用例如 unzip 解压归档文件:
unzip o3dv.zip第 3 部分:目录权限
Section titled “第 3 部分:目录权限”最后一步,修改 public 目录权限:
chown -R git:git $GITEA_CUSTOM/public现在一切就绪!重启您的 Gitea 实例以应用这些更改,并在浏览器中进行测试。
简单检查一下。最终目录结构应类似如下:
$GITEA_CUSTOM/templates-- custom `-- footer.tmpl
$GITEA_CUSTOM/public/assets/-- o3dv |-- o3dv.zip |-- o3dv.license.md |-- o3dv.min.js |-- envmaps \...自定义 Gitea 邮件
Section titled “自定义 Gitea 邮件”$GITEA_CUSTOM/templates/mail 目录允许您修改 Gitea 每一种邮件的正文。
可被覆盖的模板可以在 Gitea 源码的
templates/mail
目录中找到。
覆盖方式是将对应文件复制到 $GITEA_CUSTOM/templates/mail 下,
并保持与源码一致的完整路径结构。
任何包含在 {{ 和 }} 中的语句都是 Gitea 的模板语法,
如果您没有完全理解这些组件,就不应修改它们。
为 Gitea 添加统计分析
Section titled “为 Gitea 添加统计分析”Google Analytics、Matomo(原 Piwik)以及其他分析服务都可以集成到 Gitea。
要添加跟踪代码,请参考本文的“页面中的其他插入内容”一节,
并将相应 JavaScript 添加到 $GITEA_CUSTOM/templates/custom/header.tmpl 文件中。
自定义 gitignores、labels、licenses、locales 和 readmes
Section titled “自定义 gitignores、labels、licenses、locales 和 readmes”将自定义文件放入 custom/options 下对应的子目录中。
gitignores
Section titled “gitignores”要添加自定义 .gitignore,请在 $GITEA_CUSTOM/options/gitignore 中添加一个文件,
文件内容遵循现有的 .gitignore 规则。
自定义 git 配置
Section titled “自定义 git 配置”从 Gitea 1.20 开始,您可以通过 git.config 区块自定义 git 配置。
启用签名 git push
Section titled “启用签名 git push”签名推送
允许客户端对 push 操作本身进行加密签名(而不仅仅是对单个提交签名)。
要启用签名推送,请将以下内容添加到 app.ini:
[git.config]receive.certNonceSeed = <randomstring>certNonceSeed 应设置为一个随机字符串并妥善保密。它用于生成防重放 nonce。
Gitea 默认已经设置了 receive.advertisePushOptions = true,因此无需额外配置。
请注意,Gitea 不会读取 /etc/gitconfig,因此必须像上面这样通过 app.ini 设置该选项。
在客户端侧,可以通过 git push --signed 进行签名推送,
或者使用 git config --global push.gpgSign if-asked 永久启用。
Labels
Section titled “Labels”从 Gitea 1.19 开始,您可以向 $GITEA_CUSTOM/options/label 中添加一个遵循
YAML 标签格式
的文件:
labels: - name: "foo/bar" # 下拉列表中显示的标签名称 exclusive: true # 是否为作用域标签使用互斥命名空间,作用域分隔符为 / color: aabbcc # 十六进制颜色值 description: Some label # 标签用途的详细描述旧的传统文件格式 仍可使用,格式如下,但我们强烈建议改用新的 YAML 格式。
#hex-color label name ; label description
更多信息请参阅标签文档。
Licenses
Section titled “Licenses”要添加自定义许可证,请将包含许可证文本的文件添加到 $GITEA_CUSTOM/options/license。
Locales
Section titled “Locales”本地化语言由我们的 Crowdin 管理。
您可以通过将修改后的语言文件放到 $GITEA_CUSTOM/options/locale 中来覆盖某个语言环境。
Gitea 默认的语言文件可以在源码目录
options/locale 中找到,
这些文件可以作为您修改时的参考示例。
如果要添加一个全新的语言环境,除了将文件放到上述位置外,
您还需要在 app.ini 的 [i18n] 部分中添加新的语言代码和名称。
请记住,Gitea 会将这些设置视为覆盖项,因此如果您还想保留其他语言,
就需要复制默认值并在其中加入您自己的语言项。
[i18n]LANGS = en-US,foo-BARNAMES = English,FooBar如果用户浏览器的语言与列表中的任何语言都不匹配,则第一种语言会被用作默认语言。
不同版本之间的语言文件可能会变化,因此强烈建议持续跟踪您自定义过的语言文件。
Readmes
Section titled “Readmes”要添加自定义 Readme,请将一个 Markdown 格式的文件(不带 .md 扩展名)
放到 $GITEA_CUSTOM/options/readme 中。
Reactions
Section titled “Reactions”要修改反应表情,您可以在 app.ini 中设置允许使用的 reactions。
[ui]REACTIONS = +1, -1, laugh, confused, heart, hooray, eyes完整的受支持 emoji 列表见 emoji list。
自定义 Gitea 外观
Section titled “自定义 Gitea 外观”内置主题有 gitea-light、gitea-dark 和 gitea-auto
(会自动适应操作系统设置)。
默认主题可以通过 app.ini 中 ui 部分的
DEFAULT_THEME 进行修改。
Gitea 还支持用户主题,这意味着每位用户都可以选择要使用的主题。
用户可选主题列表可以通过 app.ini 中 ui
部分的 THEMES 值进行配置。
要让所有用户都能使用自定义主题:
- 将 CSS 文件添加到
$GITEA_CUSTOM/public/assets/css/theme-<theme-name>.css。 您可以通过执行gitea help并查看其中的 “CustomPath” 值来确认实例的$GITEA_CUSTOM。 - 将
<theme-name>添加到app.ini中THEMES设置的逗号分隔列表中, 或者将THEMES留空以允许所有主题。
名为 theme-my-theme.css 的自定义主题文件会在用户主题选择页面中显示为 my-theme。
您还可以在自定义主题 CSS 文件中加入主题元信息,以提供更多说明。
如果自定义主题是暗色主题,请在 :root 块中设置全局 CSS 变量 --is-dark-theme: true。
这样 Gitea 就可以相应地调整 Monaco 代码编辑器的主题。
如果要实现 “auto” 主题,可以参考 theme-gitea-auto.css。
gitea-theme-meta-info { --theme-display-name: "My Awesome Theme"; /* this theme will be display as "My Awesome Theme" on the UI */}:root { --is-dark-theme: true; /* if it is a dark theme */ --color-primary: #112233; /* more custom theme variables ... */}社区主题列在 gitea/awesome-gitea#themes。
默认主题源码可在这里找到。
可以使用 CSS 变量自定义字体:
:root { --fonts-proportional: /* custom proportional fonts */ !important; --fonts-monospace: /* custom monospace fonts */ !important; --fonts-emoji: /* custom emoji fonts */ !important;}