Add version v28 (#564)

<!-- cloudflare-preview --> Preview: https://pr-564.docs-gitea-com.pages.dev

Reviewed-on: https://gitea.com/gitea/docs/pulls/564
Reviewed-by: bircni <[email protected]>
Co-authored-by: Lunny Xiao <[email protected]>
This commit is contained in:
Lunny Xiao authored and bircni committed 2026-09-30 06:40:44 +00:00
1 parent deb2f068d4
commit ba60edbbda
338 files changed
+114457 -47

No files matched your search

@@ -0,0 +1,9 @@
{
"label": "貢獻",
"position": 35,
"link": {
"type": "generated-index",
"slug": "/contributing",
"title": "貢獻"
}
}
@@ -0,0 +1,110 @@
---
date: "2023-05-25T23:41:00+08:00"
slug: "guidelines-backend"
sidebar_position: 20
aliases:
- /zh-tw/guidelines-backend
---
# 後端開發指南
## 背景
Gitea 使用 Golang 作為後端編程語言。它使用了許多第三方包,並且自己也編寫了一些包。
例如,Gitea 使用[Chi](https://github.com/go-chi/chi)作為基本的 Web 框架。[Xorm](https://xorm.io)是一個用於與資料庫交互的 ORM 框架。
因此,管理這些包非常重要。在開始編寫後端程式碼之前,請參考以下準則。
## 包設計準則
### 包列表
為了保持易於理解的程式碼並避免循環依賴,擁有良好的程式碼結構是很重要的。Gitea 後端分為以下幾個部分:
- `build`:幫助構建 Gitea 的腳本。
- `cmd`:包含所有 Gitea 的實際子命令,包括 web、doctor、serv、hooks、admin 等。`web`將啟動 Web 服務。`serv`和`hooks`將被 Git 或 OpenSSH 調用。其他子命令可以幫助維護 Gitea。
- `tests`:常用的測試函數
- `tests/integration`:整合測試,用於測試後端迴歸。
- `tests/e2e`:端到端測試,用於測試前端和後端的相容性和視覺迴歸。
- `models`:包含由 xorm 用於構建資料庫表的資料結構。它還包含查詢和更新資料庫的函數。應避免與其他 Gitea 程式碼的依賴關係。在某些情況下,比如日誌記錄時可以例外。
- `models/db`:基本的資料庫操作。所有其他`models/xxx`包都應依賴於此包。`GetEngine`函數只能從 models/中調用。
- `models/fixtures`:單元測試和整合測試中使用的範例資料。一個`yml`文件表示一個將在測試開始時加載到資料庫中的表。
- `models/migrations`:儲存不同版本之間的資料庫遷移。修改資料庫結構的 PR**必須**包含一個遷移步驟。
- `modules`:在 Gitea 中處理特定功能的不同模組。工作正在進行中:其中一些模組應該移到`services`中,特別是那些依賴於 models 的模組,因為它們依賴於資料庫。
- `modules/setting`:儲存從 ini 文件中讀取的所有系統設定,並在各處引用。但是在可能的情況下,應將其作為函數參數使用。
- `modules/git`:用於與`Git`命令行或 Gogit 包交互的包。
- `public`:編譯後的前端文件(JavaScript、圖像、CSS 等)
- `routers`:處理伺服器請求。由於它使用其他 Gitea 包來處理請求,因此其他包(models、modules 或 services)不能依賴於 routers。
- `routers/api`:包含`/api/v1`相關路由,用於處理 RESTful API 請求。
- `routers/install`:只能在系統處於安裝模式(INSTALL_LOCK=false)時響應。
- `routers/private`:僅由內部子命令調用,特別是`serv`和`hooks`。
- `routers/web`:處理來自 Web 瀏覽器或 Git SMART HTTP 協議的 HTTP 請求。
- `services`:用於常見路由操作或命令執行的支援函數。使用`models`和`modules`來處理請求。
- `templates`:用於生成 HTML 輸出的 Golang 模板。
### 包依賴關係
由於 Golang 不支援導入循環,我們必須仔細決定包之間的依賴關係。這些包之間有一些級別。以下是理想的包依賴關係方向。
`cmd` -> `routers` -> `services` -> `models` -> `modules`
從左到右,左側的包可以依賴於右側的包,但右側的包不能依賴於左側的包。在同一級別的子包中,可以根據該級別的規則進行依賴。
**注意事項**
為什麼我們需要在`models`之外使用資料庫事務?以及如何使用?
某些操作在資料庫記錄插入/更新/刪除失敗時應該允許回滾。
因此,服務必須能夠建立資料庫事務。以下是一些範例:
```go
// services/repository/repository.go
func CreateXXXX() error {
return db.WithTx(func(ctx context.Context) error {
// do something, if err is returned, it will rollback automatically
if err := issues.UpdateIssue(ctx, repoID); err != nil {
// ...
return err
}
// ...
return nil
})
}
```
在`services`中**不應該**直接使用`db.GetEngine(ctx)`,而是應該在`models/`下編寫一個函數。
如果該函數將在事務中使用,請將`context.Context`作為函數的第一個參數。
```go
// models/issues/issue.go
func UpdateIssue(ctx context.Context, repoID int64) error {
e := db.GetEngine(ctx)
// ...
}
```
### 包名稱
對於頂層包,請使用複數作為包名,例如`services`、`models`,對於子包,請使用單數,例如`services/user`、`models/repository`。
### 導入別名
由於有一些使用相同包名的包,例如`modules/user`、`models/user`和`services/user`,當這些包在一個 Go 文件中被導入時,很難知道我們使用的是哪個包以及它是變量名還是導入名。因此,我們始終建議使用導入別名。為了與常見的駝峰命名法的包變量區分開,建議使用**snake_case**作為導入別名的命名規則。
例如:`import user_service "code.gitea.io/gitea/services/user"`
### 重要注意事項
- 永遠不要寫成`x.Update(exemplar)`,而沒有明確的`WHERE`子句:
- 這將導致表中的所有行都被使用 exemplar 的非零值進行更新,包括 ID。
- 通常應該寫成`x.ID(id).Update(exemplar)`。
- 如果在遷移過程中使用`x.Insert(exemplar)`向表中插入記錄,而 ID 是預設的:
- 對於 MSSQL 變體,你將需要執行`` SET IDENTITY_INSERT `table` ON ``(否則遷移將失敗)
- 對於 PostgreSQL,你還需要更新 ID 序列,否則遷移將悄無聲息地通過,但後續的插入將失敗:
`` SELECT setval('table_name_id_seq', COALESCE((SELECT MAX(id)+1 FROM `table_name`), 1), false) ``
### 未來的任務
目前,我們正在進行一些重構,以完成以下任務:
- 糾正不符合規則的程式碼。
- `models`中的文件太多了,所以我們正在將其中的一些移動到子包`models/xxx`中。
- 由於它們依賴於`models`,因此應將某些`modules`子包移動到`services`中。
@@ -0,0 +1,149 @@
---
date: "2023-05-25T16:00:00+02:00"
slug: "guidelines-frontend"
sidebar_position: 20
aliases:
- /zh-tw/guidelines-frontend
---
# 前端開發指南
## 背景
Gitea 在其前端中使用[Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html)(基於[jQuery](https://api.jquery.com))和 [Vue3](https://vuejs.org/)。
HTML 頁面由[Go HTML Template](https://pkg.go.dev/html/template)渲染。
源文件可以在以下目錄中找到:
- **CSS 樣式**: `web_src/css/`
- **JavaScript 文件**: `web_src/js/`
- **Vue 元件**: `web_src/js/components/`
- **Go HTML 模板**: `templates/`
## 通用準則
我們推薦使用[Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html)和[Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html)。
## Gitea 特定準則
1. 每個功能(Fomantic-UI/jQuery 模組)應放在單獨的文件/目錄中。
2. HTML 的 id 和 class 應使用 kebab-case,最好包含 2-3 個與功能相關的關鍵詞。
3. 在 JavaScript 中使用的 HTML 的 id 和 class 應在整個專案中是唯一的,並且應包含 2-3 個與功能相關的關鍵詞。建議在僅在 JavaScript 中使用的 class 中使用 `js-` 前綴。
4. 不應覆蓋框架提供的 class 的 CSS 樣式。始終使用具有 2-3 個與功能相關的關鍵詞的新 class 名稱來覆蓋框架樣式。Gitea 中的幫助 CSS 類在 `helpers.less` 中。
5. 後端可以透過使用`ctx.PageData["myModuleData"] = map[]{}`將複雜資料傳遞給前端,但不要將整個模型暴露給前端,以避免泄露敏感資料。
6. 簡單頁面和與 SEO 相關的頁面使用 Go HTML 模板渲染生成靜態的 Fomantic-UI HTML 輸出。複雜頁面可以使用 Vue3。
7. 明確變量類型,優先使用`elem.disabled = true`而不是`elem.setAttribute('disabled', 'anything')`,優先使用`$el.prop('checked', var === 'yes')`而不是`$el.prop('checked', var)`。
8. 使用語義化元素,優先使用`<button class="ui button">`而不是`<div class="ui button">`。
9. 避免在 CSS 中使用不必要的`!important`,如果無法避免,添加註釋解釋為什麼需要它。
10. 避免在一個事件監聽器中混合不同的事件,優先為每個事件使用獨立的事件監聽器。
11. 推薦使用自訂事件名稱前綴`ce-`。
12. 建議使用 Tailwind CSS,它可以透過 `tw-` 前綴獲得,例如 `tw-relative`. Gitea 自身的助手類 CSS 使用 `gt-` 前綴(`gt-ellipsis`),Gitea 自身的私有框架級 CSS 類使用 `g-` 前綴(`g-modal-confirm`)。
13. 儘量避免內聯腳本和樣式,建議將 JS 程式碼放入 JS 文件中並使用 CSS 類。如果內聯腳本和樣式不可避免,請解釋無法避免的原因。
### 可訪問性 / ARIA
在歷史上,Gitea 大量使用了可訪問性不友好的框架 Fomantic UI。
Gitea 使用一些補丁使 Fomantic UI 更具可訪問性(參見 `aria.md`),
但仍然存在許多問題需要大量的工作和時間來修復。
### 框架使用
不建議混合使用不同的框架,這會使程式碼難以維護。
一個 JavaScript 模組應遵循一個主要框架,並遵循該框架的最佳實踐。
推薦的實現方式:
- Vue + Vanilla JS
- Fomantic-UI(jQuery)
- htmx (部分頁面重新加載其他靜態元件)
- Vanilla JS
不推薦的實現方式:
- Vue + Fomantic-UI(jQuery)
- jQuery + Vanilla JS
- htmx + 任何其他需要大量 JavaScript 程式碼或不必要的功能,如 htmx 腳本 (`hx-on`)
為了保持介面一致,Vue 元件可以使用 Fomantic-UI 的 CSS 類。
儘管不建議混合使用不同的框架,
我們使用 htmx 進行簡單的交互。您可以在此 [PR](https://github.com/go-gitea/gitea/pull/28908) 中查看一個簡單交互的範例,其中應使用 htmx。如果您需要更高級的反應性,請不要使用 htmx,請使用其他框架(Vue/Vanilla JS)。
但如果混合使用是必要的,並且程式碼設計良好且易於維護,也可以工作。
### `async` 函數
只有當函數內部存在`await`調用或返回`Promise`時,纔將函數標記為`async`。
不建議使用`async`事件監聽器,這可能會導致問題。
原因是`await`後的程式碼在事件分發之外執行。
參考:https://github.com/github/eslint-plugin-github/blob/main/docs/rules/async-preventdefault.md
如果一個事件監聽器必須是`async`,應在任何`await`之前使用`e.preventDefault()`,
建議將其放在函數的開頭。
如果我們想在非異步上下文中調用`async`函數,
建議使用`const _promise = asyncFoo()`來告訴讀者
這是有意為之的,我們想調用異步函數並忽略 Promise。
一些 lint 規則和 IDE 也會在未處理返回的 Promise 時發出警告。
### 獲取資料
要獲取資料,請使用`modules/fetch.js`中的包裝函數`GET`、`POST`等。他們
接受內容的`data`選項,將自動設定 CSRF 令牌並返回
[Response](https://developer.mozilla.org/en-US/docs/Web/API/Response)。
### HTML 屬性和 dataset
禁止使用`dataset`,它的駝峰命名行為使得搜索屬性變得困難。
然而,仍然存在一些特殊情況,因此當前的準則是:
- 對於舊程式碼:
- 應將`$.data()`重構為`$.attr()`。
- 在極少數情況下,可以使用`$.data()`將一些非字符串資料綁定到元素上,但強烈不推薦使用。
- 對於新程式碼:
- 不應使用`node.dataset`,而應使用`node.getAttribute`。
- 不要將任何使用者資料綁定到 DOM 節點上,使用合適的設計模式描述節點和資料之間的關係。
### 顯示/隱藏元素
- 推薦在 Vue 元件中使用`v-if`和`v-show`來顯示/隱藏元素。
- Go 模板程式碼應使用 `.tw-hidden` 和 `showElem()/hideElem()/toggleElem()` 來顯示/隱藏元素,請參閱`.tw-hidden`的註釋以獲取更多詳細資訊。
### Go HTML 模板中的樣式和屬性
建議使用以下方式:
```html
<div
class="gt-name1 gt-name2 {{if .IsFoo}}gt-foo{{end}}"
{{if
.IsFoo}}data-foo{{end}}
></div>
```
而不是:
```html
<div
class="gt-name1 gt-name2{{if .IsFoo}} gt-foo{{end}}"
{{if
.IsFoo}}
data-foo{{end}}
></div>
```
以使程式碼更易讀。
### 舊程式碼
許多舊程式碼已經存在於本文撰寫之前。建議重構舊程式碼以遵循指南。
### Vue3 和 JSX
Gitea 現在正在使用 Vue3。我們決定不引入 JSX,以保持 HTML 程式碼和 JavaScript 程式碼分離。
### UI 範例
Gitea 使用一些自制的 UI 元素並自訂其他元素,以將它們更好地整合到通用 UI 方法中。當在開發模式(`RUN_MODE=dev`)下運行 Gitea 時,在 `http(s)://your-gitea-url:port/devtest` 下會提供一個包含一些標準化 UI 範例的頁面。
@@ -0,0 +1,40 @@
---
date: "2023-05-25T00:00:00+00:00"
slug: "guidelines-refactoring"
sidebar_position: 20
aliases:
- /zh-tw/guidelines-refactoring
---
# 重構指南
## 背景
自 2014 年 2 月 12 日編寫了第一行程式碼以來,Gitea 已經發展成為一個龐大的專案。
因此,程式碼庫變得越來越大。程式碼庫越大,維護就越困難。
存在許多過時的機制,許多框架混合在一起,一些遺留程式碼可能會導致錯誤並阻礙新功能的開發。
為了使程式碼庫更易於維護,使 Gitea 變得更好,開發人員應牢記使用現代機制來重構舊程式碼。
本文件是關於重構程式碼庫的指南集合。
## 重構建議
- 設計更多關於未來的內容,而不僅僅解決當前問題。
- 減少模糊性,減少衝突,提高可維護性。
- 描述重構,例如:
- 為什麼需要重構。
- 如何解決舊問題。
- 重構的優點/缺點是什麼。
- 只做必要的更改,儘量保留舊邏輯。
- 引入一些中間步驟,使重構更容易審查,完整的重構計劃可以在幾個 PR 中完成。
- 如果存在分歧,應該請 TOC(技術監督委員會)參與決策。
- 添加必要的測試以確保重構的正確性。
- 非錯誤重構優先在里程碑的開始時進行,這樣可以更容易地在發佈之前發現問題。
## 審查和合併建議
- 重構的 PR 不應該長時間保持打開狀態(通常為 7 天),應儘快進行審查。
- 重構的 PR 應儘快合併,不應被其他 PR 阻塞。
- 如果 TOC 沒有異議,重構的 PR 可以在 7 天后由一名核心成員(非作者)批准後合併。
- 如果最終結果良好,容忍一些不完美/臨時的步驟。
- 如果重構是必要的,容忍一些迴歸錯誤,並儘快修復錯誤。
@@ -0,0 +1,25 @@
---
date: "2016-12-01T16:00:00+02:00"
slug: "localization"
sidebar_position: 70
aliases:
- /zh-tw/localization
---
# 本地化
Gitea 的本地化是通過我們的[Crowdin 專案](https://crowdin.com/project/gitea)進行的。
對於對**英語翻譯**的更改,可以發出 pull-request,來更改[英語語言環境](https://github.com/go-gitea/gitea/blob/main/options/locale/locale_en-US.ini)中合適的關鍵字。
有關對**非英語**翻譯的更改,請參閱上面的 Crowdin 專案。
## 支援的語言
上述 Crowdin 專案中列出的任何語言一旦翻譯了 25% 或更多都將得到支援。
翻譯被接受後,它將在下一次 Crowdin 同步後反映在主儲存庫中,這通常是在任何 PR 合併之後。
在撰寫本文時,這意味著更改後的翻譯可能要到 Gitea 的下一個版本纔會出現。
如果使用開發版本,則在同步更改內容後,它應該會在更新後立即顯示。