2021-10-14 22:35:26 -04:00
---
date: "2021-10-13T16:00:00+02:00"
title: "Guidelines for Frontend Development"
slug: "guidelines-frontend"
2023-07-26 00:53:13 -04:00
sidebar_position: 30
2021-10-14 22:35:26 -04:00
toc: false
draft: false
Refactor docs (#23752)
This was intended to be a small followup for
https://github.com/go-gitea/gitea/pull/23712, but...here we are.
1. Our docs currently use `slug` as the entire URL, which makes
refactoring tricky (see https://github.com/go-gitea/gitea/pull/23712).
Instead, this PR attempts to make future refactoring easier by using
slugs as an extension of the section. (Hugo terminology)
- What the above boils down to is this PR attempts to use directory
organization as URL management. e.g. `usage/comparison.en-us.md` ->
`en-us/usage/comparison/`, `usage/packages/overview.en-us.md` ->
`en-us/usage/packages/overview/`
- Technically we could even remove `slug`, as Hugo defaults to using
filename, however at least with this PR it means `slug` only needs to be
the name for the **current file** rather than an entire URL
2. This PR adds appropriate aliases (redirects) for pages, so anything
on the internet that links to our docs should hopefully not break.
3. A minor nit I've had for a while, renaming `seek-help` to `support`.
It's a minor thing, but `seek-help` has a strange connotation to it.
4. The commits are split such that you can review the first which is the
"actual" change, and the second is added redirects so that the first
doesn't break links elsewhere.
---------
Signed-off-by: jolheiser <john.olheiser@gmail.com>
2023-04-27 23:33:41 -04:00
aliases:
- /en-us/guidelines-frontend
2021-10-14 22:35:26 -04:00
menu:
sidebar:
2023-03-23 11:18:24 -04:00
parent: "contributing"
2021-10-14 22:35:26 -04:00
name: "Guidelines for Frontend"
2023-07-26 00:53:13 -04:00
sidebar_position: 30
2021-10-14 22:35:26 -04:00
identifier: "guidelines-frontend"
---
# Guidelines for Frontend Development
## Background
2023-03-14 22:20:19 -04:00
Gitea uses [Fomantic-UI ](https://fomantic-ui.com/introduction/getting-started.html ) (based on [jQuery ](https://api.jquery.com )) and [Vue3 ](https://vuejs.org/ ) for its frontend.
2021-10-14 22:35:26 -04:00
2022-04-12 16:36:24 -04:00
The HTML pages are rendered by [Go HTML Template ](https://pkg.go.dev/html/template ).
The source files can be found in the following directories:
2022-07-27 21:22:47 -04:00
2023-03-14 22:20:19 -04:00
* **CSS styles:** `web_src/css/`
2022-06-06 10:44:20 -04:00
* **JavaScript files:** `web_src/js/`
* **Vue components:** `web_src/js/components/`
* **Go HTML templates:** `templates/`
2021-10-14 22:35:26 -04:00
## 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.
2023-02-21 01:13:37 -05:00
2. HTML ids and classes should use kebab-case, it's preferred to contain 2-3 feature related keywords.
2021-10-14 22:35:26 -04:00
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.
2023-02-21 01:13:37 -05:00
4. CSS styling for classes provided by frameworks should not be overwritten. Always use new class names with 2-3 feature related keywords to overwrite framework styles. Gitea's helper CSS classes in `helpers.less` could be helpful.
5. The backend can pass complex data to the frontend by using `ctx.PageData["myModuleData"] = map[]{}` , but do not expose whole models to the frontend to avoid leaking sensitive data.
6. Simple pages and SEO-related pages use Go HTML Template render to generate static Fomantic-UI HTML output. Complex pages can use Vue3.
7. Clarify variable types, prefer `elem.disabled = true` instead of `elem.setAttribute('disabled', 'anything')` , prefer `$el.prop('checked', var === 'yes')` instead of `$el.prop('checked', var)` .
8. Use semantic elements, prefer `<button class="ui button">` instead of `<div class="ui button">` .
9. Avoid unnecessary `!important` in CSS, add comments to explain why it's necessary if it can't be avoided.
2023-03-05 09:23:42 -05:00
10. Avoid mixing different events in one event listener, prefer to use individual event listeners for every event.
11. Custom event names are recommended to use `ce-` prefix.
2023-04-24 07:08:59 -04:00
12. Gitea's tailwind-style CSS classes use `gt-` prefix (`gt-relative`), while Gitea's own private framework-level CSS classes use `g-` prefix (`g-modal-confirm`).
2023-02-21 01:13:37 -05:00
### Accessibility / ARIA
In history, Gitea heavily uses Fomantic UI which is not an accessibility-friendly framework.
Gitea uses some patches to make Fomantic UI more accessible (see the `aria.js` and `aria.md` ),
but there are still many problems which need a lot of work and time to fix.
2021-10-14 22:35:26 -04:00
2021-11-22 06:40:17 -05:00
### Framework Usage
2022-06-06 10:44:20 -04:00
Mixing different frameworks together is discouraged, it makes the code difficult to be maintained.
A JavaScript module should follow one major framework and follow the framework's best practice.
2021-11-22 06:40:17 -05:00
Recommended implementations:
2022-07-27 21:22:47 -04:00
2022-06-06 10:44:20 -04:00
* Vue + Vanilla JS
2021-11-22 06:40:17 -05:00
* Fomantic-UI (jQuery)
2022-06-06 10:44:20 -04:00
* Vanilla JS
2021-11-22 06:40:17 -05:00
Discouraged implementations:
2022-07-27 21:22:47 -04:00
2022-06-06 10:44:20 -04:00
* Vue + Fomantic-UI (jQuery)
* jQuery + Vanilla JS
To make UI consistent, Vue components can use Fomantic-UI CSS classes.
2022-07-27 21:22:47 -04:00
Although mixing different frameworks is discouraged,
it should also work if the mixing is necessary and the code is well-designed and maintainable.
2021-11-22 06:40:17 -05:00
2021-11-12 07:37:45 -05:00
### `async` Functions
2022-07-27 21:22:47 -04:00
Only mark a function as `async` if and only if there are `await` calls
2021-11-12 07:37:45 -05:00
or `Promise` returns inside the function.
2022-06-02 00:22:42 -04:00
It's not recommended to use `async` event listeners, which may lead to problems.
2022-07-27 21:22:47 -04:00
The reason is that the code after await is executed outside the event dispatch.
2021-11-12 07:37:45 -05:00
Reference: https://github.com/github/eslint-plugin-github/blob/main/docs/rules/async-preventdefault.md
2023-03-02 11:46:47 -05:00
If an event listener must be `async` , the `e.preventDefault()` should be before any `await` ,
it's recommended to put it at the beginning of the function.
2021-11-12 07:37:45 -05:00
If we want to call an `async` function in a non-async context,
it's recommended to use `const _promise = asyncFoo()` to tell readers
that this is done by purpose, we want to call the async function and ignore the Promise.
Some lint rules and IDEs also have warnings if the returned Promise is not handled.
2023-09-11 04:25:10 -04:00
### Fetching data
To fetch data, use the wrapper functions `GET` , `POST` etc. from `modules/fetch.js` . They
2023-09-18 20:50:30 -04:00
accept a `data` option for the content, will automatically set CSRF token and return a
2023-09-11 04:25:10 -04:00
Promise for a [Response ](https://developer.mozilla.org/en-US/docs/Web/API/Response ).
2021-11-22 06:40:17 -05:00
### HTML Attributes and `dataset`
2022-06-06 10:44:20 -04:00
The usage of `dataset` is forbidden, its camel-casing behaviour makes it hard to grep for attributes.
However, there are still some special cases, so the current guideline is:
2021-11-22 06:40:17 -05:00
* For legacy code:
* `$.data()` should be refactored to `$.attr()` .
* `$.data()` can be used to bind some non-string data to elements in rare cases, but it is highly discouraged.
* For new code:
2022-07-27 21:22:47 -04:00
* `node.dataset` should not be used, use `node.getAttribute` instead.
2021-11-22 06:40:17 -05:00
* never bind any user data to a DOM node, use a suitable design pattern to describe the relation between node and data.
2023-02-18 23:06:14 -05:00
### Show/Hide Elements
* Vue components are recommended to use `v-if` and `v-show` to show/hide elements.
* Go template code should use Gitea's `.gt-hidden` and `showElem()/hideElem()/toggleElem()` , see more details in `.gt-hidden` 's comment.
2023-03-05 09:23:42 -05:00
### Styles and Attributes in Go HTML Template
It's recommended to use:
```html
< div class = "gt-name1 gt-name2 {{if .IsFoo}}gt-foo{{end}}" { { if . IsFoo } } data-foo { { end } } > < / div >
```
instead of:
```html
< div class = "gt-name1 gt-name2{{if .IsFoo}} gt-foo{{end}}" { { if . IsFoo } } data-foo { { end } } > < / div >
```
to make the code more readable.
2022-06-06 10:44:20 -04:00
### Legacy Code
A lot of legacy code already existed before this document's written. It's recommended to refactor legacy code to follow the guidelines.
2022-10-01 22:13:44 -04:00
### Vue3 and JSX
2021-10-14 22:35:26 -04:00
2022-10-01 22:13:44 -04:00
Gitea is using Vue3 now. We decided not to introduce JSX to keep the HTML and the JavaScript code separated.
2023-07-31 06:49:21 -04:00
### UI Examples
Gitea uses some self-made UI elements and customizes others to integrate them better into the general UI approach. When running Gitea in development mode (`RUN_MODE=dev`), a page with some standardized UI examples is available under `http(s)://your-gitea-url:port/devtest` .