Add api page (#32)

# Changes

- Added [redocusaurus](https://github.com/rohit-gohri/redocusaurus) package to display swagger api with reference to [woodpecker](https://github.com/woodpecker-ci/woodpecker/tree/master/docs)
- Change `sed` for swagger.json for proper version and baseurl.
- Add a dropdown for different api versions. (screenshot below)
- On API pages, only API version dropdown will show(hide locale dropdown, version dropdown for doc, and doc search)
- Allow build CSR API pages for development so it saves building time.

# Screenshots

![Screen Shot 2023-06-27 at 11.56.59](/attachments/7f43976d-f9f1-42ff-85f5-0bc84e549441)

![Screen Shot 2023-06-27 at 10.58.11](/attachments/bde25da5-b0a6-4908-9c69-c6aed41f8f59)

![Screen Shot 2023-06-21 at 12.26.26](/attachments/84a9bf5a-229b-4031-9654-3bae6cb3301a)

![Screen Shot 2023-06-19 at 16.34.33](/attachments/653b2b59-bc8a-4e6c-82f2-eb9710f55d8d)

Search:

![Screen Shot 2023-06-21 at 14.49.15](/attachments/3a09bd89-36a8-4156-a2df-2d3176d3ddb1)

Reviewed-on: https://gitea.com/gitea/gitea-docusaurus/pulls/32
Co-authored-by: HesterG <hestergong@gmail.com>
Co-committed-by: HesterG <hestergong@gmail.com>
This commit is contained in:
HesterG
2023-07-05 03:54:54 +00:00
committed by Lunny Xiao
parent a6ca489269
commit 04a97d20b1
14 changed files with 2069 additions and 60 deletions

View File

@@ -38,8 +38,7 @@ jobs:
rm static/_* rm static/_*
- name: build site - name: build site
run: | run: |
npm ci make build
npm run build
- name: aws credential configure - name: aws credential configure
uses: https://github.com/aws-actions/configure-aws-credentials@v1 uses: https://github.com/aws-actions/configure-aws-credentials@v1
with: with:

View File

@@ -34,5 +34,4 @@ jobs:
rm static/_* rm static/_*
- name: build site - name: build site
run: | run: |
npm ci make build
npm run build

View File

@@ -1,8 +1,4 @@
ifeq ($(shell sed --version 2>/dev/null | grep -q GNU && echo gnu),gnu) export NODE_OPTIONS := "--max-old-space-size=4096"
SED_INPLACE := sed -i
else
SED_INPLACE := sed -i ''
endif
.PHONY: all .PHONY: all
all: build all: build
@@ -36,8 +32,8 @@ prepare-latest: clone_main
cp -r .tmp/upstream-docs-latest/docs/static/* static/ cp -r .tmp/upstream-docs-latest/docs/static/* static/
rsync -avz --prune-empty-dirs --include '*/' --include='*.en-us.md' --exclude '*' .tmp/upstream-docs-latest/docs/content/doc/ docs/ rsync -avz --prune-empty-dirs --include '*/' --include='*.en-us.md' --exclude '*' .tmp/upstream-docs-latest/docs/content/doc/ docs/
cp .tmp/upstream-docs-latest/docs/content/page/index.en-us.md docs/intro.md cp .tmp/upstream-docs-latest/docs/content/page/index.en-us.md docs/intro.md
cp .tmp/upstream-docs-latest/templates/swagger/v1_json.tmpl static/latest-swagger.json cp .tmp/upstream-docs-latest/templates/swagger/v1_json.tmpl static/swagger-latest.json
bash loop_docs.sh lastest en-us bash loop_docs.sh latest en-us
.PHONY: prepare-latest-zh-cn .PHONY: prepare-latest-zh-cn
prepare-latest-zh-cn: prepare-latest-zh-cn:
@@ -46,7 +42,8 @@ prepare-latest-zh-cn:
mkdir -p i18n/zh-cn/docusaurus-plugin-content-docs/current mkdir -p i18n/zh-cn/docusaurus-plugin-content-docs/current
rsync -avz --prune-empty-dirs --include '*/' --include='*.zh-cn.md' --exclude '*' .tmp/upstream-docs-latest/docs/content/doc/ i18n/zh-cn/docusaurus-plugin-content-docs/current/ rsync -avz --prune-empty-dirs --include '*/' --include='*.zh-cn.md' --exclude '*' .tmp/upstream-docs-latest/docs/content/doc/ i18n/zh-cn/docusaurus-plugin-content-docs/current/
cp .tmp/upstream-docs-latest/docs/content/page/index.zh-cn.md i18n/zh-cn/docusaurus-plugin-content-docs/current/intro.md cp .tmp/upstream-docs-latest/docs/content/page/index.zh-cn.md i18n/zh-cn/docusaurus-plugin-content-docs/current/intro.md
bash loop_docs.sh lastest zh-cn bash loop_docs.sh latest zh-cn
rm -rf .tmp/upstream-docs-latest
.PHONY: clone_\#% .PHONY: clone_\#%
clone_\#%: create_dir clone_\#%: create_dir
@@ -61,7 +58,7 @@ prepare\#%: clone_\#%
cp -r .tmp/upstream-docs-$*/docs/static/* static/ cp -r .tmp/upstream-docs-$*/docs/static/* static/
rsync -a --prune-empty-dirs --include '*/' --include='*.en-us.md' --exclude '*' .tmp/upstream-docs-$*/docs/content/doc/ versioned_docs/version-1.$*/ rsync -a --prune-empty-dirs --include '*/' --include='*.en-us.md' --exclude '*' .tmp/upstream-docs-$*/docs/content/doc/ versioned_docs/version-1.$*/
cp .tmp/upstream-docs-$*/docs/content/page/index.en-us.md versioned_docs/version-1.$*/intro.md cp .tmp/upstream-docs-$*/docs/content/page/index.en-us.md versioned_docs/version-1.$*/intro.md
cp .tmp/upstream-docs-$*/templates/swagger/v1_json.tmpl static/$*-swagger.json cp .tmp/upstream-docs-$*/templates/swagger/v1_json.tmpl static/swagger-$*.json
bash loop_docs.sh $* en-us bash loop_docs.sh $* en-us
.PHONY: prepare-zh-cn\#% .PHONY: prepare-zh-cn\#%
@@ -72,18 +69,22 @@ prepare-zh-cn\#%:
rsync -avz --prune-empty-dirs --include '*/' --include='*.zh-cn.md' --exclude '*' .tmp/upstream-docs-$*/docs/content/doc/ i18n/zh-cn/docusaurus-plugin-content-docs/version-1.$*/ rsync -avz --prune-empty-dirs --include '*/' --include='*.zh-cn.md' --exclude '*' .tmp/upstream-docs-$*/docs/content/doc/ i18n/zh-cn/docusaurus-plugin-content-docs/version-1.$*/
cp .tmp/upstream-docs-$*/docs/content/page/index.zh-cn.md i18n/zh-cn/docusaurus-plugin-content-docs/version-1.$*/intro.md cp .tmp/upstream-docs-$*/docs/content/page/index.zh-cn.md i18n/zh-cn/docusaurus-plugin-content-docs/version-1.$*/intro.md
bash loop_docs.sh $* zh-cn bash loop_docs.sh $* zh-cn
rm -rf .tmp/upstream-docs-$*
.PHONY: install .PHONY: install
install: install:
npm install npm install
.PHONY: prepare-docs
prepare-docs: install prepare-latest prepare\#20 prepare\#19 prepare-latest-zh-cn prepare-zh-cn\#20 prepare-zh-cn\#19 prepare-awesome-latest prepare-awesome\#19 prepare-awesome\#20
.PHONY: build .PHONY: build
build: install prepare-latest prepare\#19 prepare\#20 prepare-latest-zh-cn prepare-zh-cn\#19 prepare-zh-cn\#20 prepare-awesome-latest prepare-awesome\#19 prepare-awesome\#20 build:
npm ci npm ci
npm run build npm run build
.PHONY: serve .PHONY: serve
serve: install prepare-latest prepare\#19 prepare\#20 prepare-latest-zh-cn prepare-zh-cn\#19 prepare-zh-cn\#20 prepare-awesome-latest prepare-awesome\#19 prepare-awesome\#20 serve: prepare-docs
npm run start npm run start
.PHONY: clean .PHONY: clean
@@ -92,6 +93,6 @@ clean:
rm -rf docs rm -rf docs
rm -rf versioned_docs/ rm -rf versioned_docs/
rm -rf static/_* rm -rf static/_*
rm -rf static/latest-swagger.json rm -rf static/swagger-latest.json
rm -rf static/19-swagger.json rm -rf static/swagger-19.json
rm -rf static/20-swagger.json rm -rf static/swagger-20.json

View File

@@ -4,6 +4,7 @@
```shell ```shell
make clean make clean
make prepare-docs
make build make build
``` ```
@@ -11,6 +12,7 @@ make build
```shell ```shell
make clean make clean
make prepare-docs
make serve make serve
``` ```
@@ -38,3 +40,12 @@ npx docusaurus write-translations --locale zh-cn
npm run build npm run build
npm run serve npm run serve
``` ```
## Use CSR Api
This is for development, api pages will be CSR so this saves building time
```
npm run start-CSRApi
npm run build-CSRApi
```

View File

@@ -13,6 +13,40 @@ function sortItemsByCategory(items) {
return sortedItems; return sortedItems;
} }
const includeAPI = process.env.INCLUDE_API !== 'false';
const apiConfig = [
'redocusaurus',
{
// Plugin Options for loading OpenAPI files
specs: includeAPI ? [
{
spec: 'static/swagger-latest.json',
route: '/api/next/',
},
{
route: '/api/1.20/',
spec: 'static/swagger-20.json',
},
{
route: '/api/1.19/',
spec: 'static/swagger-19.json',
},
]: [],
// Theme Options for modifying how redoc renders them
theme: {
// Change with your site colors
primaryColor: '#1890ff',
},
},
]
const pageConfig = includeAPI ? {
exclude: [
'api/**',
],
}: {}
/** @type {import('@docusaurus/types').Config} */ /** @type {import('@docusaurus/types').Config} */
const config = { const config = {
title: 'Gitea Documentation', title: 'Gitea Documentation',
@@ -82,8 +116,10 @@ const config = {
theme: { theme: {
customCss: require.resolve('./src/css/custom.css'), customCss: require.resolve('./src/css/custom.css'),
}, },
pages: pageConfig,
}), }),
], ],
apiConfig,
], ],
themes: [ themes: [
[ [
@@ -119,10 +155,28 @@ const config = {
}, },
items: [ items: [
{ {
to: '/', type: 'doc',
docId: 'intro',
position: 'left', position: 'left',
label: 'Docs', label: 'Docs',
}, },
{
to: '/api/1.19/',
label: 'API',
position: 'left',
activeBaseRegex: 'api/(1.19|1.20|next)/',
},
{
type: 'dropdown',
label: 'API Version',
position: 'right',
items: [
{to: '/api/next/', label: '1.21-dev' },
{to: '/api/1.20/', label: '1.20.0-rc0' },
{to: '/api/1.19/', label: '1.19.3' },
],
className: 'api-dropdown',
},
{ {
href: 'https://github.com/go-gitea/gitea', href: 'https://github.com/go-gitea/gitea',
label: 'Code', label: 'Code',

View File

@@ -15,7 +15,7 @@ SED_INPLACE() {
} }
version="$1" version="$1"
if [ "$version" != "lastest" ]; then if [ "$version" != "latest" ]; then
version="1.$1" version="1.$1"
fi fi
locale="$2" locale="$2"
@@ -31,7 +31,7 @@ elif ["$version" == "1.20"]; then
fi fi
docs_dir="versioned_docs/version-$version" docs_dir="versioned_docs/version-$version"
if [ "$version" == "lastest" ]; then if [ "$version" == "latest" ]; then
if [ "$locale" == "en-us" ]; then if [ "$locale" == "en-us" ]; then
docs_dir="docs" docs_dir="docs"
else else
@@ -58,13 +58,14 @@ SED_INPLACE "s/{{< min-go-version >}}/$minGoVer/" "$docs_dir/installation/from-s
# TODO: improve this sed # TODO: improve this sed
# need confirmation # need confirmation
if [ "$version" == "lastest" ]; then if [ "$version" == "latest" ]; then
SED_INPLACE 's/"version":.*/"version":"1.21-dev"/' static/latest-swagger.json SED_INPLACE 's/"version": "{{AppVer | JSEscape | Safe}}"/"version": "1.21-dev"/' static/swagger-latest.json
elif [ "$version" == "1.20" ]; then elif [ "$version" == "1.20" ]; then
SED_INPLACE 's/"version":.*/"version":"1.20.0-rc2"/' static/20-swagger.json SED_INPLACE 's/"version": "{{AppVer | JSEscape | Safe}}"/"version": "1.20.0-rc2"/' static/swagger-20.json
elif [ "$version" == "1.19" ]; then elif [ "$version" == "1.19" ]; then
SED_INPLACE 's/"version":.*/"version":"1.19.3"/' static/19-swagger.json SED_INPLACE 's/"version": "{{AppVer | JSEscape | Safe}}"/"version": "1.19.3"/' static/swagger-19.json
fi fi
SED_INPLACE 's/"basePath": "{{AppSubUrl | JSEscape | Safe}}/"basePath": "https:\/\/gitea.com/' static/swagger-"$1".json
for file in `find ./"$docs_dir" -name "*.md"`; do for file in `find ./"$docs_dir" -name "*.md"`; do
# hide hugo toc # hide hugo toc

1914
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -5,7 +5,9 @@
"scripts": { "scripts": {
"docusaurus": "docusaurus", "docusaurus": "docusaurus",
"start": "docusaurus start", "start": "docusaurus start",
"start-CSRApi": "cross-env INCLUDE_API='false' docusaurus start",
"build": "docusaurus build", "build": "docusaurus build",
"build-CSRApi": "cross-env INCLUDE_API='false' docusaurus build",
"swizzle": "docusaurus swizzle", "swizzle": "docusaurus swizzle",
"deploy": "docusaurus deploy", "deploy": "docusaurus deploy",
"clear": "docusaurus clear", "clear": "docusaurus clear",
@@ -21,10 +23,12 @@
"clsx": "^1.2.1", "clsx": "^1.2.1",
"prism-react-renderer": "^1.3.5", "prism-react-renderer": "^1.3.5",
"react": "^17.0.2", "react": "^17.0.2",
"react-dom": "^17.0.2" "react-dom": "^17.0.2",
"redocusaurus": "^1.6.3"
}, },
"devDependencies": { "devDependencies": {
"@docusaurus/module-type-aliases": "^2.3.1" "@docusaurus/module-type-aliases": "^2.3.1",
"cross-env": "^7.0.3"
}, },
"browserslist": { "browserslist": {
"production": [ "production": [

View File

@@ -0,0 +1,12 @@
import React from 'react';
import ApiDoc from '@theme/ApiDoc';
// For csr api pages
export default function ClientOnly(props) {
return (
<ApiDoc
specProps={{
url: props.swaggerPath,
}}
/>
);
}

View File

@@ -1,4 +1,4 @@
import React from 'react' import React from 'react';
import Translate from '@docusaurus/Translate'; import Translate from '@docusaurus/Translate';
export default function Outdated(props) { export default function Outdated(props) {

View File

@@ -58,3 +58,57 @@
background-color: rgb(7, 19, 24); background-color: rgb(7, 19, 24);
color: rgb(184, 231, 251); color: rgb(184, 231, 251);
} }
.redocusaurus .menu-content {
top: 70px !important;
height: calc(100vh - 70px) !important;
}
/* The following css is for toggling API version dropdown/menu,
selectors like :first-of-type are for browsers those do not support :has */
/* Do not show doc search on api pages */
body:has(.redocusaurus) [class*='searchBox'],
.plugin-redoc [class*='searchBox'],
.plugin-pages [class*='searchBox'] {
display: none;
}
@media (min-width: 996px) {
/* hide api-dropdown on other pages */
.navbar__item.dropdown:not(:has(.api-dropdown)),
.navbar__item.dropdown:first-of-type {
display: none;
}
/* show api-dropdown dropdown and hide other dropdowns on api pages */
body:has(.redocusaurus) .navbar__item.dropdown:not(:has(.api-dropdown)),
.plugin-redoc .navbar__item.dropdown:not(:first-of-type),
.plugin-pages .navbar__item.dropdown:not(:first-of-type) {
display: none;
}
body:has(.redocusaurus) .navbar__item.dropdown:has(.api-dropdown),
.plugin-redoc .navbar__item.dropdown:first-of-type,
.plugin-pages .navbar__item.dropdown:first-of-type {
display: block;
}
}
@media (max-width: 996px) {
/* need to find a way to customize the classname */
/* on mobile, dropdown becomes menu list */
/* Hide api version menu on other pages */
.menu__list-item.menu__list-item--collapsed:has(.api-dropdown),
.menu__list-item.menu__list-item--collapsed:nth-of-type(3) {
display: none;
}
/* Hide collapsible menus except for API menu on API pages */
body:has(.redocusaurus) .menu__list-item.menu__list-item--collapsed:not(:has(.api-dropdown)),
.plugin-redoc .menu__list-item.menu__list-item--collapsed:not(:first-of-type),
.plugin-pages .menu__list-item.menu__list-item--collapsed:not(:first-of-type) {
display: none;
}
/* Show collapsible API menu on API pages */
body:has(.redocusaurus) .menu__list-item:has(.api-dropdown),
.plugin-redoc .menu__list-item:nth-of-type(3),
.plugin-pages .menu__list-item:nth-of-type(3) {
display: list-item !important;
}
}

View File

@@ -0,0 +1,8 @@
import React from 'react';
import ClientOnly from '@site/src/components/ClientOnly';
export default function Api19() {
return (
<ClientOnly swaggerPath="/swagger-19.json"/>
);
}

View File

@@ -0,0 +1,8 @@
import React from 'react';
import ClientOnly from '@site/src/components/ClientOnly';
export default function Api20() {
return (
<ClientOnly swaggerPath="/swagger-20.json"/>
);
}

View File

@@ -0,0 +1,8 @@
import React from 'react';
import ClientOnly from '@site/src/components/ClientOnly';
export default function ApiLatest() {
return (
<ClientOnly swaggerPath="/swagger-latest.json"/>
);
}