diff --git a/.eslintrc b/.eslintrc index bab34478cf..4419e16a35 100644 --- a/.eslintrc +++ b/.eslintrc @@ -3,8 +3,6 @@ reportUnusedDisableDirectives: true ignorePatterns: - /web_src/js/vendor - - /templates/repo/activity.tmpl - - /templates/repo/view_file.tmpl parserOptions: sourceType: module diff --git a/.gitignore b/.gitignore index 5bf71be65d..10d9574f33 100644 --- a/.gitignore +++ b/.gitignore @@ -9,6 +9,8 @@ _test # IntelliJ .idea +# Goland's output filename can not be set manually +/go_build_* # MS VSCode .vscode diff --git a/docs/content/doc/developers/guidelines-frontend.md b/docs/content/doc/developers/guidelines-frontend.md new file mode 100644 index 0000000000..86286127aa --- /dev/null +++ b/docs/content/doc/developers/guidelines-frontend.md @@ -0,0 +1,51 @@ +--- +date: "2021-10-13T16:00:00+02:00" +title: "Guidelines for Frontend Development" +slug: "guidelines-frontend" +weight: 20 +toc: false +draft: false +menu: + sidebar: + parent: "developers" + name: "Guidelines for Frontend" + weight: 20 + identifier: "guidelines-frontend" +--- + +# Guidelines for Frontend Development + +**Table of Contents** + +{{< toc >}} + +## Background + +Gitea uses [Less CSS](https://lesscss.org), [Fomantic-UI](https://fomantic-ui.com/introduction/getting-started.html) (based on [jQuery](https://api.jquery.com)) and [Vue2](https://vuejs.org/v2/guide/) for its frontend. + +The HTML pages are rendered by [Go HTML Template](https://pkg.go.dev/html/template) + +## General Guidelines + +We recommend [Google HTML/CSS Style Guide](https://google.github.io/styleguide/htmlcssguide.html) and [Google JavaScript Style Guide](https://google.github.io/styleguide/jsguide.html) + +### Gitea specific guidelines: + +1. Every feature (Fomantic-UI/jQuery module) should be put in separate files/directories. +2. HTML ids and classes should use kebab-case. +3. HTML ids and classes used in JavaScript should be unique for the whole project, and should contain 2-3 feature related keywords. We recommend to use the `js-` prefix for classes that are only used in JavaScript. +4. jQuery events across different features should use their own namespaces. +5. CSS styling for classes provided by frameworks should not be overwritten. Always use new class-names to overwrite framework styles. We recommend to use the `us-` prefix for user defined styles. +6. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}` +7. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue2 (or Vue3 in future). + +## Legacy Problems and Solutions + +### Too much code in `web_src/index.js` + +Previously, most JavaScript code was written into `web_src/index.js` directly, making the file unmaintainable. +Try to keep this file small by creating new modules instead. These modules can be put in the `web_src/js/features` directory for now. + +### Vue2/Vue3 and JSX + +Gitea is using Vue2 now, we plan to upgrade to Vue3. We decided not to introduce JSX to keep the HTML and the JavaScript code separated. diff --git a/docs/content/doc/developers/hacking-on-gitea.en-us.md b/docs/content/doc/developers/hacking-on-gitea.en-us.md index 23e3b37680..d91d80e626 100644 --- a/docs/content/doc/developers/hacking-on-gitea.en-us.md +++ b/docs/content/doc/developers/hacking-on-gitea.en-us.md @@ -132,7 +132,14 @@ See `make help` for all available `make` targets. Also see [`.drone.yml`](https: To run and continuously rebuild when source files change: ```bash +# for both frontend and backend make watch + +# or: watch frontend files (html/js/css) only +make watch-frontend + +# or: watch backend files (go) only +make watch-backend ``` On macOS, watching all backend source files may hit the default open files limit which can be increased via `ulimit -n 12288` for the current shell or in your shell startup file for all future shells. @@ -167,7 +174,9 @@ make revive vet misspell-check ### Working on JS and CSS -Either use the `watch-frontend` target mentioned above or just build once: +Frontend development should follow [Guidelines for Frontend Development](./guidelines-frontend.md) + +To build with frontend resources, either use the `watch-frontend` target mentioned above or just build once: ```bash make build && ./gitea diff --git a/modules/context/context.go b/modules/context/context.go index 29f52c53cd..6bd934928e 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -51,7 +51,7 @@ type Context struct { Resp ResponseWriter Req *http.Request Data map[string]interface{} // data used by MVC templates - PageData map[string]interface{} // data used by JavaScript modules in one page + PageData map[string]interface{} // data used by JavaScript modules in one page, it's `window.config.pageData` Render Render translation.Locale Cache cache.Cache @@ -645,9 +645,10 @@ func Contexter() func(next http.Handler) http.Handler { "CurrentURL": setting.AppSubURL + req.URL.RequestURI(), "PageStartTime": startTime, "Link": link, + "IsProd": setting.IsProd(), }, } - // PageData is passed by reference, and it will be rendered to `window.config.PageData` in `head.tmpl` for JavaScript modules + // PageData is passed by reference, and it will be rendered to `window.config.pageData` in `head.tmpl` for JavaScript modules ctx.PageData = map[string]interface{}{} ctx.Data["PageData"] = ctx.PageData diff --git a/routers/web/repo/activity.go b/routers/web/repo/activity.go index dcb7bf57cd..f9d248b06e 100644 --- a/routers/web/repo/activity.go +++ b/routers/web/repo/activity.go @@ -60,7 +60,7 @@ func Activity(ctx *context.Context) { return } - if ctx.Data["ActivityTopAuthors"], err = models.GetActivityStatsTopAuthors(ctx.Repo.Repository, timeFrom, 10); err != nil { + if ctx.PageData["repoActivityTopAuthors"], err = models.GetActivityStatsTopAuthors(ctx.Repo.Repository, timeFrom, 10); err != nil { ctx.ServerError("GetActivityStatsTopAuthors", err) return } diff --git a/routers/web/user/home.go b/routers/web/user/home.go index 2f1fca4527..d2b67e6e59 100644 --- a/routers/web/user/home.go +++ b/routers/web/user/home.go @@ -106,7 +106,10 @@ func Dashboard(ctx *context.Context) { ctx.Data["Title"] = ctxUser.DisplayName() + " - " + ctx.Tr("dashboard") ctx.Data["PageIsDashboard"] = true ctx.Data["PageIsNews"] = true - ctx.Data["SearchLimit"] = setting.UI.User.RepoPagingNum + + ctx.PageData["dashboardRepoList"] = map[string]interface{}{ + "searchLimit": setting.UI.User.RepoPagingNum, + } if setting.Service.EnableUserHeatmap { data, err := models.GetUserHeatmapDataByUserTeam(ctxUser, ctx.Org.Team, ctx.User) diff --git a/templates/base/head.tmpl b/templates/base/head.tmpl index 817bdae288..80bb121c6b 100644 --- a/templates/base/head.tmpl +++ b/templates/base/head.tmpl @@ -1,6 +1,6 @@ - + {{if .Title}}{{.Title | RenderEmojiPlain}} - {{end}} {{if .Repository.Name}}{{.Repository.Name}} - {{end}}{{AppName}} @@ -12,15 +12,6 @@ - {{if .IsSigned}} - - {{end}} - {{if .ContextUser}} - - {{end}} - {{if .SearchLimit}} - - {{end}} {{if .GoGetImport}} @@ -31,10 +22,11 @@ AppVer: '{{AppVer}}', AppSubUrl: '{{AppSubUrl}}', AssetUrlPrefix: '{{AssetUrlPrefix}}', + IsProd: {{.IsProd}}, CustomEmojis: {{CustomEmojis}}, UseServiceWorker: {{UseServiceWorker}}, csrf: '{{.CsrfToken}}', - PageData: {{ .PageData }}, + pageData: {{ .PageData }}, HighlightJS: {{if .RequireHighlightJS}}true{{else}}false{{end}}, SimpleMDE: {{if .RequireSimpleMDE}}true{{else}}false{{end}}, Tribute: {{if .RequireTribute}}true{{else}}false{{end}}, diff --git a/templates/repo/activity.tmpl b/templates/repo/activity.tmpl index 08e2a31115..d4cff880e5 100644 --- a/templates/repo/activity.tmpl +++ b/templates/repo/activity.tmpl @@ -108,11 +108,8 @@ {{.i18n.Tr "repo.activity.git_stats_and_deletions" }} {{.i18n.Tr (TrN .i18n.Lang .Activity.Code.Deletions "repo.activity.git_stats_deletion_1" "repo.activity.git_stats_deletion_n") .Activity.Code.Deletions }}. -
- - +
+
{{end}} @@ -126,7 +123,7 @@
{{range .Activity.PublishedReleases}}

-

{{$.i18n.Tr "repo.activity.published_release_label"}}
+ {{$.i18n.Tr "repo.activity.published_release_label"}} {{.TagName}} {{if not .IsTag}} {{.Title | RenderEmoji}} @@ -145,7 +142,7 @@
{{range .Activity.MergedPRs}}

-

{{$.i18n.Tr "repo.activity.merged_prs_label"}}
+ {{$.i18n.Tr "repo.activity.merged_prs_label"}} #{{.Index}} {{.Issue.Title | RenderEmoji}} {{TimeSinceUnix .MergedUnix $.Lang}}

@@ -161,7 +158,7 @@
{{range .Activity.OpenedPRs}}

-

{{$.i18n.Tr "repo.activity.opened_prs_label"}}
+ {{$.i18n.Tr "repo.activity.opened_prs_label"}} #{{.Index}} {{.Issue.Title | RenderEmoji}} {{TimeSinceUnix .Issue.CreatedUnix $.Lang}}

@@ -177,7 +174,7 @@
{{range .Activity.ClosedIssues}}

-

{{$.i18n.Tr "repo.activity.closed_issue_label"}}
+ {{$.i18n.Tr "repo.activity.closed_issue_label"}} #{{.Index}} {{.Title | RenderEmoji}} {{TimeSinceUnix .ClosedUnix $.Lang}}

@@ -193,7 +190,7 @@
{{range .Activity.OpenedIssues}}

-

{{$.i18n.Tr "repo.activity.new_issue_label"}}
+ {{$.i18n.Tr "repo.activity.new_issue_label"}} #{{.Index}} {{.Title | RenderEmoji}} {{TimeSinceUnix .CreatedUnix $.Lang}}

@@ -212,7 +209,7 @@
{{range .Activity.UnresolvedIssues}}

-

{{$.i18n.Tr "repo.activity.unresolved_conv_label"}}
+ {{$.i18n.Tr "repo.activity.unresolved_conv_label"}} #{{.Index}} {{if .IsPull}} {{.Title | RenderEmoji}} diff --git a/templates/repo/issue/view_content.tmpl b/templates/repo/issue/view_content.tmpl index 95c9296174..9ad6bee651 100644 --- a/templates/repo/issue/view_content.tmpl +++ b/templates/repo/issue/view_content.tmpl @@ -9,7 +9,7 @@ {{end}} - + diff --git a/templates/repo/view_file.tmpl b/templates/repo/view_file.tmpl index 8e75bcb4ca..0c8990a4f5 100644 --- a/templates/repo/view_file.tmpl +++ b/templates/repo/view_file.tmpl @@ -131,13 +131,3 @@
- - diff --git a/templates/user/dashboard/repolist.tmpl b/templates/user/dashboard/repolist.tmpl index f39d3711d4..e2cfa76e88 100644 --- a/templates/user/dashboard/repolist.tmpl +++ b/templates/user/dashboard/repolist.tmpl @@ -1,8 +1,7 @@ -
+
${reposTotalCount}
- + {{svg "octicon-plus"}} {{.i18n.Tr "new_repo"}} @@ -122,7 +121,7 @@