diff --git a/.github/workflows/node.yml b/.github/workflows/node.yml
index d1c2b73d7..096c0d28b 100644
--- a/.github/workflows/node.yml
+++ b/.github/workflows/node.yml
@@ -21,21 +21,12 @@ jobs:
uses: actions/setup-node@v4
with:
node-version: ${{ matrix.node }}
- - name: Install node module
- run: |
- npm install -D --save autoprefixer
- npm install -D --save postcss-cli
- npm audit fix
-
- - name: Setup Hugo
- uses: peaceiris/actions-hugo@v3
- with:
- hugo-version: '0.125.4'
- extended: true
+ - name: Install node modules
+ run: npm install
- name: Build
run: |
- hugo --minify
+ npm run build
echo 'gin-gonic.com' > public/CNAME
- name: Deploy
@@ -43,4 +34,4 @@ jobs:
if: github.ref == 'refs/heads/master'
with:
github_token: ${{ secrets.GITHUB_TOKEN }}
- publish_dir: ./public
+ publish_dir: ./dist
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index 516d63513..0790de384 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,7 +11,24 @@
# Output of the go coverage tool, specifically when used with LiteIDE
*.out
-public
-resources
-node_modules
-.hugo_build.lock
+# build output
+dist/
+# generated types
+.astro/
+
+# dependencies
+node_modules/
+
+# logs
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+pnpm-debug.log*
+
+
+# environment variables
+.env
+.env.production
+
+# macOS-specific files
+.DS_Store
diff --git a/assets/scss/_variables_project.scss b/assets/scss/_variables_project.scss
deleted file mode 100644
index ea30c0e40..000000000
--- a/assets/scss/_variables_project.scss
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-
-Add styles or override variables from the theme here.
-
-*/
-
-$primary: #3176d9 !default;
-$dark: #3176d9 !default;
-
diff --git a/astro.config.mjs b/astro.config.mjs
new file mode 100644
index 000000000..0cd52785d
--- /dev/null
+++ b/astro.config.mjs
@@ -0,0 +1,98 @@
+// @ts-check
+import { defineConfig } from 'astro/config';
+import starlight from '@astrojs/starlight';
+import starlightUtils from "@lorenzo_lewis/starlight-utils";
+
+// https://astro.build/config
+export default defineConfig({
+
+ integrations: [
+ starlight({
+ plugins: [starlightUtils({
+ multiSidebar: {
+ switcherStyle: "horizontalList",
+ },
+ })],
+
+ title: 'Gin Web Framework',
+ favicon: '/favicon.ico',
+ logo: {
+ src: "./src/assets/gin.png",
+ },
+
+ defaultLocale: 'en',
+ locales: {
+ 'en': {
+ label: 'English',
+ lang: 'en',
+ },
+ 'es': {
+ label: 'Español',
+ lang: 'es',
+ },
+ "fa": {
+ label: "Persian",
+ lang: "fa",
+ },
+ "ja": {
+ label: "日本語",
+ lang: "ja",
+ },
+ "ko-kr": {
+ label: "한국어",
+ lang: "ko-kr",
+ },
+ "pt": {
+ label: "Português",
+ lang: "pt",
+ },
+ "ru": {
+ label: "Russian",
+ lang: "ru",
+ },
+ "tr": {
+ label: "Turkish",
+ lang: "tr",
+ },
+ "zh-cn": {
+ label: "简体中文",
+ lang: "zh-cn",
+ },
+ "zh-tw": {
+ label: "繁體中文",
+ lang: "zh-tw",
+ },
+ },
+
+ social: {
+ github: 'https://github.com/gin-gonic/gin',
+ gitter: "https://gitter.im/gin-gonic/gin"
+ },
+ sidebar: [
+ {
+ label: "Docs",
+ autogenerate: { directory: "docs" }
+ },
+ {
+ label: "Blog",
+ autogenerate: { directory: "blog" }
+ },
+ ],
+
+ customCss: [
+ './src/styles/custom.css',
+ ],
+
+ expressiveCode: {
+ themes: ['github-dark', 'github-light'],
+ },
+
+ editLink: {
+ baseUrl: 'https://github.com/gin-gonic/website/edit/master/',
+ },
+
+ lastUpdated: true,
+ credits: false, // Opcional
+ }),
+ ],
+});
diff --git a/content/en/_index.html b/content/en/_index.html
deleted file mode 100644
index d5a8b9299..000000000
--- a/content/en/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**What is Gin?**
-
-Gin is a web framework written in Golang.
-
-It features a Martini-like API, but with performance up to 40 times faster than Martini.
-
-If you need performance and productivity, you will love Gin.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Fast" %}}
-Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Middleware support" %}}
-An incoming HTTP request can be handled by a chain of middleware and the final action.
-For example: Logger, Authorization, GZIP and finally post a message in the DB.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash-free" %}}
-Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON validation" %}}
-Gin can parse and validate the JSON of a request, checking, for example, the existence of required values.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Routes grouping" %}}
-Organize your routes better. Authorization required vs non required, different API versions. In addition, groups can be nested infinitely without degrading performance.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Error management" %}}
-Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, middleware can write them to a log file, to a database and send them through the network.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Rendering built-in" %}}
-Gin provides an easy to use API for JSON, XML and HTML rendering.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Extendable" %}}
-Creating new middleware is so easy, just check out the sample code.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/en/blog/_index.md b/content/en/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/en/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/en/blog/news/_index.md b/content/en/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/en/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/en/blog/releases/_index.md b/content/en/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/en/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/en/docs/_index.md b/content/en/docs/_index.md
deleted file mode 100644
index d3d8fc28a..000000000
--- a/content/en/docs/_index.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Documentation"
-linkTitle: "Documentation"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## What is Gin?
-
-Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API, but with performance up to 40 times faster than Martini. If you need smashing performance, get yourself some Gin.
-
-## How to use Gin?
-
-We provide API usage [examples](https://github.com/gin-gonic/examples) and list some publicly known [Gin users](./users).
-
-## How to contribute to Gin?
-
-* Help people on the discussion forums
-* Tell us your success stories using Gin
-* Tell us how we can improve Gin and help us do it
-* Contribute to an existing library
-
diff --git a/content/en/docs/benchmarks/_index.md b/content/en/docs/benchmarks/_index.md
deleted file mode 100644
index c00021d12..000000000
--- a/content/en/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Benchmarks"
-draft: false
-weight: 3
----
-
-Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httprouter)
-
-[See all benchmarks](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): Total Repetitions achieved in constant time, higher means more confident result
-- (2): Single Repetition Duration (ns/op), lower is better
-- (3): Heap Memory (B/op), lower is better
-- (4): Average Allocations per Repetition (allocs/op), lower is better
diff --git a/content/en/docs/deployment/_index.md b/content/en/docs/deployment/_index.md
deleted file mode 100644
index 595d97f64..000000000
--- a/content/en/docs/deployment/_index.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Deployment"
-draft: false
-weight: 6
----
-
-Gin projects can be deployed easily on any cloud provider.
-
-## [Koyeb](https://www.koyeb.com)
-
-Koyeb is a developer-friendly serverless platform to deploy apps globally with git-based deployment, TLS encryption, native autoscaling, a global edge network, and built-in service mesh & discovery.
-
-Follow the Koyeb [guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
-
-## [Qovery](https://www.qovery.com)
-
-Qovery provides free Cloud hosting with databases, SSL, a global CDN, and automatic deploys with Git.
-
-Follow the Qovery guide to [deploy your Gin project](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
-
-## [Render](https://render.com)
-
-Render is a modern cloud platform that offers native support for Go, fully managed SSL, databases, zero-downtime deploys, HTTP/2, and websocket support.
-
-Follow the Render [guide to deploying Gin projects](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE has two ways to deploy Go applications. The standard environment is easier to use but less customizable and prevents [syscalls](https://github.com/gin-gonic/gin/issues/1639) for security reasons. The flexible environment can run any framework or library.
-
-Learn more and pick your preferred environment at [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/en/docs/examples/_index.md b/content/en/docs/examples/_index.md
deleted file mode 100644
index 1387c17b3..000000000
--- a/content/en/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Examples"
-draft: false
-weight: 6
----
-
-The section lists api usage.
diff --git a/content/en/docs/examples/ascii-json.md b/content/en/docs/examples/ascii-json.md
deleted file mode 100644
index 82ab48d2a..000000000
--- a/content/en/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/bind-body-into-dirrerent-structs.md b/content/en/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index c685ccaba..000000000
--- a/content/en/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Try to bind body into different structs"
-draft: false
----
-
-The normal methods for binding request body consumes `c.Request.Body` and they
-cannot be called multiple times.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Always an error is occurred by this because c.Request.Body is EOF now.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-For this, you can use `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // At this time, it reuses body stored in the context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` stores body into the context before binding. This has
-a slight impact to performance, so you should not use this method if you are
-enough to call binding at once.
-* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
-can be called by `c.ShouldBind()` multiple times without any damage to
-performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/en/docs/examples/bind-form-data-request-with-custom-struct.md b/content/en/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 2882e8656..000000000
--- a/content/en/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "Bind form-data request with custom struct"
-draft: false
----
-
-The follow example using custom struct:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Using the command `curl` command result:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/en/docs/examples/bind-html-checkbox.md b/content/en/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index ae63e1f60..000000000
--- a/content/en/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Bind html checkboxes"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-result:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/en/docs/examples/bind-query-or-post.md b/content/en/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 7ebbe739c..000000000
--- a/content/en/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "Bind query string or post data"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // If `GET`, only `Form` binding engine (`query`) used.
- // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
- // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Test it with:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/en/docs/examples/bind-single-binary-with-template.md b/content/en/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 36f0bb212..000000000
--- a/content/en/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Build a single binary with templates"
-draft: false
----
-## Use the third-party package
-
-You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate loads templates embedded by go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/content/en/docs/examples/bind-uri.md b/content/en/docs/examples/bind-uri.md
deleted file mode 100644
index 1ed4b4bdf..000000000
--- a/content/en/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Bind Uri"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err.Error()})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Test it with:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/en/docs/examples/binding-and-validation.md b/content/en/docs/examples/binding-and-validation.md
deleted file mode 100644
index 41a564a3e..000000000
--- a/content/en/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Model binding and validation"
-draft: false
----
-
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
-
-Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
-
-Also, Gin provides two sets of methods for binding:
-- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
-- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
-
-When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
-
-You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
-
-```go
-// Binding from JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Example for binding JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding a HTML form (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Sample request
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Skip validate
-
-When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/content/en/docs/examples/controlling-log-output-coloring.md b/content/en/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 81f27efe9..000000000
--- a/content/en/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Controlling Log output coloring"
-draft: false
----
-
-By default, logs output on console should be colorized depending on the detected TTY.
-
-Never colorize logs:
-
-```go
-func main() {
- // Disable log's color
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Always colorize logs:
-
-```go
-func main() {
- // Force log's color
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/cookie.md b/content/en/docs/examples/cookie.md
deleted file mode 100644
index 231473ca5..000000000
--- a/content/en/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Set and get a cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/en/docs/examples/custom-http-config.md b/content/en/docs/examples/custom-http-config.md
deleted file mode 100644
index e9a679361..000000000
--- a/content/en/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Custom HTTP configuration"
-draft: false
----
-
-Use `http.ListenAndServe()` directly, like this:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-or
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/en/docs/examples/custom-log-format.md b/content/en/docs/examples/custom-log-format.md
deleted file mode 100644
index f9ea8b6a7..000000000
--- a/content/en/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Custom log file"
-draft: false
----
-
-For example:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
- // By default gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // your custom format
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Sample Output**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/en/docs/examples/custom-middleware.md b/content/en/docs/examples/custom-middleware.md
deleted file mode 100644
index dd7407b07..000000000
--- a/content/en/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Custom Middleware"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Set example variable
- c.Set("example", "12345")
-
- // before request
-
- c.Next()
-
- // after request
- latency := time.Since(t)
- log.Print(latency)
-
- // access the status we are sending
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // it would print: "12345"
- log.Println(example)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/en/docs/examples/custom-validators.md b/content/en/docs/examples/custom-validators.md
deleted file mode 100644
index f777436cc..000000000
--- a/content/en/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Custom validators"
-draft: false
----
-
-It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking contains binded and validated data.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
-See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/content/en/docs/examples/define-format-for-the-log-of-routes.md b/content/en/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 6cfdaa68f..000000000
--- a/content/en/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Define format for the log of routes"
-draft: false
----
-
-The default log of routes is:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
-In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Listen and Server in http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/en/docs/examples/goroutines-inside-a-middleware.md b/content/en/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 122593a1b..000000000
--- a/content/en/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Goroutines inside a middleware"
-draft: false
----
-
-When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // create copy to be used inside the goroutine
- cCp := c.Copy()
- go func() {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // note that you are using the copied context "cCp", IMPORTANT
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // since we are NOT using a goroutine, we do not have to copy the context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/graceful-restart-or-stop.md b/content/en/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index aae74ebd8..000000000
--- a/content/en/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-title: "Graceful restart or stop"
-draft: false
----
-
-Do you want to graceful restart or stop your web server?
-There are some ways this can be done.
-
-We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-An alternative to endless:
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router.Handler(),
- }
-
- go func() {
- // service connections
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Wait for interrupt signal to gracefully shutdown the server with
- // a timeout of 5 seconds.
- quit := make(chan os.Signal, 1)
- // kill (no param) default send syscall.SIGTERM
- // kill -2 is syscall.SIGINT
- // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // catching ctx.Done(). timeout of 5 seconds.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/en/docs/examples/grouping-routes.md b/content/en/docs/examples/grouping-routes.md
deleted file mode 100644
index a480aa325..000000000
--- a/content/en/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Grouping routes"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Simple group: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Simple group: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/html-rendering.md b/content/en/docs/examples/html-rendering.md
deleted file mode 100644
index cfa8e825a..000000000
--- a/content/en/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML rendering"
-draft: false
----
-
-Using LoadHTMLGlob() or LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Using templates with same name in different directories
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Custom Template renderer
-
-You can also use your own html template render
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Custom Delimiters
-
-You may use custom delims
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Custom Template Funcs
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/en/docs/examples/http-method.md b/content/en/docs/examples/http-method.md
deleted file mode 100644
index 6678e155f..000000000
--- a/content/en/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Using HTTP method"
-draft: false
----
-
-```go
-func main() {
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // By default it serves on :8080 unless a
- // PORT environment variable was defined.
- router.Run()
- // router.Run(":3000") for a hard coded port
-}
-```
diff --git a/content/en/docs/examples/http2-server-push.md b/content/en/docs/examples/http2-server-push.md
deleted file mode 100644
index 83649a407..000000000
--- a/content/en/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server push"
-draft: false
----
-
-http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // use pusher.Push() to do server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Listen and Serve in https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/en/docs/examples/jsonp.md b/content/en/docs/examples/jsonp.md
deleted file mode 100644
index 63c7dc551..000000000
--- a/content/en/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/map-as-querystring-or-postform.md b/content/en/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index fa733e2ef..000000000
--- a/content/en/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Map as querystring or postform parameters"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/en/docs/examples/multipart-urlencoded-binding.md b/content/en/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 767fc6576..000000000
--- a/content/en/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded binding"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // you can bind multipart form with explicit binding declaration:
- // c.ShouldBindWith(&form, binding.Form)
- // or you can simply use autobinding with ShouldBind method:
- var form LoginForm
- // in this case proper binding will be automatically selected
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Test it with:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/en/docs/examples/multipart-urlencoded-form.md b/content/en/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 774662b1e..000000000
--- a/content/en/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded form"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/en/docs/examples/multiple-template.md b/content/en/docs/examples/multiple-template.md
deleted file mode 100644
index 0bcf46858..000000000
--- a/content/en/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Multitemplate"
-draft: false
----
-
-Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/content/en/docs/examples/only-bind-query-string.md b/content/en/docs/examples/only-bind-query-string.md
deleted file mode 100644
index d6d4e33cc..000000000
--- a/content/en/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Only bind query string"
-draft: false
----
-
-`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/en/docs/examples/param-in-path.md b/content/en/docs/examples/param-in-path.md
deleted file mode 100644
index 6e29a59c7..000000000
--- a/content/en/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Parameters in path"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // This handler will match /user/john but will not match /user/ or /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // However, this one will match /user/john/ and also /user/john/send
- // If no other routers match /user/john, it will redirect to /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/pure-json.md b/content/en/docs/examples/pure-json.md
deleted file mode 100644
index d91f905ef..000000000
--- a/content/en/docs/examples/pure-json.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
-This feature is unavailable in Go 1.6 and lower.
-
-```go
-func main() {
- r := gin.Default()
-
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/query-and-post-form.md b/content/en/docs/examples/query-and-post-form.md
deleted file mode 100644
index 0d7b18e51..000000000
--- a/content/en/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Query and post form"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/en/docs/examples/querystring-param.md b/content/en/docs/examples/querystring-param.md
deleted file mode 100644
index bcf8b55f2..000000000
--- a/content/en/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "Query string parameters"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Query string parameters are parsed using the existing underlying request object.
- // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/redirects.md b/content/en/docs/examples/redirects.md
deleted file mode 100644
index f7d823eca..000000000
--- a/content/en/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirects"
-draft: false
----
-
-Issuing a HTTP redirect is easy. Both internal and external locations are supported.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Issuing a Router redirect, use `HandleContext` like below.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/en/docs/examples/rendering.md b/content/en/docs/examples/rendering.md
deleted file mode 100644
index a9fa75b5f..000000000
--- a/content/en/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf rendering"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H is a shortcut for map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response
- // Will output protoexample.Test protobuf serialized data
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/run-multiple-service.md b/content/en/docs/examples/run-multiple-service.md
deleted file mode 100644
index ebe6223a0..000000000
--- a/content/en/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Run multiple service"
-draft: false
----
-
-See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/en/docs/examples/secure-json.md b/content/en/docs/examples/secure-json.md
deleted file mode 100644
index 9f5642167..000000000
--- a/content/en/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
-
-```go
-func main() {
- r := gin.Default()
-
- // You can also use your own secure json prefix
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/security-headers.md b/content/en/docs/examples/security-headers.md
deleted file mode 100644
index 80e11fa88..000000000
--- a/content/en/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "Security Headers"
-draft: false
----
-
-It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection).
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-You can test it via `curl`:
-
-```bash
-// Check Headers
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// Check Host Header Injection
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/en/docs/examples/serving-data-from-reader.md b/content/en/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index f5546a8c6..000000000
--- a/content/en/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Serving data from reader"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/serving-static-files.md b/content/en/docs/examples/serving-static-files.md
deleted file mode 100644
index e296ead02..000000000
--- a/content/en/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "Serving static files"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/support-lets-encrypt.md b/content/en/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index c66288e87..000000000
--- a/content/en/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Support Let's Encrypt"
-draft: false
----
-
-example for 1-line LetsEncrypt HTTPS servers.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-example for custom autocert manager.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/en/docs/examples/upload-file/_index.md b/content/en/docs/examples/upload-file/_index.md
deleted file mode 100644
index 1810e3253..000000000
--- a/content/en/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Upload files"
-draft: false
----
-
-The section lists upload file api usage.
diff --git a/content/en/docs/examples/upload-file/multiple-file.md b/content/en/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 912472dd3..000000000
--- a/content/en/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Multiple files"
-draft: false
----
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/en/docs/examples/upload-file/single-file.md b/content/en/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 22ac899f8..000000000
--- a/content/en/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Single file"
-draft: false
----
-
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
-
-> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/en/docs/examples/using-basicauth-middleware.md b/content/en/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 318aca232..000000000
--- a/content/en/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Using BasicAuth middleware"
-draft: false
----
-
-```go
-// simulate some private data
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Group using gin.BasicAuth() middleware
- // gin.Accounts is a shortcut for map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets endpoint
- // hit "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // get user, it was set by the BasicAuth middleware
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/en/docs/examples/using-middleware.md b/content/en/docs/examples/using-middleware.md
deleted file mode 100644
index 2a3159cc3..000000000
--- a/content/en/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Using middleware"
-draft: false
----
-
-```go
-func main() {
- // Creates a router without any middleware by default
- r := gin.New()
-
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- r.Use(gin.Recovery())
-
- // Per route middleware, you can add as many as you desire.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Authorization group
- // authorized := r.Group("/", AuthRequired())
- // exactly the same as:
- authorized := r.Group("/")
- // per group middleware! in this case we use the custom created
- // AuthRequired() middleware just in the "authorized" group.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // nested group
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/en/docs/examples/without-middleware.md b/content/en/docs/examples/without-middleware.md
deleted file mode 100644
index ce7b81fbb..000000000
--- a/content/en/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Without middleware by default"
-draft: false
----
-
-Use
-
-```go
-r := gin.New()
-```
-
-instead of
-
-```go
-// Default With the Logger and Recovery middleware already attached
-r := gin.Default()
-```
diff --git a/content/en/docs/examples/write-log.md b/content/en/docs/examples/write-log.md
deleted file mode 100644
index 261b8d26a..000000000
--- a/content/en/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "How to write log file"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color, you don't need console color when writing the logs to file.
- gin.DisableConsoleColor()
-
- // Logging to a file.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Use the following code if you need to write the logs to file and console at the same time.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/en/docs/faq/_index.md b/content/en/docs/faq/_index.md
deleted file mode 100644
index 389d1432a..000000000
--- a/content/en/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: record some frequently asked question from GitHub Issue tab.
-
diff --git a/content/en/docs/features/_index.md b/content/en/docs/features/_index.md
deleted file mode 100644
index f8a05efac..000000000
--- a/content/en/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Features"
-draft: false
-weight: 4
----
-
-## Gin v1 stable features:
-
-- Zero allocation router.
-
-- Still the fastest http router and framework. From routing to writing.
-
-- Complete suite of unit tests.
-
-- Battle tested.
-
-- API frozen, new releases will not break your code.
diff --git a/content/en/docs/introduction/_index.md b/content/en/docs/introduction/_index.md
deleted file mode 100644
index cbabec114..000000000
--- a/content/en/docs/introduction/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Introduction"
-draft: false
-weight: 1
----
-
-Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
-
-In this section we will walk through what Gin is, what problems it solves, and how it can help your project.
-
-Or, if you are ready to use Gin in to your project, visit the [Quickstart](https://gin-gonic.com/docs/quickstart/).
-
-## Features
-
-### Fast
-
-Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
-
-### Middleware support
-
-An incoming HTTP request can be handled by a chain of middlewares and the final action.
-For example: Logger, Authorization, GZIP and finally post a message in the DB.
-
-### Crash-free
-
-Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. As an example - it’s also possible to report this panic to Sentry!
-
-### JSON validation
-
-Gin can parse and validate the JSON of a request - for example, checking the existence of required values.
-
-### Routes grouping
-
-Organize your routes better. Authorization required vs non required, different API versions... In addition, the groups can be nested unlimitedly without degrading performance.
-
-### Error management
-
-Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, a middleware can write them to a log file, to a database and send them through the network.
-
-### Rendering built-in
-
-Gin provides an easy to use API for JSON, XML and HTML rendering.
-
-### Extendable
-
-Creating a new middleware is so easy, just check out the sample codes.
-
diff --git a/content/en/docs/jsoniter/_index.md b/content/en/docs/jsoniter/_index.md
deleted file mode 100644
index ee7ff7eed..000000000
--- a/content/en/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## Build with [jsoniter](https://github.com/json-iterator/go)
-
-Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/en/docs/quickstart/_index.md b/content/en/docs/quickstart/_index.md
deleted file mode 100644
index 410b41816..000000000
--- a/content/en/docs/quickstart/_index.md
+++ /dev/null
@@ -1,91 +0,0 @@
----
-title: "Quickstart"
-draft: false
-weight: 2
----
-
-In this quickstart, we’ll glean insights from code segments and learn how to:
-
-## Requirements
-
-- Go 1.16 or above
-
-## Installation
-
-To install Gin package, you need to install Go and set your Go workspace first.
-
-1. Download and install it:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-Or install:
-```sh
-$ go install github.com/gin-gonic/gin@latest
-```
-
-2. Import it in your code:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (Optional) Import `net/http`. This is required for example if using constants such as `http.StatusOK`.
-
-```go
-import "net/http"
-```
-
-1. Create your project folder and `cd` inside
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. Copy a starting template inside your project
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. Run your project
-
-```sh
-$ go run main.go
-```
-
-## Getting Started
-
-> Unsure how to write and execute Go code? [Click here](https://golang.org/doc/code.html).
-
-First, create a file called `example.go`:
-
-```sh
-# assume the following codes in example.go file
-$ touch example.go
-```
-
-Next, put the following code inside of `example.go`:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-And, You can run the code via `go run example.go`:
-
-```sh
-# run example.go and visit 0.0.0.0:8080/ping on browser
-$ go run example.go
-```
diff --git a/content/en/docs/testing/_index.md b/content/en/docs/testing/_index.md
deleted file mode 100644
index d8094d084..000000000
--- a/content/en/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "Testing"
-draft: false
-weight: 7
----
-
-## How to write test case for Gin?
-
-The `net/http/httptest` package is preferable way for HTTP testing.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-Test for code example above:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/en/docs/users/_index.md b/content/en/docs/users/_index.md
deleted file mode 100644
index c3c973b91..000000000
--- a/content/en/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Users"
-draft: false
-weight: 8
----
-
-##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
-
-* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
-
-* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
-
-* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
-
-* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
-
-* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
-
-* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/content/en/featured-background.jpg b/content/en/featured-background.jpg
deleted file mode 100644
index 8bb8a4cc6..000000000
Binary files a/content/en/featured-background.jpg and /dev/null differ
diff --git a/content/en/search.md b/content/en/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/en/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/content/es/_index.html b/content/es/_index.html
deleted file mode 100644
index 6095a42f9..000000000
--- a/content/es/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**¿Qué es Gin?**
-
-Gin es un framework para desarrollo web escrito en Golang.
-
-Cuenta con una API tipo martini con un rendimiento mucho mayor, hasta 40 veces más rápido.
-
-Si necesitas rendimiento y productividad amarás a Gin.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Veloz" %}}
-Enrutamiento basado en Radix tree, poco consumo de memoria. Sin reflection. Rendimiento predecible del API.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Soporte de middleware" %}}
-Una petición entrante HTTP puede ser manejada por diversos middleware encadenados y la acción final.
-Ejemplo: Logger, Authorization, GZIP y por úlitmo guardar el mensaje en la BD.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Libre de crashes" %}}
-Gin puede recibir y recuperarse de un panic ocurrido durante una petición HTTP. Así tu servidor estará siempre disponible. También es posible hacer un reporte del panic, por ejemplo ¡a Sentry!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="Validación de JSON" %}}
-Gin permite analizar y validar datos JSON en una petición, y por ejemplo, revisar la existencia de datos requeridos.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Agrupación de rutas" %}}
-Organiza mejor tus rutas: Rutas con autorización vs rutas públicas, versiones diferentes de API. Adicionalmente los grupos de rutas pueden anidarse ilimitadamente sin afectar el rendimiento.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Manejo de errores" %}}
-Gin ofrece una conveniente forma de recopilar los errores ocurridos durante una petición HTTP. Un middleware puede incluso registrarlos en un archivo de logs, la BD o enviarlos por la red.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Render incluído" %}}
-Gin cuenta con una API fácil de usar para el render de JSON, XML y HTML.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Extensible" %}}
-Crear un middleware nuevo es muy sencillo. Sólo debes revisar los códigos de ejemplo.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/es/blog/_index.md b/content/es/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/es/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/es/blog/news/_index.md b/content/es/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/es/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/es/blog/releases/_index.md b/content/es/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/es/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/es/docs/_index.md b/content/es/docs/_index.md
deleted file mode 100644
index 536c60212..000000000
--- a/content/es/docs/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Documentación"
-linkTitle: "Documentación"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## ¿Qué es Gin?
-
-Gin es un framework para desarrollo web escrito en Go (Golang). Cuenta con una API tipo martini con un rendimiento mucho mayor -- hasta 40 veces más rápido. Si necesitas un rendimiento sensacional, sírvete un Gin.
-
-## ¿Cómo usar Gin?
-
-Ofrecemos ejemplos de uso del API [ejemplos](https://github.com/gin-gonic/examples) y listas de [usuarios de Gin conocidos](./users).
-
-## ¿Cómo puedes contribuir con Gin?
-
-* Ayudando a la comunidad en los foros de discusión
-* Contándonos tus historias de éxito utilizando Gin
-* Comunícanos cómo podemos mejorar Gin y ayudando a hacerlo posible
-* Contribuyendo a una librería existente
diff --git a/content/es/docs/benchmarks/_index.md b/content/es/docs/benchmarks/_index.md
deleted file mode 100644
index b514d2099..000000000
--- a/content/es/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Benchmarks"
-draft: false
-weight: 3
----
-
-Gin usa una versión personalizada de [HttpRouter](https://github.com/julienschmidt/httprouter)
-
-[Ver todos los benchmarks](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): Repeticiones totales logradas en tiempo constante, a mayor valor el resultado es mejor
-- (2): Duración de repetición única (ns/op), el valor menor es mejor
-- (3): Memoria del heap (B/op), el valor menor es mejor
-- (4): Asignaciones promedio por repetición (allocs/op), el valor menor es mejor
diff --git a/content/es/docs/deployment/_index.md b/content/es/docs/deployment/_index.md
deleted file mode 100644
index 5e77d94eb..000000000
--- a/content/es/docs/deployment/_index.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "Despliegue"
-draft: false
-weight: 6
----
-
-Los proyectos en Gin pueden ser desplegados fácilmente en cualquier proveedor en la nube.
-
-## [Render](https://render.com)
-
-Render es una plataforma moderna en la nube que ofrece soporte nativo para Go, SSL totalmente administrado, bases de datos, despliegues con disponibilidad ininterrumpida, HTTP/2 y soporte websockets.
-
-Sigue la [guía para desplegar proyectos Gin en Render](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-Google App Engine tiene dos formas de implementar aplicaciones Go. El entorno estándar es más fácil de usar, pero menos personalizable y evita [llamadas al sistema](https://github.com/gin-gonic/gin/issues/1639) por razones de seguridad. El entorno flexible puede ejecutar cualquier framework o librería.
-
-Conoce más información y elije el entorno preferido en [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/es/docs/examples/_index.md b/content/es/docs/examples/_index.md
deleted file mode 100644
index 292a7ba78..000000000
--- a/content/es/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Ejemplos"
-draft: false
-weight: 6
----
-
-Sección con la lista de ejemplos para el uso del API.
diff --git a/content/es/docs/examples/ascii-json.md b/content/es/docs/examples/ascii-json.md
deleted file mode 100644
index 5927cc3f3..000000000
--- a/content/es/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Uso de AsciiJSON para generar respuestas JSON únicamente con caracteres ASCII y escape de caracteres no-ASCII.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // retornará : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/bind-body-into-dirrerent-structs.md b/content/es/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index 5c111dfb9..000000000
--- a/content/es/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Vincular el cuerpo de un request en distintos tipos de structs"
-draft: false
----
-
-El método común para vincular el cuerpo de un request emplea `c.Request.Body` pero presenta
-el limitante que no puede llamarse múltiples veces.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // c.ShouldBind consume c.Request.Body y no puede volverse a usar.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // La condición de error siempre se cumplirá aquí porque c.Request.Body retornará EOF.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-For this, you can use `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // Aquí se lee c.Request.Body y el resultado es almacenado en context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Esta vez, se reúsa el body almacenado en el context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // También puede aceptar otros formatos
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` almacena el cuerpo en el context antes de hacer el vínculo. Esto tiene
-un ligero impacto en el rendimiento, así que no deberías usar este método si
-no es necesario vincular más de un tipo de struct a la vez.
-* Esta característica sólamente es necesaria en algunos formatos -- `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. Para otros tipos, `Query`, `Form`, `FormPost`, `FormMultipart`,
-puede ser llamada a través de `c.ShouldBind()` sin impacto negativo
-en el rendimiento (Véase [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/es/docs/examples/bind-form-data-request-with-custom-struct.md b/content/es/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 0d4380157..000000000
--- a/content/es/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "Vincular una petición form-data con un struct personalizado"
-draft: false
----
-
-El siguiente es el ejemplo para un struct personalizado:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Empleando el comando `curl` las respuestas serían:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
diff --git a/content/es/docs/examples/bind-html-checkbox.md b/content/es/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 9ceece3c9..000000000
--- a/content/es/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Vincular checkboxes html"
-draft: false
----
-
-Revise la [información detallada](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-resultado:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/es/docs/examples/bind-query-or-post.md b/content/es/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 6053c1009..000000000
--- a/content/es/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "Vincular parámetros get o data Post"
-draft: false
----
-
-Revise la [información detallada](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // Si se usa `GET`, únicamente es empleado el `Form` binding engine (`query`).
- // Si se emplea `POST`, se revisa primero el `content-type` para `JSON` o `XML`, para así usar entonces `Form` (`form-data`).
- // Véase más en https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Puede probar con:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/es/docs/examples/bind-single-binary-with-template.md b/content/es/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 6675a83a9..000000000
--- a/content/es/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Crear un ejecutable individual con templates"
-draft: false
----
-
-Puede crear un servidor en un solo binario que contenga templates usando [go-assets](https://github.com/jessevdk/go-assets).
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate carga templates incrustadas por medio de go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-Puede ver un ejemplo completo en el directorio [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/content/es/docs/examples/bind-uri.md b/content/es/docs/examples/bind-uri.md
deleted file mode 100644
index bca67448f..000000000
--- a/content/es/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: "Vincular un Uri"
-draft: false
----
-
-Revise la [información detallada](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Se puede probar utilizando:
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/es/docs/examples/binding-and-validation.md b/content/es/docs/examples/binding-and-validation.md
deleted file mode 100644
index 774d7a360..000000000
--- a/content/es/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Vincular y validar un Modelo"
-draft: false
----
-
-Para vincular el cuerpo de un request en un tipo, puede hacerse el vínculo a un modelo. Actualmente se soporta el vínculo a JSON, XML, YAML y valores estandar para formularios (foo=bar&boo=baz).
-
-Gin emplea para realizar validación el paquete [**go-playground/validator/v10**](https://github.com/go-playground/validator). Puedes revisar la documentación completa de validación por medio de tags [aquí](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Es necesario establecer el tag correspondiente en todos los campos que se desea vincular. Por ejemplo, cuando se vinculan datos de JSON debe definirse el tag `json:"fieldname"`.
-
-Adicionalmente, Gin dispone de dos conjunto de métodos para vincular:
-- **Tipo** - Must bind (Vínculo obligatorio)
- - **Métodos** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Comportamiento** - Estos métodos emplean internamente `MustBindWith`. Si ocurre un error al vincularse, la petición se aborta con `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. Esto configura el estatus de la respuesta 400 y el header `Content-Type` se establece en `text/plain; charset=utf-8`. Nótese que si se intenta establecer otro tipo de códgio de respuesta posteriormente, provocará la generación de una advertencia `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. Para un control más personalizado de este comportamiento, puede emplearse el método equivalente `ShouldBind`.
-- **Tipo** - Should bind (Vínculo no obligatorio)
- - **Métodos** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Comportamiento** - Estos métodos implementan `ShouldBindWith` internamente. Si ocurre un error al vincularse, el error es retornado y queda a juicio del desarrollador la forma apropiada de manejar la petición y el error ocurrido.
-
-Cuando se usa el método de vínculo, Gin tratará de inferir dependiendo del valor del header Content-Type. Si se cuenta con total certeza del tipo de dato a vincular ,puede usarse `MustBindWith` ó `ShouldBindWith`.
-
-También pueden declararse los campos como requeridos. Si un campo tiene declarado el tag `binding:"required"` y el valor viene vacío devolverá un error al tratar de vincularse.
-
-```go
-// Vincular empleando JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Ejemplo para vincular JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Vincular empleando XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Ejemplo para vincular un formulario HTML (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // De esta forma se intenta vincular tratando a partir del valor del header content-type.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Petición de ejemplo
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Evitar la validación
-
-Al ejecutar el el ejemplo de arriba con el comando `curl` devuelve error a causa del tag `binding:"required"` para el campo `Password`. El error deja de aparecer si se remplaza por el tag `binding:"-"`.
diff --git a/content/es/docs/examples/controlling-log-output-coloring.md b/content/es/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index c0904ae8b..000000000
--- a/content/es/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Controlar el color del texto del Log en cónsola"
-draft: false
----
-
-Por defecto la la salida en cónsola puede tener color, dependiendo del TTY detectado.
-
-Definir logs monocromáticos:
-
-```go
-func main() {
- // Deshabilita el color del log
- gin.DisableConsoleColor()
-
- // Crea un route de gin con middleware por defecto:
- // logger y recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- // Escucha y sirve peticiones en 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-Definir logs siempre colorizados:
-
-```go
-func main() {
- // Obliga a generar logs siempre con colores
- gin.ForceConsoleColor()
-
- // Crea un route de gin con middleware por defecto:
- // logger y recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- // Escucha y sirve peticiones en 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/cookie.md b/content/es/docs/examples/cookie.md
deleted file mode 100644
index 9c1f1fa2b..000000000
--- a/content/es/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Crear y obtener una cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/es/docs/examples/custom-http-config.md b/content/es/docs/examples/custom-http-config.md
deleted file mode 100644
index 05b544669..000000000
--- a/content/es/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Configuración personalizada HTTP"
-draft: false
----
-
-Se puede utilizar `http.ListenAndServe()` directamente, como se muestra:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-ó modificando valores de la siguiente manera:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/es/docs/examples/custom-log-format.md b/content/es/docs/examples/custom-log-format.md
deleted file mode 100644
index 976599220..000000000
--- a/content/es/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Personalizar formato de Logs"
-draft: false
----
-
-For example:
-
-```go
-func main() {
- router := gin.New()
- // El middleware LoggerWithFormatter guardará los a gin.DefaultWriter
- // Por defecto gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // Formato personalizado
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Ejemplo de Salida**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/es/docs/examples/custom-middleware.md b/content/es/docs/examples/custom-middleware.md
deleted file mode 100644
index 45266d215..000000000
--- a/content/es/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Personalizar un Middleware"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Establecer el valor de la variable example
- c.Set("example", "12345")
-
- // antes de la petición
-
- c.Next()
-
- // después de la petición
- latency := time.Since(t)
- log.Print(latency)
-
- // acceso al estatus que se está enviando
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // debe retornar: "12345"
- log.Println(example)
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/es/docs/examples/custom-validators.md b/content/es/docs/examples/custom-validators.md
deleted file mode 100644
index 2b8ef48a2..000000000
--- a/content/es/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Personalizar Validaciones"
-draft: false
----
-
-Es posible registrar validaciones personalizadas como puede verse en el [código de ejemplo](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// el tipo Booking contiene datos vinculados y con validación.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-Las [validaciones a nivel de struct](https://github.com/go-playground/validator/releases/tag/v8.7) pueden registrarse de esta manera también.
-Véase el ejemplo de [validación a nivel de struct](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) para mayor referencia.
diff --git a/content/es/docs/examples/define-format-for-the-log-of-routes.md b/content/es/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 6f7105dbd..000000000
--- a/content/es/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Definir el formato para el log de rutas"
-draft: false
----
-
-El log de rutas por defecto es:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-Si se desea registrar la información en un formato dado (Ejemplo, registrando valores de la petición, JSON, o algo más), se puede definir el formato con `gin.DebugPrintRouteFunc`.
-En el siguiente ejemplo se registran todas las rutas con el paquete estandar de log, sin embargo se puede emplear otro paquete de log que se adapte a lo necesitado.
-
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/goroutines-inside-a-middleware.md b/content/es/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 0f27de56b..000000000
--- a/content/es/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Goroutines dentro de un middleware"
-draft: false
----
-
-Cuando se inicia una goroutine dentro de un middleware o un handler, **NO SE DEBE** utilizar el context dentro de él, debe emplearse una copia de lectura.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // crear una copia para usar dentro de la rutina
- cCp := c.Copy()
- go func() {
- // se simula una tarea prolongada con un time.Sleep(). de 5 seconds
- time.Sleep(5 * time.Second)
-
- // IMPORTANTE: nótese que se trabaja con la copia del contexto "cCp"
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // se simula una tarea prolongada con un time.Sleep(). de 5 seconds
- time.Sleep(5 * time.Second)
-
- // debido a que NO se está usando una goroutine, no necesitamos una copia del context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/graceful-restart-or-stop.md b/content/es/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 763f3e854..000000000
--- a/content/es/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,83 +0,0 @@
----
-title: "Apagado o reinicio controlado del servidor web"
-draft: false
----
-
-Estas son algunas formas de reiniciar o detener el servidor web controladamente.
-
-Se puede utilizar [fvbock/endless](https://github.com/fvbock/endless) para sustituir al `ListenAndServe` por defecto. Véase más detalles en [#296](https://github.com/gin-gonic/gin/issues/296).
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-Alternativas de endless:
-
-* [manners](https://github.com/braintree/manners): Un servidor HTTP para Go con apagado controlado.
-* [graceful](https://github.com/tylerb/graceful): Graceful es un paquete de Go que habilita el apagado controlado de un servidor http.Handler.
-* [grace](https://github.com/facebookgo/grace): Reinicio controlado y despliegue para servidores Go con libre de interrupción del servicio.
-
-Si estás usando Go 1.8, no necesitas hacer uso de esta librería!. Considera el uso del método [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) que viene incluído en `http.Server` para el apagado controlado. Véase el ejemplo de [apagado controlado](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) con Gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // conexiones de servicio
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Espera por la señal de interrupción para el apagado controlado del servidor
- // con un tiempo de espera de 5 segundos.
- quit := make(chan os.Signal, 1)
- // kill (sin parámetro) envío por defecto de la señal syscanll.SIGTERM
- // kill -2 es syscall.SIGINT
- // kill -9 es syscall.SIGKILL pero no se puede atrapar, así que no es necesario agregarlo
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // controlando ctx.Done(). tiempo de espera de 5 segundos.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
diff --git a/content/es/docs/examples/grouping-routes.md b/content/es/docs/examples/grouping-routes.md
deleted file mode 100644
index ad5754e82..000000000
--- a/content/es/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Grouping routes"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Grupo simple con ruta: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Grupo simple con ruta: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/html-rendering.md b/content/es/docs/examples/html-rendering.md
deleted file mode 100644
index c7b50da78..000000000
--- a/content/es/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "Representación de HTML"
-draft: false
----
-
-Using LoadHTMLGlob() or LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Utilizando plantillas de mismo nombre en directorios diferentes
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Representación de Plantilla personalizada
-
-Puede emplearse una representación de plantillas html propia.
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Configuración separadores personalizados
-
-Pueden establecerse separadores personalizados
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Funciones personalizadas en plantillas
-
-Véase con más detalle el [código de ejemplo](https://github.com/gin-gonic/examples/tree/master/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/es/docs/examples/http-method.md b/content/es/docs/examples/http-method.md
deleted file mode 100644
index 3597f4ffb..000000000
--- a/content/es/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Uso de un método específico de HTTP"
-draft: false
----
-
-```go
-func main() {
- // Crea un route de gin con middleware por defecto:
- // logger y recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // Sirve por defecto en el puerto 8080
- // Salvo que una Variable de entorno PORT haya sido definida
- router.Run()
- // router.Run(":3000") para definir por código el puerto 3000
-}
-```
diff --git a/content/es/docs/examples/http2-server-push.md b/content/es/docs/examples/http2-server-push.md
deleted file mode 100644
index 2ffda0094..000000000
--- a/content/es/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server push"
-draft: false
----
-
-http.Pusher sólo es compatible con versiones **go1.8+ en adelante**. Véase el [blog de golang](https://blog.golang.org/h2push) para información detallada.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // Utilice pusher.Push() para hacer server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Escucha y sirve peticiones en https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/es/docs/examples/jsonp.md b/content/es/docs/examples/jsonp.md
deleted file mode 100644
index 2a05c314d..000000000
--- a/content/es/docs/examples/jsonp.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Uso de JSONP para realizar una petición de datos desde un servidor en un dominio diferente
-Using JSONP to request data from a server in a different domain. Agregue un callback al cuerpo de respuesta si existe un callback del parámetro de consulta.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- // el callback es x
- // Retorna : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/map-as-querystring-or-postform.md b/content/es/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index f08b806dc..000000000
--- a/content/es/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Map a partir de una cadena de parámetros GET o parámetros de un formulario POST"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/es/docs/examples/multipart-urlencoded-binding.md b/content/es/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index ea81e68cb..000000000
--- a/content/es/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Vincular formularios Multipart/Urlencoded"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // se puede vincular un formulario multipart con declaración explícita:
- // c.ShouldBindWith(&form, binding.Form)
- // o simplemente se hace auto vinculación por médio del método ShouldBind:
- var form LoginForm
- // en este caso la vinculación adecuada se seleccionará automáticamente
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Puede probarse el código por medio del siguiente curl:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/es/docs/examples/multipart-urlencoded-form.md b/content/es/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 5b4b45866..000000000
--- a/content/es/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Formulario Multipart/Urlencoded"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/es/docs/examples/multiple-template.md b/content/es/docs/examples/multiple-template.md
deleted file mode 100644
index c8dfdc3c6..000000000
--- a/content/es/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Multiplantillas"
-draft: false
----
-
-Gin permite por defecto el úso de sólo una html.Template. Puede revisar [un interpretador multi plantilas](https://github.com/gin-contrib/multitemplate) para emplear características como `block template` de go 1.6.
diff --git a/content/es/docs/examples/only-bind-query-string.md b/content/es/docs/examples/only-bind-query-string.md
deleted file mode 100644
index dd377bf2c..000000000
--- a/content/es/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Vincular únicamente un parámetros GET"
-draft: false
----
-
-La función `ShouldBindQuery` sólo vincula parámetros GET y excluye los datos POST. Véase la [información detallada](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/es/docs/examples/param-in-path.md b/content/es/docs/examples/param-in-path.md
deleted file mode 100644
index 4d99312cb..000000000
--- a/content/es/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Parámetros en rutas"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // El manejo de esta ruta aceptará valores como /user/john pero no manejará rutas como /user/ o /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // Sin embargo, en este caso si podrá manejar rutas como /user/john/ e inclusive /user/john/send
- // Si no hay otra ruta que coincida con /user/john, será redireccionada hacia /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/pure-json.md b/content/es/docs/examples/pure-json.md
deleted file mode 100644
index e879e8503..000000000
--- a/content/es/docs/examples/pure-json.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-Usualmente, JSON sustituye carácteres especiales HTML con sus entidades unicode. Por ejemplo `<` se convierte a `\u003c`. Si se requiere condificar este tipo de caracteres literalmente, se puede utilizar PureJSON.
-Esta característica no está disponible en Go 1.6 o versiones inferiores.
-
-```go
-func main() {
- r := gin.Default()
-
- // Sirve entidades unicode
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Sirve carácteres literales
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Escucha y sirve peticiones en 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
-Utilizando `curl` tenemos:
-```
-curl http://localhost:8080/purejson
-{"html":"Hello, world!"}
-
-curl http://localhost:8080/json
-{"html":"\u003cb\u003eHello, world!\u003c/b\u003e"}%
-```
diff --git a/content/es/docs/examples/query-and-post-form.md b/content/es/docs/examples/query-and-post-form.md
deleted file mode 100644
index 3a6631798..000000000
--- a/content/es/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Formulario POST y parámetros GET en URL"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/es/docs/examples/querystring-param.md b/content/es/docs/examples/querystring-param.md
deleted file mode 100644
index d583a01c0..000000000
--- a/content/es/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "Parámetros GET en URL"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Los parámetros son interpretados usando el objeto de peticiones existente.
- // La petición responde a un url que coincide con: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // método abreviado para c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/redirects.md b/content/es/docs/examples/redirects.md
deleted file mode 100644
index c8ede1c6a..000000000
--- a/content/es/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirección"
-draft: false
----
-
-Emitir una redirección HTTP es sencillo. Son soportadas las rutas internas o externas.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Emitir una redirección HTTP desde POST. Véase en el issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Emitir una redirección hacia un Router, puede emplearse `HandleContext` como en el ejemplo inferior.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/es/docs/examples/rendering.md b/content/es/docs/examples/rendering.md
deleted file mode 100644
index d8f7af21e..000000000
--- a/content/es/docs/examples/rendering.md
+++ /dev/null
@@ -1,53 +0,0 @@
----
-title: "Procesamiento de XML/JSON/YAML/ProtoBuf"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H es un método abreviado para map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // También puedes usar un struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Nótese que msg.Name se convierte en "user" dentro del JSON
- // Arrojará : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // La definición del protobuf se encuentra escrita en el archivo testdata/protoexample.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Nota: en la respuesta los datos se vuelven binarios
- // Arrojará la data serializada de protoexample.Test
- c.ProtoBuf(http.StatusOK, data)
- })
-
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/run-multiple-service.md b/content/es/docs/examples/run-multiple-service.md
deleted file mode 100644
index 16d042f3b..000000000
--- a/content/es/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Ejecutar múltiples servicios a la vez"
-draft: false
----
-
-Véase la [pregunta](https://github.com/gin-gonic/gin/issues/346) e intente el siguiente ejemplo:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/es/docs/examples/secure-json.md b/content/es/docs/examples/secure-json.md
deleted file mode 100644
index cc86e613e..000000000
--- a/content/es/docs/examples/secure-json.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Uso de SecureJSON"
-draft: false
----
-Usando SecureJSON para evitar el secuestro de JSON. Por defecto se antepone `"while(1),"` al cuerpo de respuesta si la estructura dada son valores de array.
-
-```go
-func main() {
- r := gin.Default()
-
- // Se puede emplear un prefijo JSON seguro propio
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Retornará : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/security-headers.md b/content/es/docs/examples/security-headers.md
deleted file mode 100644
index 7f06f31a1..000000000
--- a/content/es/docs/examples/security-headers.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: "Encabezados de seguridad"
-draft: false
----
-Es importante utilizar cabeceras de seguridad para proteger su aplicación web de vulnerabilidades de seguridad comunes. Este ejemplo le muestra cómo añadir cabeceras de seguridad a su aplicación Gin y también cómo evitar ataques relacionados con Host Header Injection (SSRF, Open Redirection).
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-Puede probarlo mediante `curl`:
-
-```bash
-// ヘッダーのチェック
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// ホスト・ヘッダー・インジェクションのチェック
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/es/docs/examples/serving-data-from-reader.md b/content/es/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index 1408f204f..000000000
--- a/content/es/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Retornando data a partir de un reader"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/serving-static-files.md b/content/es/docs/examples/serving-static-files.md
deleted file mode 100644
index b90ecbfbd..000000000
--- a/content/es/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,15 +0,0 @@
----
-title: "Sirviendo archivos estáticos"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/support-lets-encrypt.md b/content/es/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index d6b8daa5a..000000000
--- a/content/es/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Soporte de certificados Let's Encrypt"
-draft: false
----
-
-Ejemplo para servidores HTTPS 1-line LetsEncrypt HTTPS.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Manejador de Ping
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-Ejemplo para manejador de autocert personalizado.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Manejador de Ping
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/es/docs/examples/upload-file/_index.md b/content/es/docs/examples/upload-file/_index.md
deleted file mode 100644
index b5dfaaea3..000000000
--- a/content/es/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Subir archivos"
-draft: false
----
-
-La sección enumera el uso de la API para subir archivos.
diff --git a/content/es/docs/examples/upload-file/multiple-file.md b/content/es/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index bab10fdd2..000000000
--- a/content/es/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Múltiples archivos"
-draft: false
----
-
-Vea el código de [ejemplo detallado](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Establecer un límite de memoria inferior para formularios de multipart (el valor predeterminado es 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Formulario multipart
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Guarda el archivo recibido a un destino específico
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-Ejemplo para ejecutar `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/es/docs/examples/upload-file/single-file.md b/content/es/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 9149ff391..000000000
--- a/content/es/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Subir un archivo individual"
-draft: false
----
-
-Issue de referencia [#774](https://github.com/gin-gonic/gin/issues/774) y código [detallado de ejemplo](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-`file.Filename` **NO DEBE** confiar en su totalidad en la extensión del archivo. Véase en [`Content-Disposition` de MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) y [#1693](https://github.com/gin-gonic/gin/issues/1693)
-
-> El nombre de archivo siempre es opcional y la aplicación no debe usarlo a ciegas: la información de su ubicación debe eliminarse y debe hacerse la conversión a las reglas del sistema de archivos del servidor.
-
-```go
-func main() {
- router := gin.Default()
- // Establecer un límite de memoria inferior para formularios de multipart (el valor predeterminado es 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Archivo individual
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Guarda el archivo recibido a un destino específico
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-Ejemplo para ejecutar `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/es/docs/examples/using-basicauth-middleware.md b/content/es/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index c0e79ff90..000000000
--- a/content/es/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,40 +0,0 @@
----
-title: "Uso del middleware BasicAuth"
-draft: false
----
-
-```go
-// Se simula una información privada
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Agrupación de rutas usando el middleware gin.BasicAuth()
- // gin.Accounts es una abreviatura para map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // el endpoint /admin/secrets
- // será para el url "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // para obtener user, es configurado por el middleware BasicAuth
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- r.Run(":8080")
-}
-```
diff --git a/content/es/docs/examples/using-middleware.md b/content/es/docs/examples/using-middleware.md
deleted file mode 100644
index 310fc2caa..000000000
--- a/content/es/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,42 +0,0 @@
----
-title: "Usando middleware"
-draft: false
----
-
-```go
-func main() {
- // Se crea el router por defecto sin ningún middleware
- r := gin.New()
-
- // Middleware global
- // El middlware Logger escribirá los logs hacia gin.DefaultWriter incluso si se configura GIN_MODE=release.
- // Por defecto será gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // El middleware Recovery recupera al servicio de cualquier panics y registra un error 500 si existiese uno.
- r.Use(gin.Recovery())
-
- // Middleware por ruta, se pueden añadir tantos como sea necesario.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Grupo de Authorization
- // authorized := r.Group("/", AuthRequired())
- // exactamente el mismo que:
- authorized := r.Group("/")
- // Middleware por grupo. En este caso usamos el grupo creado
- // y se aplicará AuthRequired() middleware únicamente en el grupo "authorized".
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // Grupo anidado
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- r.Run(":8080")
-}
-```
-
diff --git a/content/es/docs/examples/without-middleware.md b/content/es/docs/examples/without-middleware.md
deleted file mode 100644
index 2de79ef3c..000000000
--- a/content/es/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,18 +0,0 @@
----
-title: "Usar Gin sin los middleware por defecto"
-draft: false
----
-
-Utilice
-
-```go
-r := gin.New()
-```
-
-En vez de
-
-```go
-// De esta forma
-// Los middleware Logger y Recovery ya vienen activos
-r := gin.Default()
-```
diff --git a/content/es/docs/examples/write-log.md b/content/es/docs/examples/write-log.md
deleted file mode 100644
index 6cd2d4c0e..000000000
--- a/content/es/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Como registrar un Log en un archivo"
-draft: false
----
-
-```go
-func main() {
- // Deshabilita el color en la cónsola. Es innecesario si se desea registrar los logs en un archivo.
- gin.DisableConsoleColor()
-
- // Declarando el archivo del Log.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Utilice el siguiente código si necesita registrar el log en un archivo y en la cónsola al mismo tiempo.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/es/docs/faq/_index.md b/content/es/docs/faq/_index.md
deleted file mode 100644
index 05ccaee0f..000000000
--- a/content/es/docs/faq/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: Se registrarán las preguntas frecuentes de la sección para [issues de GitHub](https://github.com/gin-gonic/gin/issues).
diff --git a/content/es/docs/features/_index.md b/content/es/docs/features/_index.md
deleted file mode 100644
index c9a789e8c..000000000
--- a/content/es/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Características"
-draft: false
-weight: 4
----
-
-## Gin versión 1 estable ofrece:
-
-- Router de cero alocación en memoria.
-
-- Sigue siendo el más rápido http router y framework. Desde el enrutamiento hasta la escritura.
-
-- Conjunto completo de pruebas unitarias.
-
-- Probado en batalla.
-
-- API congelada, las nuevas versiones no romperán su código.
diff --git a/content/es/docs/introduction/_index.md b/content/es/docs/introduction/_index.md
deleted file mode 100644
index 190e9b79b..000000000
--- a/content/es/docs/introduction/_index.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "Introducción"
-draft: false
-weight: 1
----
-
-Gin es un framework para desarrollo web escrito en Go (Golang). Cuenta con una API tipo martini, con un rendimiento mucho mayor, hasta 40 veces más rápido gracias a [httprouter](https://github.com/julienschmidt/httprouter). Si necesitas rendimiento y productividad amarás a Gin.
-
-En esta sección veremos qué es Gin, qué problemas resuelve y cómo puede ayudar a tu proyecto.
-
-O, si está listo para usar Gin en su proyecto, visita el [Inicio Rápido](https://gin-gonic.com/es/docs/quickstart/).
-
-## Características
-
-### Veloz
-
-Enrutamiento basado en Radix tree, poco consumo de memoria. Sin reflection. Rendimiento predecible del API.
-
-### Soporte de middleware
-
-Una petición entrante HTTP puede ser manejada por diversos middleware encadenados y la acción final.
-Ejemplo: Logger, Authorization, GZIP y por úlitmo guardar el mensaje en la BD.
-
-### Libre de crashes
-
-Gin puede recibir y recuperarse de un panic ocurrido durante una petición HTTP. Así tu servidor estará siempre disponible. También es posible hacer un reporte del panic, por ejemplo ¡a Sentry!
-
-### Validación de JSON
-
-Gin permite analizar y validar datos JSON en una petición, y por ejemplo, revisar la existencia de datos requeridos.
-
-### Agrupación de rutas
-
-Organiza mejor tus rutas: Rutas con autorización vs rutas públicas, versiones diferentes de API. Adicionalmente los grupos de rutas pueden anidarse ilimitadamente sin afectar el rendimiento.
-
-### Manejo de errores
-
-Gin ofrece una conveniente forma de recopilar los errores ocurridos durante una petición HTTP. Un middleware puede incluso registrarlos en un archivo de logs, la BD o enviarlos por la red.
-
-### Render incluído
-
-Gin cuenta con una API fácil de usar para el render de JSON, XML y HTML.
-
-### Extensible
-
-Crear un middleware nuevo es muy sencillo. Sólo debes revisar los códigos de ejemplo.
diff --git a/content/es/docs/jsoniter/_index.md b/content/es/docs/jsoniter/_index.md
deleted file mode 100644
index 788faf6d3..000000000
--- a/content/es/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## Go Build con [jsoniter](https://github.com/json-iterator/go)
-
-Gin utiliza `encoding/json` como paquete por defecto para json, pero se puede cambiar por [jsoniter](https://github.com/json-iterator/go) especificándolo en el tag al hacer go build.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/es/docs/quickstart/_index.md b/content/es/docs/quickstart/_index.md
deleted file mode 100644
index 743004adf..000000000
--- a/content/es/docs/quickstart/_index.md
+++ /dev/null
@@ -1,87 +0,0 @@
----
-title: "Inicio Rápido"
-draft: false
-weight: 2
----
-
-En este inicio rápido, captaremos información y aprenderemos por medio de porciones de código:
-
-## Requerimientos
-
-- Go 1.16 o superior
-
-## Instalación
-
-Para instalar Gin, primero debe instalar Go y configurar el espacio de trabajo Go.
-
-1. Descargar e instalar:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. Importar en el código:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. Importar el paquete `net/http` (Opcional). Es requerido para el uso de constantes como por ejemplo `http.StatusOK`.
-
-```go
-import "net/http"
-```
-
-1. Crear la carpeta del proyecto e ingresar en ella con `cd`
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. Copiar una plantilla de inicio dentro del proyecto
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. Ejecutar el proyecto
-
-```sh
-$ go run main.go
-```
-
-## Primeros Pasos
-
-> ¿No sabes cómo escribir y ejecutar código Go? [Click aquí](https://golang.org/doc/code.html).
-
-Primero, crear un archivo llamado `example.go`:
-
-```sh
-# asumimos que el código siguiente se encontrará en el archivo example.go
-$ touch example.go
-```
-
-A continuación, coloque el siguiente código dentro en `example.go`:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // Sirve y escucha peticiones en 0.0.0.0:8080
-}
-```
-
-Y ahora, puede ejecutar el código a través de `go run example.go`:
-
-```sh
-# ejecuta example.go y visita 0.0.0.0:8080/ping en el navegador
-$ go run example.go
-```
diff --git a/content/es/docs/testing/_index.md b/content/es/docs/testing/_index.md
deleted file mode 100644
index 31ff24fe6..000000000
--- a/content/es/docs/testing/_index.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: "Testing en Gin"
-draft: false
-weight: 7
----
-
-## ¿Cómo escribir casos de prueba en Gin?
-
-El paquete `net/http/httptest` es la forma preferible para las pruebas de HTTP
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-Test para el código anterior de ejemplo:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
-
-
-
diff --git a/content/es/docs/users/_index.md b/content/es/docs/users/_index.md
deleted file mode 100644
index d909d69f9..000000000
--- a/content/es/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Usuarios"
-draft: false
-weight: 8
----
-
-##### Lista de proyectos fantásticos que usan [Gin](https://github.com/gin-gonic/gin) web framework:
-
-* [gorush](https://github.com/appleboy/gorush): Servidor de notificaciones push escrito en Go.
-
-* [fnproject](https://github.com/fnproject/fn): Plataforma serverless basada en contenedores nativamente, y agnóstica de cloud.
-
-* [photoprism](https://github.com/photoprism/photoprism): Administrador de fotos personales basado en Go y TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Gateway API de ultra rendimiento con middlewares.
-
-* [picfit](https://github.com/thoas/picfit): Servidor de cambio de tamaño de imagen escrito en Go.
-
-* [gotify](https://github.com/gotify/server): Un servidor simple para enviar y recibir mensajes en tiempo real a través de web sockets.
-
-* [cds](https://github.com/ovh/cds): Plataforma open source de Continuous Delivery y automatización DevOps de nivel empresarial.
diff --git a/content/es/featured-background.jpg b/content/es/featured-background.jpg
deleted file mode 100644
index 8bb8a4cc6..000000000
Binary files a/content/es/featured-background.jpg and /dev/null differ
diff --git a/content/es/search.md b/content/es/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/es/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/content/fa/_index.html b/content/fa/_index.html
deleted file mode 100644
index e856f95c3..000000000
--- a/content/fa/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**Gin چیست?**
-
-جین یک فریم ورک وبه که با زبان گو ساخته شده.
-
- .جین یک فریم ورک شبیه به مارتینه(یکی دیگه از وب فریم ورک های گو) ولی با پرفورمنس بهتر . چیزی حدود 40 برار سریع تر
-
- اگه شما نیازمند پرفورمنس و کارایی بالا(بهره بری بالا) هستید عاشق جین میشید.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Fast" %}}
-Radix tree based routing(مسیریابی مبتنی بر درخت ردیکس), small memory foot print. No reflection(بدون تامل). Predictable API performance.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Middleware support" %}}
-An incoming HTTP request can be handled by a chain of middleware and the final action.
-For example: Logger, Authorization, GZIP and finally post a message in the DB.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash-free" %}}
-Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON validation" %}}
-Gin can parse and validate the JSON of a request, checking, for example, the existence of required values.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Routes grouping" %}}
-Organize your routes better. Authorization required vs non required, different API versions. In addition, groups can be nested infinitely without degrading performance.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Error management" %}}
-Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, middleware can write them to a log file, to a database and send them through the network.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Rendering built-in" %}}
-Gin provides an easy to use API for JSON, XML and HTML rendering.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Extendable" %}}
-Creating new middleware is so easy, just check out the sample code.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/fa/blog/_index.md b/content/fa/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/fa/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/fa/blog/news/_index.md b/content/fa/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/fa/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/fa/blog/releases/_index.md b/content/fa/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/fa/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/fa/docs/_index.md b/content/fa/docs/_index.md
deleted file mode 100644
index 09ab9d8ce..000000000
--- a/content/fa/docs/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "اسناد"
-linkTitle: "اسناد/"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin چیست ؟
-
-جین یکی از وب فریم ورکهای زبان گو است که امکاناتی مانند فریم ورک martini داره ولی با کارایی بهتر یعنی چیزی حدود 40 برابر سریع تر از martini اگر به عملکرد فوق العاده ای نیاز دارید ، خودتان امتحان کنید.
-
-## چگونه از Gin استفاده کنیم ؟
-
-ما نمونه های استفاده از API را ارائه می دهیم که میتونید مثال ها رو [اینجا](https://github.com/gin-gonic/examples) ببنید و برخی از کاربران Gin را که به طور عمومی شناخته شده اند لیست می کنیم. که میتونید [اینجا](./users) ببینید.
-
-## چگونه میتوان به Gin کمک کرد ؟
-
-- در انجمن های گفتگو به افراد کمک کنید
-- داستانهای موفقیت خود را با استفاده از جین برای ما بگویید
-- به ما بگویید که چگونه می توانیم جین را بهبود بخشیم و به ما در انجام آن کمک کنیم
-- به یک کتابخانه موجود کمک کنید
diff --git a/content/fa/docs/benchmarks/_index.md b/content/fa/docs/benchmarks/_index.md
deleted file mode 100644
index 4154952d9..000000000
--- a/content/fa/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "بنچ مارک ها"
-draft: false
-weight: 3
----
-
-جین از یک نسخه سفارشی از [HttpRouter](https://github.com/julienschmidt/httprouter) استفاده میکند.
-
-[نتایج همه بنچ مارک ها رو اینجا ببینید](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | --------: | --------------: | -----------: | --------------: |
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-راهنمای جدول بالا
-
-- (1): Total Repetitions achieved in constant time -> بالاتر یعنی نتیجه با اطمینان بیشتری است
-- (2): Single Repetition Duration (ns/op) -> هرچه پایین تر بهتر است
-- (3): Heap Memory (B/op) -> هرچه پایین تر بهتر است
-- (4): Average Allocations per Repetition (allocs/op) -> هرچه پایین تر بهتر است
diff --git a/content/fa/docs/deployment/_index.md b/content/fa/docs/deployment/_index.md
deleted file mode 100644
index a6df76d0e..000000000
--- a/content/fa/docs/deployment/_index.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "دیپلوی"
-draft: false
-weight: 6
----
-
-جین به راحتی میتواند روی هر فضای ابری دیپلوی شود.
-
-## [Qovery](https://www.qovery.com)
-
-Qovery یک هاست رایگان همراه با دیتابیس ssl , CDN را ارائه میدهد و همچنین به صورت خودکار با گیت دیپلوی میشود.
-
-[پروژه جین خودتو با استفاده از Qovery دیپلوی کن](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
-
-## [Render](https://render.com)
-
-Render یک پلت فرم ابری مدرن است که پشتیبانی نیتیو از Go ، SSL کاملاً مدیریت شده ، دیتابیس ،zero-downtime deploys ، HTTP / 2 و پشتیبانی از websocket را ارائه می دهد.
-
-[پروژه جین خودتو با Render دیپلوی کن](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE دو روش برای دیپلوی برنامه های Go دارد. استفاده از محیط استاندارد آسان تر است اما کمتر قابل تنظیم است و به دلایل امنیتی از [syscalls](https://github.com/gin-gonic/gin/issues/1639) جلوگیری می کند. محیط انعطاف پذیر آن می تواند هر چارچوب یا کتابخانه ای را اجرا کند.
-
-[محیط خودتو با Google App Engine بساز](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/fa/docs/examples/_index.md b/content/fa/docs/examples/_index.md
deleted file mode 100644
index 50f228be0..000000000
--- a/content/fa/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "مثال ها"
-draft: false
-weight: 6
----
-
-لیست مثال ها.
diff --git a/content/fa/docs/examples/ascii-json.md b/content/fa/docs/examples/ascii-json.md
deleted file mode 100644
index 82ab48d2a..000000000
--- a/content/fa/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/bind-body-into-dirrerent-structs.md b/content/fa/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index c685ccaba..000000000
--- a/content/fa/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Try to bind body into different structs"
-draft: false
----
-
-The normal methods for binding request body consumes `c.Request.Body` and they
-cannot be called multiple times.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Always an error is occurred by this because c.Request.Body is EOF now.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-For this, you can use `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // At this time, it reuses body stored in the context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` stores body into the context before binding. This has
-a slight impact to performance, so you should not use this method if you are
-enough to call binding at once.
-* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
-can be called by `c.ShouldBind()` multiple times without any damage to
-performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/fa/docs/examples/bind-form-data-request-with-custom-struct.md b/content/fa/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 2882e8656..000000000
--- a/content/fa/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "Bind form-data request with custom struct"
-draft: false
----
-
-The follow example using custom struct:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Using the command `curl` command result:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/fa/docs/examples/bind-html-checkbox.md b/content/fa/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index ae63e1f60..000000000
--- a/content/fa/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Bind html checkboxes"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-result:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/fa/docs/examples/bind-query-or-post.md b/content/fa/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 7ebbe739c..000000000
--- a/content/fa/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "Bind query string or post data"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // If `GET`, only `Form` binding engine (`query`) used.
- // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
- // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Test it with:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/fa/docs/examples/bind-single-binary-with-template.md b/content/fa/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 36f0bb212..000000000
--- a/content/fa/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Build a single binary with templates"
-draft: false
----
-## Use the third-party package
-
-You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate loads templates embedded by go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/content/fa/docs/examples/bind-uri.md b/content/fa/docs/examples/bind-uri.md
deleted file mode 100644
index 743074b69..000000000
--- a/content/fa/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Bind Uri"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Test it with:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/fa/docs/examples/binding-and-validation.md b/content/fa/docs/examples/binding-and-validation.md
deleted file mode 100644
index 41a564a3e..000000000
--- a/content/fa/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Model binding and validation"
-draft: false
----
-
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
-
-Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
-
-Also, Gin provides two sets of methods for binding:
-- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
-- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
-
-When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
-
-You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
-
-```go
-// Binding from JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Example for binding JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding a HTML form (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Sample request
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Skip validate
-
-When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/content/fa/docs/examples/controlling-log-output-coloring.md b/content/fa/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 81f27efe9..000000000
--- a/content/fa/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Controlling Log output coloring"
-draft: false
----
-
-By default, logs output on console should be colorized depending on the detected TTY.
-
-Never colorize logs:
-
-```go
-func main() {
- // Disable log's color
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Always colorize logs:
-
-```go
-func main() {
- // Force log's color
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/cookie.md b/content/fa/docs/examples/cookie.md
deleted file mode 100644
index 231473ca5..000000000
--- a/content/fa/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Set and get a cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/fa/docs/examples/custom-http-config.md b/content/fa/docs/examples/custom-http-config.md
deleted file mode 100644
index f4c0d9d95..000000000
--- a/content/fa/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: "Custom HTTP configuration"
-draft: false
----
-
-Use `http.ListenAndServe()` directly, like this:
-
-```go
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-or
-
-```go
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/fa/docs/examples/custom-log-format.md b/content/fa/docs/examples/custom-log-format.md
deleted file mode 100644
index f9ea8b6a7..000000000
--- a/content/fa/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Custom log file"
-draft: false
----
-
-For example:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
- // By default gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // your custom format
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Sample Output**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/fa/docs/examples/custom-middleware.md b/content/fa/docs/examples/custom-middleware.md
deleted file mode 100644
index dd7407b07..000000000
--- a/content/fa/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Custom Middleware"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Set example variable
- c.Set("example", "12345")
-
- // before request
-
- c.Next()
-
- // after request
- latency := time.Since(t)
- log.Print(latency)
-
- // access the status we are sending
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // it would print: "12345"
- log.Println(example)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/fa/docs/examples/custom-validators.md b/content/fa/docs/examples/custom-validators.md
deleted file mode 100644
index f777436cc..000000000
--- a/content/fa/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Custom validators"
-draft: false
----
-
-It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking contains binded and validated data.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
-See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/content/fa/docs/examples/define-format-for-the-log-of-routes.md b/content/fa/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 6cfdaa68f..000000000
--- a/content/fa/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Define format for the log of routes"
-draft: false
----
-
-The default log of routes is:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
-In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Listen and Server in http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/fa/docs/examples/goroutines-inside-a-middleware.md b/content/fa/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 122593a1b..000000000
--- a/content/fa/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Goroutines inside a middleware"
-draft: false
----
-
-When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // create copy to be used inside the goroutine
- cCp := c.Copy()
- go func() {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // note that you are using the copied context "cCp", IMPORTANT
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // since we are NOT using a goroutine, we do not have to copy the context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/graceful-restart-or-stop.md b/content/fa/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 87ca178c2..000000000
--- a/content/fa/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-title: "Graceful restart or stop"
-draft: false
----
-
-Do you want to graceful restart or stop your web server?
-There are some ways this can be done.
-
-We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-An alternative to endless:
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // service connections
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Wait for interrupt signal to gracefully shutdown the server with
- // a timeout of 5 seconds.
- quit := make(chan os.Signal, 1)
- // kill (no param) default send syscanll.SIGTERM
- // kill -2 is syscall.SIGINT
- // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // catching ctx.Done(). timeout of 5 seconds.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/fa/docs/examples/grouping-routes.md b/content/fa/docs/examples/grouping-routes.md
deleted file mode 100644
index a480aa325..000000000
--- a/content/fa/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Grouping routes"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Simple group: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Simple group: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/html-rendering.md b/content/fa/docs/examples/html-rendering.md
deleted file mode 100644
index cfa8e825a..000000000
--- a/content/fa/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML rendering"
-draft: false
----
-
-Using LoadHTMLGlob() or LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Using templates with same name in different directories
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Custom Template renderer
-
-You can also use your own html template render
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Custom Delimiters
-
-You may use custom delims
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Custom Template Funcs
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/fa/docs/examples/http-method.md b/content/fa/docs/examples/http-method.md
deleted file mode 100644
index 6678e155f..000000000
--- a/content/fa/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Using HTTP method"
-draft: false
----
-
-```go
-func main() {
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // By default it serves on :8080 unless a
- // PORT environment variable was defined.
- router.Run()
- // router.Run(":3000") for a hard coded port
-}
-```
diff --git a/content/fa/docs/examples/http2-server-push.md b/content/fa/docs/examples/http2-server-push.md
deleted file mode 100644
index 00bbd12d8..000000000
--- a/content/fa/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server push"
-draft: false
----
-
-http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // use pusher.Push() to do server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Listen and Server in https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/fa/docs/examples/jsonp.md b/content/fa/docs/examples/jsonp.md
deleted file mode 100644
index 63c7dc551..000000000
--- a/content/fa/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/map-as-querystring-or-postform.md b/content/fa/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index fa733e2ef..000000000
--- a/content/fa/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Map as querystring or postform parameters"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/fa/docs/examples/multipart-urlencoded-binding.md b/content/fa/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 767fc6576..000000000
--- a/content/fa/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded binding"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // you can bind multipart form with explicit binding declaration:
- // c.ShouldBindWith(&form, binding.Form)
- // or you can simply use autobinding with ShouldBind method:
- var form LoginForm
- // in this case proper binding will be automatically selected
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Test it with:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/fa/docs/examples/multipart-urlencoded-form.md b/content/fa/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 774662b1e..000000000
--- a/content/fa/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded form"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/fa/docs/examples/multiple-template.md b/content/fa/docs/examples/multiple-template.md
deleted file mode 100644
index 0bcf46858..000000000
--- a/content/fa/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Multitemplate"
-draft: false
----
-
-Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/content/fa/docs/examples/only-bind-query-string.md b/content/fa/docs/examples/only-bind-query-string.md
deleted file mode 100644
index d6d4e33cc..000000000
--- a/content/fa/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Only bind query string"
-draft: false
----
-
-`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/fa/docs/examples/param-in-path.md b/content/fa/docs/examples/param-in-path.md
deleted file mode 100644
index 6e29a59c7..000000000
--- a/content/fa/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Parameters in path"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // This handler will match /user/john but will not match /user/ or /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // However, this one will match /user/john/ and also /user/john/send
- // If no other routers match /user/john, it will redirect to /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/pure-json.md b/content/fa/docs/examples/pure-json.md
deleted file mode 100644
index d91f905ef..000000000
--- a/content/fa/docs/examples/pure-json.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
-This feature is unavailable in Go 1.6 and lower.
-
-```go
-func main() {
- r := gin.Default()
-
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/query-and-post-form.md b/content/fa/docs/examples/query-and-post-form.md
deleted file mode 100644
index 0d7b18e51..000000000
--- a/content/fa/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Query and post form"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/fa/docs/examples/querystring-param.md b/content/fa/docs/examples/querystring-param.md
deleted file mode 100644
index bcf8b55f2..000000000
--- a/content/fa/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "Query string parameters"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Query string parameters are parsed using the existing underlying request object.
- // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/redirects.md b/content/fa/docs/examples/redirects.md
deleted file mode 100644
index f7d823eca..000000000
--- a/content/fa/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirects"
-draft: false
----
-
-Issuing a HTTP redirect is easy. Both internal and external locations are supported.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Issuing a Router redirect, use `HandleContext` like below.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/fa/docs/examples/rendering.md b/content/fa/docs/examples/rendering.md
deleted file mode 100644
index a9fa75b5f..000000000
--- a/content/fa/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf rendering"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H is a shortcut for map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response
- // Will output protoexample.Test protobuf serialized data
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/run-multiple-service.md b/content/fa/docs/examples/run-multiple-service.md
deleted file mode 100644
index ebe6223a0..000000000
--- a/content/fa/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Run multiple service"
-draft: false
----
-
-See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/fa/docs/examples/secure-json.md b/content/fa/docs/examples/secure-json.md
deleted file mode 100644
index 9f5642167..000000000
--- a/content/fa/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
-
-```go
-func main() {
- r := gin.Default()
-
- // You can also use your own secure json prefix
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/security-headers.md b/content/fa/docs/examples/security-headers.md
deleted file mode 100644
index 80e11fa88..000000000
--- a/content/fa/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "Security Headers"
-draft: false
----
-
-It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection).
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-You can test it via `curl`:
-
-```bash
-// Check Headers
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// Check Host Header Injection
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/fa/docs/examples/serving-data-from-reader.md b/content/fa/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index f5546a8c6..000000000
--- a/content/fa/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Serving data from reader"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/serving-static-files.md b/content/fa/docs/examples/serving-static-files.md
deleted file mode 100644
index e296ead02..000000000
--- a/content/fa/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "Serving static files"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/support-lets-encrypt.md b/content/fa/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index c66288e87..000000000
--- a/content/fa/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Support Let's Encrypt"
-draft: false
----
-
-example for 1-line LetsEncrypt HTTPS servers.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-example for custom autocert manager.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/fa/docs/examples/upload-file/_index.md b/content/fa/docs/examples/upload-file/_index.md
deleted file mode 100644
index 1810e3253..000000000
--- a/content/fa/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Upload files"
-draft: false
----
-
-The section lists upload file api usage.
diff --git a/content/fa/docs/examples/upload-file/multiple-file.md b/content/fa/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 912472dd3..000000000
--- a/content/fa/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Multiple files"
-draft: false
----
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/fa/docs/examples/upload-file/single-file.md b/content/fa/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 22ac899f8..000000000
--- a/content/fa/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Single file"
-draft: false
----
-
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
-
-> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/fa/docs/examples/using-basicauth-middleware.md b/content/fa/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 318aca232..000000000
--- a/content/fa/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Using BasicAuth middleware"
-draft: false
----
-
-```go
-// simulate some private data
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Group using gin.BasicAuth() middleware
- // gin.Accounts is a shortcut for map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets endpoint
- // hit "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // get user, it was set by the BasicAuth middleware
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/fa/docs/examples/using-middleware.md b/content/fa/docs/examples/using-middleware.md
deleted file mode 100644
index 2a3159cc3..000000000
--- a/content/fa/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Using middleware"
-draft: false
----
-
-```go
-func main() {
- // Creates a router without any middleware by default
- r := gin.New()
-
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- r.Use(gin.Recovery())
-
- // Per route middleware, you can add as many as you desire.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Authorization group
- // authorized := r.Group("/", AuthRequired())
- // exactly the same as:
- authorized := r.Group("/")
- // per group middleware! in this case we use the custom created
- // AuthRequired() middleware just in the "authorized" group.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // nested group
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/fa/docs/examples/without-middleware.md b/content/fa/docs/examples/without-middleware.md
deleted file mode 100644
index ce7b81fbb..000000000
--- a/content/fa/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Without middleware by default"
-draft: false
----
-
-Use
-
-```go
-r := gin.New()
-```
-
-instead of
-
-```go
-// Default With the Logger and Recovery middleware already attached
-r := gin.Default()
-```
diff --git a/content/fa/docs/examples/write-log.md b/content/fa/docs/examples/write-log.md
deleted file mode 100644
index 261b8d26a..000000000
--- a/content/fa/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "How to write log file"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color, you don't need console color when writing the logs to file.
- gin.DisableConsoleColor()
-
- // Logging to a file.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Use the following code if you need to write the logs to file and console at the same time.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/fa/docs/faq/_index.md b/content/fa/docs/faq/_index.md
deleted file mode 100644
index 389d1432a..000000000
--- a/content/fa/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: record some frequently asked question from GitHub Issue tab.
-
diff --git a/content/fa/docs/features/_index.md b/content/fa/docs/features/_index.md
deleted file mode 100644
index 45facf683..000000000
--- a/content/fa/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "امکانات"
-draft: false
-weight: 4
----
-
-## امکانات نسخه پایدار 1 جین :
-
-- Zero allocation router.
-
-- هنوز سریعترین روتر و فریم ورک http. از مسیریابی گرفته تا نوشتن.
-
-- مجموعه کامل یونیت تست ها
-
-- نبرد تست شده.
-
-- API forzen ، در نسخه های جدید کد شما بریک نمیشود.
diff --git a/content/fa/docs/introduction/_index.md b/content/fa/docs/introduction/_index.md
deleted file mode 100755
index a5a328b11..000000000
--- a/content/fa/docs/introduction/_index.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "مقدمه"
-draft: false
-weight: 1
----
-
-Gin یک فریم ورک وب ساخته شده با Go است که امکاناتی مانند martini دارد (یکی دیگر از فریم ورک های وب گو) ولی با کارایی بالاتر چیزی حدود 40 برابر سریع تر با تشکر از [httprouter](https://github.com/iamAmirrezaSaki/website.git).اگه به عملکرد فوق العاده ایی نیاز دارید عاشق Gin می شوید.
-
-در این بخش ما به بررسی جین میپردازیم که چه مشکلاتی را حل می کند و چگونه می تواند به پروژه شما کمک کند.
-
-یا اگر آماده استفاده از Gin برای پروژه خود هستید ، به [شروع سریع] (https://gin-gonic.com/docs/quickstart/) سر بزنید.
-
-## امکانات
-
-### سرعت بالا(سریع)
-
-مسیریابی مبتنی بر درخت ردیکس(Radix tree based routing) ، چاپ ردپا روی حافظه کم(small memory foot print). بدون تأمل. عملکرد قابل پیش بینی API.
-
-### پشتیبانی از میان افزارها(middleware)
-
-یک درخواست HTTP ورودی میتواند از میان زنجیره ایی از میان افزار ها بگردد و سپس به یک اقدام نهایی منجر شود.
-برای مثال: زنجیره ی میان افزار ها -> Logger, Authorization, GZIOP و در نهایت یک اقدام یا پروسه نهایی که منجرب به ذخیره ی یک پیام در دیتابیس میشود.
-
-### (بدون خرابی)Crash-free
-
-Gin می تواند در هنگام درخواست HTTP دچار پنیک(کرش) شود و آن را بازیابی کند. به این ترتیب سرور شما همیشه در دسترس خواهد بود و پایدار میماند. همچنین می توانید این پنیک(کرش) را به Sentry گزارش دهید!
-
-### JSON validation(اعتبار سنجی فرمت JSON)
-
-جین می تواند JSON ورودی را تجزیه و اعتبار سنجی کند - به عنوان مثال ، بررسی مقادیر مورد نیاز.(فیلد های اجباری مورد نیاز)
-
-### Routes grouping(گروه بندی کردن مسیر ها یا API ها)
-
-مسیرهای خود را بهتر سازماندهی کنید. گروه ها می توانند بدون محدودیت عملکرد به صورت نامحدود تو در تو قرار بگیرند.
-
-### Error management(مدیریت خطا)
-
-جین یک روش مناسب برای جمع آوری تمام خطاهایی که در هنگام درخواست HTTP رخ داده است فراهم می کند. در نهایت ، یک میان افزار می تواند آنها را در یک فایل log یا یک پایگاه داده بنویسد و از طریق شبکه ارسال کند.
-
-### Rendering built-in(رندر داخلی)
-
-Gin استفاده آسان از API را برای استفاده از JSON ، XML و HTML فراهم می کند.
-
-### Extendable(توسعه پذیر)
-
-ساخت یک میان افزار جدید بسیار ساده است. تنها کافی است به نمونه کدها یه نگاه بندازید.
diff --git a/content/fa/docs/jsoniter/_index.md b/content/fa/docs/jsoniter/_index.md
deleted file mode 100644
index 349040067..000000000
--- a/content/fa/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## [jsoniter](https://github.com/json-iterator/go)
-
-جین به صورت پیشفرض از پکیج 'encoding/json' استفاده میکند ولی شما میتوانید ان را به jsoniter تغییر دهید با استفاده از تگ jsoniter در هنگام بیلد.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/fa/docs/quickstart/_index.md b/content/fa/docs/quickstart/_index.md
deleted file mode 100644
index f3f411fe0..000000000
--- a/content/fa/docs/quickstart/_index.md
+++ /dev/null
@@ -1,87 +0,0 @@
----
-title: "شروع سریع"
-draft: false
-weight: 2
----
-
-در اینجا ما اطلاعاتی را در کدها دریافت میکنیم و همچنین یاد میگیریم که :
-
-## الزامات
-
-- Go 1.16 یا بالا تر
-
-## نصب و راه اندازی
-
-برای نصب پکیج Gin ابتدا باید گو را نصب کنید و محیط خودتون رو تنظیم کنید.
-
-1. دانلود و نصب:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. جین را به پروژتون اضافه کنید
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. وارد کنید "net/http" برای متغیر های ثابت مثل http.StatusOK (اختیاری).
-
-```go
-import "net/http"
-```
-
-1. یک پوشه بسازید و وارد اون پوشه بشید
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. یک الگوی اولیه برای شروع را در داخل پروژه خود کپی کنید
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. پروژتون رو اجرا کنید
-
-```sh
-$ go run main.go
-```
-
-## شروع
-
-> نمیدونید چطور یک کد گو رو اجرا کنید ؟ [اینجا کلیک کنید](https://golang.org/doc/code.html).
-
-ابتدا یک فایل به اسم `example.go` بسازید :
-
-```sh
-# assume the following codes in example.go file
-$ touch example.go
-```
-
-سپس کد های زیر رو توی فایل `example.go` بنویسید :
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-حالا میتوانید کد رو با دستور زیر اجرا کنید :
-
-```sh
-# run example.go and visit 0.0.0.0:8080/ping on browser
-$ go run example.go
-```
diff --git a/content/fa/docs/testing/_index.md b/content/fa/docs/testing/_index.md
deleted file mode 100644
index 766982b44..000000000
--- a/content/fa/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "تست"
-draft: false
-weight: 7
----
-
-## چگونه در gin تست بنویسیم ؟
-
-پکیج `net/http/httptest` روشی برتر برای آزمایش HTTP است.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-تست برای کد بالا :
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/fa/docs/users/_index.md b/content/fa/docs/users/_index.md
deleted file mode 100644
index 6056d5c94..000000000
--- a/content/fa/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "کاربران"
-draft: false
-weight: 8
----
-
-##### لیستی عالی از پروژه های ساخته شده با [Gin](https://github.com/gin-gonic/gin):
-
-- [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.(سرور پوش نوتیفیکیشن)
-
-- [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
-
-- [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
-
-- [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
-
-- [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
-
-- [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
-
-- [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/content/fa/featured-background.jpg b/content/fa/featured-background.jpg
deleted file mode 100644
index 8bb8a4cc6..000000000
Binary files a/content/fa/featured-background.jpg and /dev/null differ
diff --git a/content/fa/search.md b/content/fa/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/fa/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/content/ja/_index.html b/content/ja/_index.html
deleted file mode 100644
index 776fa4548..000000000
--- a/content/ja/_index.html
+++ /dev/null
@@ -1,76 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**Ginとは何か?**
-
-Gin は、Golang で書かれた Web フレームワークです。
-
-martini に似た API を持ちながら、非常に優れたパフォーマンスを発揮し、最大で40倍高速であることが特徴です。
-
-性能と優れた生産性が必要なら、きっと Gin が好きになれるでしょう。
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="高速" %}}
-基数木(redix tree)を元にしたルーティング、小さなメモリフットプリント、リフレクションなし、予測可能な API 性能などの特徴があります。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="ミドルウェアのサポート" %}}
-受信したHTTPリクエストをミドルウェアのチェーンと最終的なアクションによりハンドリングできます。たとえば、ロガー、認証、GZIP、さらに DB へのメッセージのポストなどが可能です。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="クラッシュフリー" %}}
-Gin は、HTTP リクエスト中に発生した panic をキャッチし、回復することが可能です。これにより、サーバーが常に利用可能な状態になります。さらに、この panic を Sentry などに報告することもできます。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON のバリデーション" %}}
-Gin はリクエストの JSON をパース・検証できます。たとえば、必須の値が存在するかどうかをチェックできます。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="ルートのグループ化" %}}
-ルートを上手く組織化しましょう。認証が必要なページと必要のないページ、異なるバージョンの API などを区別できます。さらに、各グループは性能劣化なしに無制限にネストできます。
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="エラーの管理" %}}
-Gin は HTTP リクエスト中に発生したすべてのエラーを収集する便利な手段を提供します。最終的に、ミドルウェアによって、ログファイルへの書き込み、データベースへの格納、ネットワーク越しの送信などが行われます。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="レンダリングのビルトイン" %}}
-Gin は JSON、XML、HTML のレンダリングのための簡単に使える API を提供します。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="拡張可能" %}}
-新しいミドルウェアの作成は非常に簡単です。サンプルコードを見てみてください。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/ja/blog/_index.md b/content/ja/blog/_index.md
deleted file mode 100644
index 0d5fcbf40..000000000
--- a/content/ja/blog/_index.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-title: "ブログ"
-linkTitle: "ブログ"
-menu:
- main:
- weight: 30
----
-
-
-ここれは **blog** セクションです。ニュースとリリースという2種類のカテゴリがあります。
-
-このディレクトリ内のファイルは時系列の降順にリストされます。
diff --git a/content/ja/blog/news/_index.md b/content/ja/blog/news/_index.md
deleted file mode 100644
index ed6a6ce82..000000000
--- a/content/ja/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "ニュース"
-linkTitle: "ニュース"
-weight: 20
----
-
-
diff --git a/content/ja/blog/releases/_index.md b/content/ja/blog/releases/_index.md
deleted file mode 100644
index 84b8217e9..000000000
--- a/content/ja/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "リリース"
-linkTitle: "リリース"
-weight: 20
----
-
-
diff --git a/content/ja/docs/_index.md b/content/ja/docs/_index.md
deleted file mode 100644
index f410d7114..000000000
--- a/content/ja/docs/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "ドキュメント"
-linkTitle: "ドキュメント"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin ってなに?
-
-Gin は Golang で書かれた Web アプリケーションフレームワークです。[martini](https://github.com/go-martini/martini) に似たAPIを持ちながら、[httprouter](https://github.com/julienschmidt/httprouter) のおかげでそれより40倍以上も速いパフォーマンスがあります。良いパフォーマンスと生産性が必要であれば、Gin が好きになれるでしょう。
-
-## Gin はどうやって使うの?
-
-APIの使い方の[サンプル](https://github.com/gin-gonic/examples)と、公開されている gin を利用しているプロダクトの[リスト](./users)を提供しています。
-
-## Gin にコントリビュートするには?
-
-* 議論の場で人々を助けてあげてください
-* Gin を利用した成功事例を教えてください
-* Gin を良くするにはどうすればいいか教えてください
-* 既に存在するライブラリにコントリビュートしてください
diff --git a/content/ja/docs/benchmarks/_index.md b/content/ja/docs/benchmarks/_index.md
deleted file mode 100644
index 0dd8d5135..000000000
--- a/content/ja/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "ベンチマーク"
-draft: false
-weight: 3
----
-
-Gin は [HttpRouter](https://github.com/julienschmidt/httprouter) をカスタムしたバージョンを利用しています。
-
-[すべてのベンチマークを見る](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): 一定時間内を満たした総試行回数。高いとよりよい結果を示している。
-- (2): 1試行にかかった時間(ns/op)。低いと良い。
-- (3): ヒープメモリ。低いと良い。
-- (4): 1試行回数当たりの平均ヒープアロケーション。低いと良い。
diff --git a/content/ja/docs/deployment/_index.md b/content/ja/docs/deployment/_index.md
deleted file mode 100644
index fe487c3db..000000000
--- a/content/ja/docs/deployment/_index.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "Deployment"
-draft: false
-weight: 6
----
-
-Ginのプロジェクトはあらゆるクラウドサービス上に簡単にデプロイできます。
-
-## [Render](https://render.com)
-
-RenderはGoをネイティブサポートするモダンなクラウドプラットフォームで、フルマネージドSSL、データベース、ダウンタイムのないデプロイ、HTTP/2、そしてwebsocketもサポートしています。
-
-Renderの[Ginプロジェクトのデプロイガイド](https://render.com/docs/deploy-go-gin)に詳細な記述があります。
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAEでGoのアプリケーションをデプロイするには2つの方法があります。スタンダード環境は簡単に使用できますが、カスタマイズ性は低く、セキュリティ上の問題で[システムコール](https://github.com/gin-gonic/gin/issues/1639)の使用は避けるべきです。フレキシブル環境はあらゆるフレームワークやライブラリが使用できます。
-
-さらに学んだり、より適した環境を探すには[Google App Engine 上での Go の使用](https://cloud.google.com/appengine/docs/go/)を参考にしてください。
diff --git a/content/ja/docs/examples/_index.md b/content/ja/docs/examples/_index.md
deleted file mode 100644
index ecb11cf4b..000000000
--- a/content/ja/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "APIの使い方のサンプル"
-draft: false
-weight: 6
----
-
-このセクションでは APIの使い方のサンプルを挙げます。
diff --git a/content/ja/docs/examples/ascii-json.md b/content/ja/docs/examples/ascii-json.md
deleted file mode 100644
index 5c8a75979..000000000
--- a/content/ja/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-AsciiJSON メソッドを使うことで、ASCII 文字列以外をエスケープした
-ASCII 文字列のみの JSON を出力できます。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"} が出力されます
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
diff --git a/content/ja/docs/examples/bind-body-into-dirrerent-structs.md b/content/ja/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index bfd17bf6f..000000000
--- a/content/ja/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "body を異なる構造体にバインドするには"
-draft: false
----
-
-通常のリクエスト本文をバインドするメソッドたちは、`c.Request.Body` を消費します。よってそれらのメソッドは複数回呼び出すことができません。
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // この c.ShouldBind メソッドは c.Request.Body を消費し、再利用できなくします。
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // c.Request.Body が EOF なので、常にエラーとなります。
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-複数回呼び出したい場合、`c.ShouldBindBodyWith` を使ってください。
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // このコードは、c.Request.Body を読み込み、そして結果を context に保存します。
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // ここでは、context に保存された body を再利用します。
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // 他のフォーマットも受け付けます。
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` はバインド前に context にリクエスト本文を保存します。この処理は、パフォーマンスにわずかな影響を与えます。バインディングが一度だけで良いなら、このメソッドは使うべきではありません。
-* この機能は `JSON`, `XML`, `MsgPack`,`ProtoBuf` のフォーマットでのみ必要です。`Query`, `Form`, `FormPost`, `FormMultipart` のような他のフォーマットでは `c.ShouldBind()` を何度も呼び出せるので、パフォーマンスへの影響はありません。(Issue [#1341](https://github.com/gin-gonic/gin/pull/1341) も参照ください)
diff --git a/content/ja/docs/examples/bind-form-data-request-with-custom-struct.md b/content/ja/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 34d83fb5b..000000000
--- a/content/ja/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,96 +0,0 @@
----
-title: "フォーム投稿されたリクエストを構造体にバインドする"
-draft: false
----
-
-下記のサンプルコードは、カスタム構造体を使っています。
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-`curl` を使った結果です。
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
-**NOTE**: 下記の構造体はサポートしていません。
-
-```go
-type StructX struct {
- X struct {} `form:"name_x"` // ここが form を持ってしまっている
-}
-
-type StructY struct {
- Y StructX `form:"name_y"` // ここが form を持ってしまっている
-}
-
-type StructZ struct {
- Z *StructZ `form:"name_z"` // ここが form を持ってしまっている
-}
-```
-
-端的に言えば、ネストした構造体は `form` を今は持つことができません。
-
-
diff --git a/content/ja/docs/examples/bind-html-checkbox.md b/content/ja/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 20bc88be6..000000000
--- a/content/ja/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "HTMLチェックボックスをバインドする"
-draft: false
----
-
-[詳細な情報](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092) はこちら。
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-結果
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/ja/docs/examples/bind-query-or-post.md b/content/ja/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 7e96cf9ca..000000000
--- a/content/ja/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "クエリ文字列あるいはポストされたデータをバインドする"
-draft: false
----
-
-[詳細](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292) はこちら。
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // `GET` の場合、`Form` (クエリ文字列) がバインディングのみが使われます
- // `POST` の場合、まず `JSON` か `XML` か判断するために `content-type` がチェックされ、そして `Form` (フォームデータ) が使われます。
- // 詳細は https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48 を参照
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-以下のコードでテストできます。
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/ja/docs/examples/bind-single-binary-with-template.md b/content/ja/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 07ebfa937..000000000
--- a/content/ja/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "テンプレートを含めた1つのバイナリをビルドする"
-draft: false
----
-
-[go-assets](https://github.com/jessevdk/go-assets) を利用することで、サーバーアプリケーションを、テンプレートを含む1つのバイナリにまとめることができます。
-
-[go-assets]: https://github.com/jessevdk/go-assets
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate は go-assets-builder によって埋め込まれたテンプレートたちをロードします。
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-完全なサンプルコードは、[assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) を見てください。
-
-
diff --git a/content/ja/docs/examples/bind-uri.md b/content/ja/docs/examples/bind-uri.md
deleted file mode 100644
index dc28f0702..000000000
--- a/content/ja/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "URLをバインドする"
-draft: false
----
-
-[詳細](https://github.com/gin-gonic/gin/issues/846) はこちら。
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-以下のコードでテストできます。
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
-
diff --git a/content/ja/docs/examples/binding-and-validation.md b/content/ja/docs/examples/binding-and-validation.md
deleted file mode 100644
index 71697056f..000000000
--- a/content/ja/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "モデルへのバインディングとバリデーションする"
-draft: false
----
-
-リクエストボディをある型にバインドするには、モデルへのバインディングを利用してください。Gin は今のところ JSON, XML, YAML と標準的なフォームの値(foo=bar&boo=baz)をサポートしています。
-
-Gin は [**go-playground/validator/v10**](https://github.com/go-playground/validator) をバリデーションに使用しています。 タグの使い方のすべてのドキュメントを読むには [ここ](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags) を参照してください。
-
-バインドしたいすべてのフィールドに対応するタグを設定する必要があることに注意してください。たとえば、JSONからバインドする場合は、`json:"fieldname"` を設定します。
-
-また、Gin は2種類のバインドのためのメソッドを用意しています。
-- **種類** - Must bind
- - **メソッド** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **挙動** - これらのメソッドは、内部では `MustBindWith` メソッドを使っています。もしバインド時にエラーがあった場合、ユーザーからのリクエストは `c.AbortWithError(400, err).SetType(ErrorTypeBind)` で中止されます。この処理は、ステータスコード 400 を設定し、`Content-Type` ヘッダーに `text/plain; charset=utf-8` をセットします。もしこのあとにステータスコードを設定しようとした場合、`[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422` という注意メッセージが表示されるので注意してください。もしこの挙動をよりコントロールする必要がある場合、`ShouldBind` という同様のメソッドを利用することを検討してください。
-- **種類** - Should bind
- - **メソッド** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **挙動** - これらのメソッドは、内部では `ShouldBindWith` メソッドを使っています。もしバインド時にエラーがあった場合、エラーが返ってくるので、開発者の責任で、適切にエラーやリクエストをハンドリングします。
-
-`Bind` メソッドを使用するとき、Gin は Content-Type ヘッダーに応じて何のバインダーでバインドするか推測しようとします。もし何のバインダーでバインドするかわかるならば、`MustBindWith` や `ShouldBindWith` が使えます。
-
-また、どのフィールドが必須か指定することができます。もしフィールドが、`binding:"required"` 指定されていて、バインディングの際に値が空であれば、エラーが返ります。
-
-```go
-// JSON からバインドする
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // JSON でバインドする例 ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // XML でバインドする例 (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // HTML Form からバインドする例 (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // このコードは、content-type ヘッダーから類推して HTML Form でバインドする
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // 0.0.0.0:8080 でサーバーを立てる
- router.Run(":8080")
-}
-```
-
-### リクエスト例
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### バリデーションをスキップする
-
-上記の `curl` コマンドのサンプルを実行すると、エラーが返ります。これはサンプルコードで `binding:"required"` が `Password` フィールドに指定されているからです。`binding:"-"` を `Password` フィールドに指定することで、上記のサンプルを実行してもエラーは返らなくなります。
diff --git a/content/ja/docs/examples/controlling-log-output-coloring.md b/content/ja/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index c69272c14..000000000
--- a/content/ja/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "ログ出力の色付けを制御する"
-draft: false
----
-
-デフォルトでは、ログ出力は検出された TTY に応じて色付けされます。
-
-ログの色付けを止めるには:
-
-```go
-func main() {
- // ログの色付けを無効にする:
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-常にログの色付けをするには:
-
-```go
-func main() {
- // ログの色付けを常に有効にする:
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ja/docs/examples/cookie.md b/content/ja/docs/examples/cookie.md
deleted file mode 100644
index fcbc27f0f..000000000
--- a/content/ja/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "cookieの設定と取得"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/ja/docs/examples/custom-http-config.md b/content/ja/docs/examples/custom-http-config.md
deleted file mode 100644
index 730ad1862..000000000
--- a/content/ja/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "カスタム HTTP 設定"
-draft: false
----
-
-以下のように `http.ListenAndServe()` を直接使ってください。
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-あるいは
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
-
-
diff --git a/content/ja/docs/examples/custom-log-format.md b/content/ja/docs/examples/custom-log-format.md
deleted file mode 100644
index 07c3abd8c..000000000
--- a/content/ja/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "カスタムログファイル"
-draft: false
----
-
-例:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter ミドルウェアは gin.DefaultWriter にログを出力する
- // デフォルトでは gin.DefaultWriter は os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // your custom format
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**出力例**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/ja/docs/examples/custom-middleware.md b/content/ja/docs/examples/custom-middleware.md
deleted file mode 100644
index aa5d7ec99..000000000
--- a/content/ja/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "カスタムミドルウェア"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // サンプル変数を設定
- c.Set("example", "12345")
-
- // request 処理の前
-
- c.Next()
-
- // request 処理の後
- latency := time.Since(t)
- log.Print(latency)
-
- // 送信予定のステータスコードにアクセスする
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // "12345" が表示される
- log.Println(example)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/custom-validators.md b/content/ja/docs/examples/custom-validators.md
deleted file mode 100644
index 460df4516..000000000
--- a/content/ja/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: "カスタムバリデーション"
-draft: false
----
-
-カスタムしたバリデーションを使用することもできます。[サンプルコード](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) も見てみてください。
-
-```go
-package main
-
-import (
- "net/http"
- "reflect"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking はバリデーションされてバインドされたデータを持ちます
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-func bookableDate(
- v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
- field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
-) bool {
- if date, ok := field.Interface().(time.Time); ok {
- today := time.Now()
- if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
-{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
-```
-
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) もこの方法で登録できます。
-[struct-lvl-validation のサンプルコード](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) を見ることでより学べます。
diff --git a/content/ja/docs/examples/define-format-for-the-log-of-routes.md b/content/ja/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 172441891..000000000
--- a/content/ja/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "ルーティングログのフォーマットを定義する"
-draft: false
----
-
-デフォルトのルーティングログは以下のようになります。
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-もしログのフォーマットを定義したい(JSONやキーバリュー形式、その他)なら、`gin.DebugPrintRouteFunc` を定義することで可能です。
-以下のサンプルコードでは、すべてのルーティングを標準の log パッケージで記録していますが、必要に応じて最適な別のログツールを利用することも可能です。
-
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // http://0.0.0.0:8080 でサーバーを立てる
- r.Run()
-}
-```
diff --git a/content/ja/docs/examples/goroutines-inside-a-middleware.md b/content/ja/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 8123cadc0..000000000
--- a/content/ja/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "ミドルウェア内の Goroutine"
-draft: false
----
-
-新しい goroutine をミドルウェアやハンドラー内で生成する場合、goroutine の内部でオリジナルの context を **使用しないでください**。読み込み用のコピーを使ってください。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // goroutine 内で使用するコピーを生成します
- cCp := c.Copy()
- go func() {
- // time.Sleep() を使って、長時間かかる処理をシミュレートします。5秒です。
- time.Sleep(5 * time.Second)
-
- // コピーされた context である "cCp" を使ってください。重要!
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // time.Sleep() を使って、長時間かかる処理をシミュレートします。5秒です。
- time.Sleep(5 * time.Second)
-
- // goroutine を使ってなければ、context をコピーする必要はありません。
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/graceful-restart-or-stop.md b/content/ja/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 3cf526c4a..000000000
--- a/content/ja/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-title: "graceful restart と stop"
-draft: false
----
-
-graceful restart と stop をしたいですか?
-いくつかの方法があります。
-
-[fvbock/endless](https://github.com/fvbock/endless) を使って、デフォルトの `ListenAndServe` を置き換えることができます。詳細は Issue [#296](https://github.com/gin-gonic/gin/issues/296) を参照ください。
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-endless の代わりは以下があります。
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-もし Go 1.8 を使っているなら、これらのライブラリを使う必要はないかもしれません!http.Server 組み込みの [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) メソッドを、graceful shutdowns に利用することを検討してみてください。詳細は Gin の [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) サンプルコードを見てみてください。
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // サービスの接続
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // シグナル割り込みを待ち、タイムアウト時間が5秒の graceful shutdown をする
- quit := make(chan os.Signal, 1)
- // kill (no param) default send syscanll.SIGTERM
- // kill -2 is syscall.SIGINT
- // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // ctx.Done() をキャッチする。5秒間のタイムアウト。
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
-
diff --git a/content/ja/docs/examples/grouping-routes.md b/content/ja/docs/examples/grouping-routes.md
deleted file mode 100644
index 5cf449e75..000000000
--- a/content/ja/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "ルーティングをグループ化する"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // v1 のグループ
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // v2 のグループ
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/html-rendering.md b/content/ja/docs/examples/html-rendering.md
deleted file mode 100644
index 6fb9576c0..000000000
--- a/content/ja/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML をレンダリングする"
-draft: false
----
-
-LoadHTMLGlob() あるいは LoadHTMLFiles() メソッドを使用してください。
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-別のディレクトリにある同名のテンプレートを使う方法です。
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### カスタムテンプレートエンジン
-
-独自のHTMLテンプレートエンジンを使うこともできます。
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### カスタムデリミタ
-
-独自のデリミタを使用することもできます。
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### カスタムテンプレート関数
-
-詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/template) を参照。
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/ja/docs/examples/http-method.md b/content/ja/docs/examples/http-method.md
deleted file mode 100644
index 1697c3582..000000000
--- a/content/ja/docs/examples/http-method.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "GET,POST,PUT,PATCH,DELETE,OPTIONS メソッドを使う"
-draft: false
----
-
-```go
-func main() {
- // デフォルトのミドルウェアで新しい gin ルーターを作成する
- // logger とアプリケーションクラッシュをキャッチする recovery ミドルウェア
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // デフォルトではポート 8080 が利用されるが、
- // 環境変数 PORT を指定していればそちらが優先される。
- router.Run()
- // router.Run(":3000") と書くことでポートをハードコーディングできる
-}
-```
-
-
diff --git a/content/ja/docs/examples/http2-server-push.md b/content/ja/docs/examples/http2-server-push.md
deleted file mode 100644
index fb3f7e2c7..000000000
--- a/content/ja/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,52 +0,0 @@
----
-title: "HTTP/2 サーバープッシュ"
-draft: false
----
-
-http.Pusher は **go1.8+** 以降でのみサポートしています。 詳細な情報は [golang blog](https://blog.golang.org/h2push) を見てください。
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // サーバープッシュするために pusher.Push() を使う
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // https://127.0.0.1:8080 でサーバーを立てる
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
-
diff --git a/content/ja/docs/examples/jsonp.md b/content/ja/docs/examples/jsonp.md
deleted file mode 100644
index dae73ed0e..000000000
--- a/content/ja/docs/examples/jsonp.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "JSONP をレンダリングする"
-draft: false
----
-
-JSONP を使うことで、別のドメインのサーバーからレスポンスを受け取ることができます。callback をクエリ文字列に指定することで、レスポンスに callback を追加します。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback は x です。
- // x({\"foo\":\"bar\"}) が出力されます。
- c.JSONP(http.StatusOK, data)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/map-as-querystring-or-postform.md b/content/ja/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index 68c6db17b..000000000
--- a/content/ja/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "クエリ文字列やフォーム投稿によるパラメータをマッピングする"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
-
diff --git a/content/ja/docs/examples/multipart-urlencoded-binding.md b/content/ja/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 1c3f85dd0..000000000
--- a/content/ja/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Multipart/Urlencoded されたデータをバインドする"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // 明示的にバインディングを定義して、multipart form をバインドすることができます。
- // c.ShouldBindWith(&form, binding.Form)
- // あるいは、ShouldBind メソッドを使うことで、シンプルに自動でバインドすることもできます。
- var form LoginForm
- // このケースでは正しいバインディングが自動で選択されます。
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-以下のコードでテストできます。
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
-
-
diff --git a/content/ja/docs/examples/multipart-urlencoded-form.md b/content/ja/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index d4f4527eb..000000000
--- a/content/ja/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Multipart/Urlencoded フォーム"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/multiple-template.md b/content/ja/docs/examples/multiple-template.md
deleted file mode 100644
index 749c2767d..000000000
--- a/content/ja/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,9 +0,0 @@
----
-title: "複数のテンプレート"
-draft: false
----
-
-Gin はデフォルトでは、1つの html.Template しか使用できません。
-go 1.6 の `block template` のような機能が使用できる [a multitemplate render](https://github.com/gin-contrib/multitemplate) を検討してください。
-
-
diff --git a/content/ja/docs/examples/only-bind-query-string.md b/content/ja/docs/examples/only-bind-query-string.md
deleted file mode 100644
index 47c524dc0..000000000
--- a/content/ja/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: "クエリ文字列のみバインドする"
-draft: false
----
-
-`ShouldBindQuery` 関数はクエリ文字列のみをバインドし、POSTデータをバインドしません。[詳細](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017) はこちら。
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-
-```
-
diff --git a/content/ja/docs/examples/param-in-path.md b/content/ja/docs/examples/param-in-path.md
deleted file mode 100644
index 8a50fa341..000000000
--- a/content/ja/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: "パスに含まれるパラメータ"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // このハンドラは /user/john にはマッチするが、/user/ や /user にはマッチしない
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // しかし、下記は /user/john/ と /user/john/send にマッチする
- // もしほかのルーターが /user/john にマッチしなければ、/user/john/ にリダイレクトしてくれる
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/pure-json.md b/content/ja/docs/examples/pure-json.md
deleted file mode 100644
index 2cc0d7adf..000000000
--- a/content/ja/docs/examples/pure-json.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-通常、JSON メソッドは `<` のようなHTML 文字を `\u003c` のような Unicode に置き換えます。
-もしこのような文字をそのままエンコードしたい場合、PureJSON メソッドを代わりに使用してください。
-この機能は、Go 1.6 以下では使えません。
-
-```go
-func main() {
- r := gin.Default()
-
- // Unicode を返します
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // そのままの文字を返します
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/query-and-post-form.md b/content/ja/docs/examples/query-and-post-form.md
deleted file mode 100644
index 59be66288..000000000
--- a/content/ja/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-title: "フォーム投稿によるクエリ文字列"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
-
-
diff --git a/content/ja/docs/examples/querystring-param.md b/content/ja/docs/examples/querystring-param.md
deleted file mode 100644
index 71409666e..000000000
--- a/content/ja/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: "クエリ文字列のパラメータ"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // クエリ文字列のパラメータは、既存の Request オブジェクトによって解析される。
- // このルーターは、/welcome?firstname=Jane&lastname=Doe にマッチしたURLにアクセスすると、レスポンスを返す
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname") へのショートカット
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/redirects.md b/content/ja/docs/examples/redirects.md
deleted file mode 100644
index f4617c4ad..000000000
--- a/content/ja/docs/examples/redirects.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "リダイレクト"
-draft: false
----
-
-HTTP リダイレクトするのは簡単です。内部パス、外部URL両方のリダイレクトに対応しています。
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-POSTからのHTTPリダイレクトのissueは [#444](https://github.com/gin-gonic/gin/issues/444) を参照してください。
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Router でリダイレクトするには、下記のように `HandleContext` メソッドを使ってください。
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
-
-
-
diff --git a/content/ja/docs/examples/rendering.md b/content/ja/docs/examples/rendering.md
deleted file mode 100644
index b44dfbcdb..000000000
--- a/content/ja/docs/examples/rendering.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: "XML, JSON, YAML, ProtoBuf をレンダリングする"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H は map[string]interface{} へのショートカットです。
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // 構造体を使うこともできます。
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // msg.Name は JSON 内で "user" となることに注意してください
- // 右記が出力されます : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // protobuf の定義は testdata/protoexample にかかれています。
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // データはレスポンス時にバイナリデータになることに注意してください。
- // protoexample.Test の protobuf でシリアライズされたデータが出力されます。
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/run-multiple-service.md b/content/ja/docs/examples/run-multiple-service.md
deleted file mode 100644
index 77d82e755..000000000
--- a/content/ja/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,83 +0,0 @@
----
-title: "Gin を使って複数のサービスを稼働させる"
-draft: false
----
-
-[issue](https://github.com/gin-gonic/gin/issues/346) を見て、以下のサンプルコードを試してみてください。
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
diff --git a/content/ja/docs/examples/secure-json.md b/content/ja/docs/examples/secure-json.md
deleted file mode 100644
index 3669a52f3..000000000
--- a/content/ja/docs/examples/secure-json.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-SecureJSON メソッドを使うことで、JSON ハイジャックを防げます。与えられた構造体が Array であれば、
-デフォルトで `"while(1),"` がレスポンスに含まれます。
-
-```go
-func main() {
- r := gin.Default()
-
- // 別の prefix を使うこともできます
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // while(1);["lena","austin","foo"] が出力されます。
- c.SecureJSON(http.StatusOK, names)
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
diff --git a/content/ja/docs/examples/security-headers.md b/content/ja/docs/examples/security-headers.md
deleted file mode 100644
index 521eeeef2..000000000
--- a/content/ja/docs/examples/security-headers.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "セキュリティ・ヘッダ"
-draft: false
----
-
-セキュリティヘッダの使用は、一般的なセキュリティの脆弱性からウェブアプリケーションを守るために重要です。この例では、Gin アプリケーションにセキュリティヘッダーを追加する方法と、ホストヘッダーインジェクションに関連する攻撃(SSRF、Open Redirection)を回避する方法を示します。
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-`curl`でテストできます:
-
-
-```bash
-// ヘッダーのチェック
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// ホスト・ヘッダー・インジェクションのチェック
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/ja/docs/examples/serving-data-from-reader.md b/content/ja/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index 94e99811e..000000000
--- a/content/ja/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "io.Reader からのデータを返す"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/serving-static-files.md b/content/ja/docs/examples/serving-static-files.md
deleted file mode 100644
index 55a728101..000000000
--- a/content/ja/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "静的ファイルを返す"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // 0.0.0.0:8080 でサーバーを立てます。
- router.Run(":8080")
-}
-```
diff --git a/content/ja/docs/examples/support-lets-encrypt.md b/content/ja/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index a5a5dfadc..000000000
--- a/content/ja/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Let's Encrypt のサポート"
-draft: false
----
-
-1行の Let's Encrypt HTTPS サーバーのサンプルコードです。
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-カスタム autocert manager を利用したサンプルコードです。
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
-
diff --git a/content/ja/docs/examples/upload-file/_index.md b/content/ja/docs/examples/upload-file/_index.md
deleted file mode 100644
index 982d95955..000000000
--- a/content/ja/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "ファイルアップロード"
-draft: false
----
-
-このセクションではファイルのアップロードAPIの使い方を列挙します。
diff --git a/content/ja/docs/examples/upload-file/multiple-file.md b/content/ja/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index dccd25d0d..000000000
--- a/content/ja/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "複数のファイル"
-draft: false
----
-
-詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple) 参照のこと.
-
-```go
-func main() {
- router := gin.Default()
- // マルチパートフォームが利用できるメモリの制限を設定する(デフォルトは 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // マルチパートフォーム
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // 特定のディレクトリにファイルをアップロードする
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-`curl` での使い方:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/ja/docs/examples/upload-file/single-file.md b/content/ja/docs/examples/upload-file/single-file.md
deleted file mode 100644
index e393e8465..000000000
--- a/content/ja/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "単一のファイル"
-draft: false
----
-
-issue [#774](https://github.com/gin-gonic/gin/issues/774) と、詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/upload-file/single) 参照。
-
-`file.Filename` を信用する**べきではありません**。 [MDN の `Content-Disposition`](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition#Directives) と [#1693](https://github.com/gin-gonic/gin/issues/1693) を参照。
-
-> ファイル名は常にオプションであり、アプリケーションで闇雲に使用しないでください。パス情報を削除し、サーバーのファイルシステムルールに変換すべきです。
-
-```go
-func main() {
- router := gin.Default()
- // マルチパートフォームが利用できるメモリの制限を設定する(デフォルトは 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // 単一のファイル
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // 特定のディレクトリにファイルをアップロードする
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-`curl` での使い方:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
-
diff --git a/content/ja/docs/examples/using-basicauth-middleware.md b/content/ja/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index db0c110e4..000000000
--- a/content/ja/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,42 +0,0 @@
----
-title: "BasicAuth ミドルウェアを使う"
-draft: false
----
-
-```go
-// 秘匿されたデータをシミュレートする
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // gin.BasicAuth() ミドルウェアを使用したグループ
- // gin.Accounts は map[string]string へのショートカットです。
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets エンドポイントは localhost:8080/admin/secrets です。
- authorized.GET("/secrets", func(c *gin.Context) {
- // BasicAuth ミドルウェアで設定されたユーザー名にアクセスします。
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // 0.0.0.0:8080 でサーバーを立てます。
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/using-middleware.md b/content/ja/docs/examples/using-middleware.md
deleted file mode 100644
index f43ca6b08..000000000
--- a/content/ja/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "ミドルウェアを利用する"
-draft: false
----
-
-```go
-func main() {
- // デフォルトのミドルウェアが何もない router を作成する
- r := gin.New()
-
- // グローバルなミドルウェア
- // Logger ミドルウェアは GIN_MODE=release を設定してても、 gin.DefaultWriter にログを出力する
- // gin.DefaultWriter はデフォルトでは os.Stdout。
- r.Use(gin.Logger())
-
- // Recovery ミドルウェアは panic が発生しても 500 エラーを返してくれる
- r.Use(gin.Recovery())
-
- // 個別のルーティングに、ミドルウェアを好きに追加することもできる
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // 認証が必要なグループ
- // authorized := r.Group("/", AuthRequired())
- // 下記と同一
- authorized := r.Group("/")
- // 個別のグループのミドルウェア。この例では、AuthRequired() ミドルウェアを認証が必要なグループに設定している。
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // ネストしたグループ
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // 0.0.0.0:8080 でサーバーを立てる
- r.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/examples/without-middleware.md b/content/ja/docs/examples/without-middleware.md
deleted file mode 100644
index 2dff9b652..000000000
--- a/content/ja/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "デフォルトで設定されるミドルウェアがない空の Gin を作成する"
-draft: false
----
-
-```go
-r := gin.New()
-```
-
-下記のコードではなく、上記のコードを利用する
-
-```go
-// Default は Logger と Recovery ミドルウェアが既にアタッチされている
-r := gin.Default()
-```
-
-
diff --git a/content/ja/docs/examples/write-log.md b/content/ja/docs/examples/write-log.md
deleted file mode 100644
index 793f78198..000000000
--- a/content/ja/docs/examples/write-log.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "ログファイルへ書き込むには"
-draft: false
----
-
-```go
-func main() {
- // コンソール出力時の色を無効にする。ログファイルに書き込むならば、色は不要なので。
- gin.DisableConsoleColor()
-
- // ファイルへログを書き込む
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // ログに書き込みつつ、コンソールにも出力する場合、下記のコードを利用する。
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-
diff --git a/content/ja/docs/faq/_index.md b/content/ja/docs/faq/_index.md
deleted file mode 100644
index bfec22d8b..000000000
--- a/content/ja/docs/faq/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: Github の Issue でよく聞かれる質問を書く
diff --git a/content/ja/docs/features/_index.md b/content/ja/docs/features/_index.md
deleted file mode 100644
index 58eed7860..000000000
--- a/content/ja/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "機能"
-draft: false
-weight: 4
----
-
-#### Gin v1 の安定性
-
-- ヒープメモリの拡張が0のルーター
-
-- 最速の http ルーターとフレームワーク
-
-- 一揃いのユニットテストをすべて満たしている
-
-- バトルがテストされている
-
-- APIは固まっており、新しいバージョンが既存のコードを壊すことはない
diff --git a/content/ja/docs/introduction/_index.md b/content/ja/docs/introduction/_index.md
deleted file mode 100644
index 98b1b6385..000000000
--- a/content/ja/docs/introduction/_index.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "まず始めに"
-draft: false
-weight: 1
----
-
-Gin は Golang で書かれた Web アプリケーションフレームワークです。martini に似たAPIを持ちながら、httprouter のおかげでそれより40倍以上も速いパフォーマンスがあります。良いパフォーマンスと生産性が必要であれば、Gin が好きになれるでしょう。
-
-この章では、Gin とは何か、どんな問題を解決してくれるのか、そしてどのようにあなたのプロジェクトを助かるのかを説明します。
-
-あなたがプロジェクトで Gin を使う準備がもし整っているのならば、[クイックスタート](../quickstart)を見てください。
-
-# 機能
-
-#### 高速
-基数木ベースのルーティング、そして小さなメモリ使用量。reflection は使っていません。予測可能なAPIパフォーマンス。
-
-#### ミドルウェアの支援
-受け取った HTTP リクエストは、一連のミドルウェアと、最終的なアクションによって処理されます。
-例:ログ出力、認証、GZIP 圧縮、そして最終的にDBにメッセージを投稿します。
-
-#### クラッシュフリー
-Gin は、HTTP リクエストの処理中に発生した panic を recover します。これにより、サーバーは常にユーザーからの応答を返すことができます。またこれにより例えば panic を Sentry に送ったりすることも可能です!
-
-#### JSON バリデーション
-Gin は JSON によるリクエストを解析してバリデーションすることができます。例えば必要な値の存在をチェックすることができます。
-
-#### ルーティングのグループ化
-ルーティングをもっとよく整理しましょう。認証が必要かどうか、異なるバージョンのAPIかどうか...加えて、パフォーマンスを低下させることなく、無制限にネストしたグループ化を行うことができます。
-
-#### エラー管理
-Ginは、HTTP リクエスト中に発生したすべてのエラーを収集するための便利な方法を提供します。最終的に、ミドルウェアはそれらをログファイル、データベースに書き込み、ネットワーク経由で送信することができます。
-
-#### 組み込みのレンダリング
-Ginは、JSON、XML、およびHTMLでレンダリングするための使いやすいAPIを提供します。
-
-#### 拡張性
-とても簡単に新しいミドルウェアを作成できます。サンプルコードをチェックしてみてください。
diff --git a/content/ja/docs/jsoniter/_index.md b/content/ja/docs/jsoniter/_index.md
deleted file mode 100644
index 21bc826f6..000000000
--- a/content/ja/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## [jsoniter](https://github.com/json-iterator/go) でビルドする
-
-Gin はデフォルトの json パッケージとして `encoding/json` を使っていますが、他のタグからビルドすることで、[jsoniter](https://github.com/json-iterator/go) を使うこともできます。
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/ja/docs/quickstart/_index.md b/content/ja/docs/quickstart/_index.md
deleted file mode 100644
index 505733b47..000000000
--- a/content/ja/docs/quickstart/_index.md
+++ /dev/null
@@ -1,86 +0,0 @@
----
-title: "クイックスタート"
-draft: false
-weight: 2
----
-
-このクイックスタートでは、コードの集まりからの洞察を収集し、どのようにするかを学びます。
-
-## 要件
-
-- Gin を利用するには Go 1.16 以上が必要です。
-
-## インストール
-
-Gin をインストールするには、まず Go のインストールおよび Go のワークスペースを作ることが必要です。
-
-1. ダウンロードしてインストールする
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. コード内でインポートする
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (オプション) `net/http` をインポートする。`http.StatusOK` のような定数を使用する場合に必要です
-
-```go
-import "net/http"
-```
-
-1. プロジェクトフォルダを作り、 `cd` で中に入ります。
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. 開始用テンプレートをプロジェクトディレクトリにコピーする
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. プロジェクトを実行する
-
-```sh
-$ go run main.go
-```
-
-## Getting Started
-
-> Go のコードを書いて実行する方法がわからない? [ここをクリックしてください](https://golang.org/doc/code.html).
-
-まず、`example.go` を作成します。
-
-```sh
-# 後述のコードが、example.go のファイルにあるとします。
-$ touch example.go
-```
-
-次に、下記のコードを `example.go` に書きます。
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // 0.0.0.0:8080 でサーバーを立てます。
-}
-```
-
-そして `go run example.go` でコードを実行します。
-
-```
-# example.go を実行し、ブラウザで 0.0.0.0:8080/ping にアクセスする
-$ go run example.go
-```
diff --git a/content/ja/docs/testing/_index.md b/content/ja/docs/testing/_index.md
deleted file mode 100644
index f88ce81a4..000000000
--- a/content/ja/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "テスト"
-draft: false
-weight: 7
----
-
-##### Gin でテストコードを書くには
-
-`net/http/httptest` パッケージが、HTTP テストをするには好ましい方法です。
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-テストコードの例は以下のようになります。
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/ja/docs/users/_index.md b/content/ja/docs/users/_index.md
deleted file mode 100644
index 1b3b53ac1..000000000
--- a/content/ja/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Gin のユーザー"
-draft: false
-weight: 8
----
-
-##### [Gin](https://github.com/gin-gonic/gin) を利用している素晴らしいプロジェクト一覧。
-
-* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
-
-* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
-
-* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
-
-* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
-
-* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
-
-* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/content/ja/search.md b/content/ja/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/ja/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/content/ko-kr/_index.html b/content/ko-kr/_index.html
deleted file mode 100644
index fd2efc05d..000000000
--- a/content/ko-kr/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**What is Gin?**
-
-Gin is a web framework written in Golang.
-
-It features a martini-like API with much better performance, up to 40 times faster.
-
-If you need performance and good productivity, you will love Gin.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Fast" %}}
-Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Middleware support" %}}
-A incoming HTTP request can be handled by a chain of middlewares and the final action.
-For example: Logger, Authorization, GZIP and finally post a message in the DB.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash-free" %}}
-Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON validation" %}}
-Gin can parse and validate the JSON of a request, checking for example the existence of required values.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Routes grouping" %}}
-Organize your routes better. Authorization required vs non required, different API versions. In addition, the groups can be nested unlimitedly without degrading performance.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Error management" %}}
-Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, a middleware can write them to a log file, to a database and send them through the network.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Rendering built-in" %}}
-Gin provides an easy to use API for JSON, XML and HTML rendering.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Extendable" %}}
-Creating a new middleware is so easy, just check out the sample codes.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/ko-kr/blog/_index.md b/content/ko-kr/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/ko-kr/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/ko-kr/blog/news/_index.md b/content/ko-kr/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/ko-kr/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/ko-kr/blog/releases/_index.md b/content/ko-kr/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/ko-kr/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/ko-kr/docs/_index.md b/content/ko-kr/docs/_index.md
deleted file mode 100644
index ae381b000..000000000
--- a/content/ko-kr/docs/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "문서"
-linkTitle: "문서"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin 이란?
-
-Gin은 Go 언어로 작성된 HTTP Web 프레임워크입니다. [Martini](https://github.com/go-martini/martini)와 유사한 API를 제공하지만,최대 40배 빠른 성능을 발휘합니다. 매우 좋은 성능이 필요하다면 Gin을 사용하세요.
-
-## Gin의 사용법은?
-
-우리는 API [예제들](https://github.com/gin-gonic/examples)과 [Gin을 사용하는 프로젝트](./users) 리스트를 제공하고 있습니다.
-
-## Gin에 기여하기 위해서는?
-
-* 토론 포럼에서 사람들을 도와주세요
-* Gin을 사용한 성공사례를 알려주세요
-* Gin을 개선하기 위한 좋은 방법이 있다면 알려주세요
-* 기존의 라이브러리에 기여해주세요
diff --git a/content/ko-kr/docs/benchmarks/_index.md b/content/ko-kr/docs/benchmarks/_index.md
deleted file mode 100644
index f1ce2a5c8..000000000
--- a/content/ko-kr/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "벤치마크"
-draft: false
-weight: 3
----
-
-Gin은 [HttpRouter](https://github.com/julienschmidt/httprouter)을 커스텀 한 버전을 사용합니다.
-
-[모든 벤치마크 보기](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| 벤치마크 이름 | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): 일정한 시간 내에 실행된 총횟수, 높을수록 더 좋은 결과를 뜻합니다.
-- (2): 1회 실행에 걸린 시간 (ns/op), 낮을수록 좋습니다.
-- (3): 힙 메모리 (B/op), 낮을수록 좋습니다.
-- (4): 1회 실행에 할당된 메모리 평균량 (allocs/op), 낮을수록 좋습니다.
diff --git a/content/ko-kr/docs/deployment/_index.md b/content/ko-kr/docs/deployment/_index.md
deleted file mode 100644
index 9b650deaf..000000000
--- a/content/ko-kr/docs/deployment/_index.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "배포"
-draft: false
-weight: 6
----
-
-Gin 프로젝트는 모든 클라우드 제공 업체에 쉽게 배포 할 수 있습니다.
-
-## [Render](https://render.com)
-
-Render은 Go를 기본 지원하는 최신 클라우드 플랫폼으로, SSL관리, 데이터베이스, 무중단 배포, HTTP/2, websocket을 지원합니다.
-
-Render의 [Gin프로젝트 배포 가이드](https://render.com/docs/deploy-go-gin)를 참조하세요.
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE에는 Go어플리케이션을 배포하는 두 가지 방법이 있습니다. 표준환경은 간단히 사용할 수 있으나, 사용자 정의가 어려우며 보안상의 이유로 [syscalls](https://github.com/gin-gonic/gin/issues/1639)를 사용할 수 없습니다. 가변형 환경은 모든 프레임워크와 라이브러리를 사용할 수 있습니다.
-
-[Google App Engine의 Go](https://cloud.google.com/appengine/docs/go/)에서 자세히 알아보고 자신에게 알맞은 환경을 선택하세요.
diff --git a/content/ko-kr/docs/examples/_index.md b/content/ko-kr/docs/examples/_index.md
deleted file mode 100644
index de0236e9f..000000000
--- a/content/ko-kr/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "예제"
-draft: false
-weight: 6
----
-
-이 장에는 API 사용법이 있습니다.
diff --git a/content/ko-kr/docs/examples/ascii-json.md b/content/ko-kr/docs/examples/ascii-json.md
deleted file mode 100644
index 64e7205cc..000000000
--- a/content/ko-kr/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-이스케이프 된 비 ASCII character를 AsciiJSON을 사용하여 ASCII 전용 JSON을 생성합니다
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // 출력내용 : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md b/content/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index f99f476be..000000000
--- a/content/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,59 +0,0 @@
----
-title: "body를 다른 구조체에 바인드 하기"
-draft: false
----
-
-일반적인 body 바인딩 메소드는 `c.Request.Body`를 소모합니다.
-따라서 이러한 메소드들은 여러번 호출할 수 없습니다.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // 아래의 c.ShouldBind는 c.Request.Body를 소모하며, 재이용이 불가능합니다.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // c.Request.Body가 EOF 이므로 에러가 발생합니다.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-이를 위해 `c.ShouldBindBodyWith`를 사용하여 해결 할 수 있습니다.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // c.Request.Body를 읽고 context에 결과를 저장합니다.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // context에 저장된 body를 읽어 재이용 합니다.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // 다른 형식을 사용할 수도 있습니다.
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith`는 바인딩 전에 context에 body를 저장합니다. 이것은 성능에 약간의
-영향을 미치기 때문에 한번의 바인딩으로 충분하다면, 이 메소드를 사용하지 않는 것이 좋습니다.
-* 이 기능은 `JSON`, `XML`, `MsgPack`,`ProtoBuf` 형식에만 필요합니다.
-`Query`, `Form`, `FormPost`, `FormMultipart`와 같은 다른 형식은 성능에 영향을 주지 않고
-`c.ShouldBind()`에 의해 여러번 호출 될 수 있습니다. (이슈 참고[#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md b/content/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 5dd47cd31..000000000
--- a/content/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "양식 데이터 리퀘스트를 구조체에 바인드 하기"
-draft: false
----
-
-아래의 예제는 사용자 정의 구조체를 사용합니다:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-`curl` 명령어를 이용한 결과 입니다:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/ko-kr/docs/examples/bind-html-checkbox.md b/content/ko-kr/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 4a6a2ce2f..000000000
--- a/content/ko-kr/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "html 체크박스를 바인드 하기"
-draft: false
----
-
-[자세한 정보](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)를 확인 하세요.
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-결과:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/ko-kr/docs/examples/bind-query-or-post.md b/content/ko-kr/docs/examples/bind-query-or-post.md
deleted file mode 100644
index fbcc43197..000000000
--- a/content/ko-kr/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "쿼리 문자열 혹은 post 데이터를 바인드하기"
-draft: false
----
-
-[자세한 정보](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292)를 확인하세요.
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // `GET`의 경우 `Form` (`query`)만 사용됩니다.
- // `POST`의 경우, 먼저 `content-type`가 `JSON` 혹은 `XML`을 확인한 다음 `Form` (`form-data`)가 사용됩니다.
- // 자세한 정보는 https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48 를 참고하세요.
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-다음과 같이 테스트 할 수 있습니다:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/ko-kr/docs/examples/bind-single-binary-with-template.md b/content/ko-kr/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 99c109e99..000000000
--- a/content/ko-kr/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "템플릿을 포함한 단일 바이너리 빌드"
-draft: false
----
-
-[go-assets](https://github.com/jessevdk/go-assets)를 사용하여 템플릿을 포함한 단일 바이너리로 서버를 만들 수 있습니다.
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate은 go-assets-builder에 의해 임베디드 된 템플릿을 로드합니다
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-전체 예제는 [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) 디렉토리에서 확인하세요.
diff --git a/content/ko-kr/docs/examples/bind-uri.md b/content/ko-kr/docs/examples/bind-uri.md
deleted file mode 100644
index cf5408e4c..000000000
--- a/content/ko-kr/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "URI를 바인드하기"
-draft: false
----
-
-[자세한 정보](https://github.com/gin-gonic/gin/issues/846)를 확인하세요.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-다음과 같이 테스트 할 수 있습니다:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/ko-kr/docs/examples/binding-and-validation.md b/content/ko-kr/docs/examples/binding-and-validation.md
deleted file mode 100644
index 9fd744dbf..000000000
--- a/content/ko-kr/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,119 +0,0 @@
----
-title: "모델 바인딩과 유효성 검사"
-draft: false
----
-
-리퀘스트 바디를 바인딩하려면 모델 바인딩을 사용하세요. 현재 JSON, XML, YAML 및 표준 form values (foo=bar&boo=baz) 바인딩을 지원합니다.
-
-Gin은 유효성 검사에 [**go-playground/validator/v10**](https://github.com/go-playground/validator)을 사용합니다. 태그 사용법에 대한 전체 문서는 [여기](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags)를 확인하세요.
-
-바인딩 하려는 모든 항목에 대해 해당 바인딩 태그를 설정해야 합니다. 예를 들어, JSON을 바인딩 하려면 `json:"fieldname"`을 설정하세요.
-
-또한, Gin은 바인딩을 위해 2가지 방법을 제공합니다:
-
-- **타입** - Must bind
- - **메소드** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **동작** - 이 메소드들은 내부에서 `MustBindWith`를 사용합니다. 바인딩 에러가 있는 경우, 리퀘스트는 `c.AbortWithError(400, err).SetType(ErrorTypeBind)`와 함께 중단됩니다. 응답코드는 400으로 설정되며, `Content-Type`헤더에는 `text/plain; charset=utf-8`이 설정됩니다. 이 이후에 응답코드를 설정하려고 하면 `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422` 경고가 발생합니다. 동작을 더 상세하게 제어하고 싶다면 `ShouldBind`와 같은 메소드를 사용하세요.
-- **타입** - Should bind
- - **메소드** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **동작** - 이 메소드들은 내부에서 `ShouldBindWith`를 사용합니다. 바인딩 에러가 있는 경우, 에러를 적절히 처리하고 반환하는 것은 개발자의 몫입니다.
-
-Gin은 Bind-method를 사용할 때 Content-Type 헤더에 따라 바인더를 유추합니다. 바인딩하는 내용이 확실한 경우 `MustBindWith` 또는 `ShouldBindWith`를 사용할 수 있습니다.
-
-특정 항목을 필수로 지정할 수도 있습니다. 항목이 `binding:"required"`로 설정되어 있으나, 바인딩 할 값이 비어 있다면 에러가 반환됩니다.
-
-```go
-// JSON 바인딩
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // JSON 바인딩 예제 ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // XML 바인딩 예제 (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // HTML form 바인딩 예제 (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // content-type 헤더에 따라 사용할 바인더를 유추합니다.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- router.Run(":8080")
-}
-```
-
-### 요청문 예제
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### 유효성 검사 건너뛰기
-
-위의 `curl` 명령어를 실행하면, 에러가 반환됩니다. 이 예제에서는 `Password`에 `binding:"required"`가 설정되어 있기 때문입니다. `Password`에 `binding:"-"`을 설정한 후 실행하면 에러가 발생하지 않습니다.
diff --git a/content/ko-kr/docs/examples/controlling-log-output-coloring.md b/content/ko-kr/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index bed56dd70..000000000
--- a/content/ko-kr/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "로그 출력 색상 설정"
-draft: false
----
-
-기본적으로, 출력되는 로그의 색상은 감지된 TTY에 따라 지정 됩니다.
-
-로그에 색상이 적용되지 않습니다:
-
-```go
-func main() {
- // 로그 색상을 비활성화 합니다
- gin.DisableConsoleColor()
-
- // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
- // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-항상 로그의 색상이 적용됩니다:
-
-```go
-func main() {
- // 강제적으로 로그의 색상을 지정합니다
- gin.ForceConsoleColor()
-
- // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
- // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/cookie.md b/content/ko-kr/docs/examples/cookie.md
deleted file mode 100644
index b2baf5db8..000000000
--- a/content/ko-kr/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "쿠키의 설정 및 가져오기"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/ko-kr/docs/examples/custom-http-config.md b/content/ko-kr/docs/examples/custom-http-config.md
deleted file mode 100644
index d73de58af..000000000
--- a/content/ko-kr/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "HTTP 구성 사용자 정의"
-draft: false
----
-
-아래와 같이 직접 `http.ListenAndServe()` 를 사용하세요:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-혹은
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/ko-kr/docs/examples/custom-log-format.md b/content/ko-kr/docs/examples/custom-log-format.md
deleted file mode 100644
index 80513f959..000000000
--- a/content/ko-kr/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "로그 파일 사용자 정의"
-draft: false
----
-
-예제:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter 미들웨어는 gin.DefaultWriter에 로그를 작성합니다.
- // 기본값 gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // 사용자 정의 형식
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**출력 예제**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/ko-kr/docs/examples/custom-middleware.md b/content/ko-kr/docs/examples/custom-middleware.md
deleted file mode 100644
index 9c2afe1ea..000000000
--- a/content/ko-kr/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "커스텀 미들웨어"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // 샘플 변수 설정
- c.Set("example", "12345")
-
- // Request 이전
-
- c.Next()
-
- // Request 이후
- latency := time.Since(t)
- log.Print(latency)
-
- // 송신할 상태 코드에 접근
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // 출력내용: "12345"
- log.Println(example)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
-
diff --git a/content/ko-kr/docs/examples/custom-validators.md b/content/ko-kr/docs/examples/custom-validators.md
deleted file mode 100644
index 84899c543..000000000
--- a/content/ko-kr/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: "커스텀 유효성 검사"
-draft: false
----
-
-커스텀 유효성 검사를 사용 할 수도있습니다. [예제 코드](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations)를 확인하세요.
-
-```go
-package main
-
-import (
- "net/http"
- "reflect"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking은 유효성 검사 후 바인딩 된 데이터를 갖습니다.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-func bookableDate(
- v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
- field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
-) bool {
- if date, ok := field.Interface().(time.Time); ok {
- today := time.Now()
- if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
-{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
-```
-
-[구조체 레벨 유효성 검사](https://github.com/go-playground/validator/releases/tag/v8.7)도 이 방법으로 설정 할 수 있습니다.
-[struct-lvl-validation 예제](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations)를 보며 더 많은 것을 배울 수 있습니다.
diff --git a/content/ko-kr/docs/examples/define-format-for-the-log-of-routes.md b/content/ko-kr/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 1210c602e..000000000
--- a/content/ko-kr/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "라우트의 로그 형식을 정의"
-draft: false
----
-
-라우트의 기본 로그는 다음과 같습니다:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-만약 로그 형식을 정의 하려면(JSON, 키-값 형식, 그 이외의 형식 등), `gin.DebugPrintRouteFunc`를 사용하여 정의할 수 있습니다.
-아래의 예제는 모든 라우트에 대해 표준 로그 패키지를 사용하고 있지만, 필요에 따라 적절한 다른 도구를 사용하는 것도 가능합니다.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // 서버가 실행 되고 http://0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run()
-}
-```
diff --git a/content/ko-kr/docs/examples/goroutines-inside-a-middleware.md b/content/ko-kr/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index d5277d4e3..000000000
--- a/content/ko-kr/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "미들웨어 내부의 Go루틴"
-draft: false
----
-
-미들웨어 혹은 핸들러 내부에서 새로운 Go루틴을 시작하려면, 기존의 context를 **사용해서는 안됩니다.** 읽기 전용으로 복사해서 사용해야 합니다.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // Go루틴 내부에서 사용하기 위한 복사본을 작성합니다.
- cCp := c.Copy()
- go func() {
- // time.Sleep()를 사용하여 장시간(5초) 작업을 시뮬레이션 합니다.
- time.Sleep(5 * time.Second)
-
- // 중요! 복사된 context인 "cCp"를 사용하세요.
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // time.Sleep()를 사용하여 장시간(5초) 작업을 시뮬레이션 합니다.
- time.Sleep(5 * time.Second)
-
- // Go루틴을 사용하지 않는다면, context를 복사할 필요가 없습니다.
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/graceful-restart-or-stop.md b/content/ko-kr/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index f314cb948..000000000
--- a/content/ko-kr/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Graceful 재시작과 정지"
-draft: false
----
-
-웹 서버를 graceful 재시작 혹은 정지를 하고 싶습니까?
-이 작업을 하기 위한 몇 가지 방법이 있습니다.
-
-[fvbock/endless](https://github.com/fvbock/endless)를 사용하여 기본 `ListenAndServe`를 바꿀 수 있습니다. 자세한 내용은 이슈 [#296](https://github.com/gin-gonic/gin/issues/296)를 참조하세요.
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-endless의 대안은 다음과 같습니다:
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-만약 Go 1.8을 사용한다면, 이 라이브러리를 사용할 필요가 없습니다! Graceful 종료를 위해 http.Server에 포함되어 있는 [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) 메소드를 사용할 것을 검토해보세요. 자세한 내용은 Gin의 [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) 예제에서 확인해 주세요.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // 서비스 접속
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // 5초의 타임아웃으로 인해 인터럽트 신호가 서버를 정상종료 할 때까지 기다립니다.
- quit := make(chan os.Signal, 1)
- // kill (파라미터 없음) 기본값으로 syscanll.SIGTERM를 보냅니다
- // kill -2 는 syscall.SIGINT를 보냅니다
- // kill -9 는 syscall.SIGKILL를 보내지만 캐치할수 없으므로, 추가할 필요가 없습니다.
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // 5초의 타임아웃으로 ctx.Done()을 캐치합니다.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/ko-kr/docs/examples/grouping-routes.md b/content/ko-kr/docs/examples/grouping-routes.md
deleted file mode 100644
index 36e77973b..000000000
--- a/content/ko-kr/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "라우트 그룹화"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // v1 그룹
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // v2 그룹
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/html-rendering.md b/content/ko-kr/docs/examples/html-rendering.md
deleted file mode 100644
index 858da069b..000000000
--- a/content/ko-kr/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML 랜더링"
-draft: false
----
-
-LoadHTMLGlob() 혹은 LoadHTMLFiles()를 사용합니다.
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-다른 디렉토리에 있는 동일한 이름의 템플릿을 사용할 경우
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### 커스텀 템플릿 렌더링 엔진
-
-독자적인 HTML 템플릿 렌더링 엔진을 사용하는 것도 가능합니다.
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### 커스텀 구분자
-
-구분자를 사용자 정의하여 사용할 수도 있습니다.
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### 커스텀 템플릿 기능
-
-자세한 내용은 [예제 코드](https://github.com/gin-gonic/examples/tree/master/template)를 확인하세요.
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-결과:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/ko-kr/docs/examples/http-method.md b/content/ko-kr/docs/examples/http-method.md
deleted file mode 100644
index c139b839f..000000000
--- a/content/ko-kr/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "HTTP 메소드 사용"
-draft: false
----
-
-```go
-func main() {
- // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
- // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // 환경변수에 PORT가 지정되어 있지 않는 경우
- // 기본값으로 8080 포트를 사용합니다.
- router.Run()
- // router.Run(":3000") 와 같이 하드코딩으로 포트를 지정 할 수 있습니다.
-}
-```
diff --git a/content/ko-kr/docs/examples/http2-server-push.md b/content/ko-kr/docs/examples/http2-server-push.md
deleted file mode 100644
index ec44bfba8..000000000
--- a/content/ko-kr/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 서버 푸시"
-draft: false
----
-
-http.Pusher는 **go1.8 이상**에서만 지원됩니다. 자세한 정보는 [Go언어 블로그](https://blog.golang.org/h2push)에서 확인하세요.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // 서버 푸시를 위해 pusher.Push()를 사용합니다
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // 서버가 실행 되고 https://127.0.0.1:8080 에서 요청을 기다립니다.
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/ko-kr/docs/examples/jsonp.md b/content/ko-kr/docs/examples/jsonp.md
deleted file mode 100644
index dfc434acc..000000000
--- a/content/ko-kr/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-JSONP를 사용하여 다른 도메인의 서버에 요청하고 데이터를 받아올 수 있습니다. 조회 매개변수 콜백이 존재하는 경우 응답 본문에 콜백을 추가하세요.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback은 x입니다
- // 출력내용 : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/map-as-querystring-or-postform.md b/content/ko-kr/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index b7bb2adcb..000000000
--- a/content/ko-kr/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "쿼리 문자열 혹은 POST 폼의 파라미터에 매핑"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/ko-kr/docs/examples/multipart-urlencoded-binding.md b/content/ko-kr/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 10fb44370..000000000
--- a/content/ko-kr/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded 바인딩"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // 명시적으로 바인딩을 정의하여 multipart form을 바인딩 할 수 있습니다:
- // c.ShouldBindWith(&form, binding.Form)
- // 혹은 ShouldBind 메소드를 사용하여 간단하게 자동으로 바인딩을 할 수 있습니다:
- var form LoginForm
- // 이 경우에는 자동으로 적절한 바인딩이 선택 됩니다
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-다음과 같이 테스트 할 수 있습니다:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/ko-kr/docs/examples/multipart-urlencoded-form.md b/content/ko-kr/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 366ad38b3..000000000
--- a/content/ko-kr/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded 양식"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/ko-kr/docs/examples/multiple-template.md b/content/ko-kr/docs/examples/multiple-template.md
deleted file mode 100644
index b301e06b3..000000000
--- a/content/ko-kr/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "다중 템플릿"
-draft: false
----
-
-Gin은 기본적으로 하나의 html.Template만 사용하도록 허용합니다. Go 1.6의 `block template`와 같은 기능을 사용 하려면 [다중 템플릿 렌더(multitemplate)](https://github.com/gin-contrib/multitemplate)를 확인하세요.
diff --git a/content/ko-kr/docs/examples/only-bind-query-string.md b/content/ko-kr/docs/examples/only-bind-query-string.md
deleted file mode 100644
index b611a6462..000000000
--- a/content/ko-kr/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "쿼리 문자열만 바인딩하기"
-draft: false
----
-
-`ShouldBindQuery` 함수는 POST 데이터가 아닌 쿼리 파라미터만 바인딩 합니다. [자세한 정보](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017)를 확인 하세요.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/ko-kr/docs/examples/param-in-path.md b/content/ko-kr/docs/examples/param-in-path.md
deleted file mode 100644
index 5056093c1..000000000
--- a/content/ko-kr/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "경로를 포함한 파라미터"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // 이 핸들러는 /user/john와 매칭되지만 /user/ 또는 /user와는 매칭되지 않습니다.
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // 하지만, 이것은 /user/john/ 뿐만 아니라 /user/john/send와도 매칭됩니다.
- // /user/john와 매칭되는 라우터가 없다면, /user/john/로 리다이렉트 됩니다.
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/pure-json.md b/content/ko-kr/docs/examples/pure-json.md
deleted file mode 100644
index c79d58e67..000000000
--- a/content/ko-kr/docs/examples/pure-json.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-일반적으로 JSON은 `<`와 같은 HTML문자를 `\u003c`처럼 유니코드로 변환 합니다.
-만약 이러한 문자를 그대로 인코딩 하려면 PureJSON을 사용하세요.
-이 기능은 Go 1.6 이하에서는 사용할 수 없습니다.
-
-```go
-func main() {
- r := gin.Default()
-
- // 유니코드 엔티티 반환
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // 리터럴 문자 반환
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/query-and-post-form.md b/content/ko-kr/docs/examples/query-and-post-form.md
deleted file mode 100644
index b75a62fe5..000000000
--- a/content/ko-kr/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "POST 양식 쿼리"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/ko-kr/docs/examples/querystring-param.md b/content/ko-kr/docs/examples/querystring-param.md
deleted file mode 100644
index 929fd362b..000000000
--- a/content/ko-kr/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "쿼리 문자열 파라미터"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // 쿼리 문자열 파라미터는 기존의 Request객체를 사용하여 분석 됩니다.
- // 이 URL과 일치하는 요청에 대해 응답합니다: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname")의 단축어
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/redirects.md b/content/ko-kr/docs/examples/redirects.md
deleted file mode 100644
index 7953fb2fd..000000000
--- a/content/ko-kr/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "리디렉션"
-draft: false
----
-
-HTTP 리다이렉트 하는 것은 간단합니다. 내부와 외부위치를 모두 지원합니다.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-라우터 리다이렉트를 실행하려면, 아래와 같이 `HandleContext`를 사용하세요.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/ko-kr/docs/examples/rendering.md b/content/ko-kr/docs/examples/rendering.md
deleted file mode 100644
index 01ed56122..000000000
--- a/content/ko-kr/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf 랜더링"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H은 map[string]interface{} 타입입니다.
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // 구조체도 사용할 수 있습니다.
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // msg.Name은 JSON에서 "user"가 됩니다.
- // 출력내용 : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // protobuf의 정의는 testdata/protoexample 파일에 작성되어 있습니다.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // 데이터는 응답(response)시에 이진 데이터가 됩니다.
- // protobuf로 직렬화된 protoexample.Test가 출력됩니다.
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/run-multiple-service.md b/content/ko-kr/docs/examples/run-multiple-service.md
deleted file mode 100644
index 9d3640c3b..000000000
--- a/content/ko-kr/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "여러 개의 서비스를 실행하기"
-draft: false
----
-
-이 [질문](https://github.com/gin-gonic/gin/issues/346)을 보고, 다음 예제를 실행해 보세요:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/ko-kr/docs/examples/secure-json.md b/content/ko-kr/docs/examples/secure-json.md
deleted file mode 100644
index d5ab5e628..000000000
--- a/content/ko-kr/docs/examples/secure-json.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-json 하이재킹을 방지하기 위해 SecureJSON를 사용합니다.
-주어진 구조체가 배열인 경우, 기본적으로 `"while(1),"` 이 응답 본문에 포함 됩니다.
-
-```go
-func main() {
- r := gin.Default()
-
- // 자체적인 보안 json 접두사를 사용할 수도 있습니다.
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // 출력내용 : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/security-headers.md b/content/ko-kr/docs/examples/security-headers.md
deleted file mode 100644
index cd308b6d5..000000000
--- a/content/ko-kr/docs/examples/security-headers.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "보안 헤더"
-draft: false
----
-
-일반적인 보안 취약점으로부터 웹 애플리케이션을 보호하려면 보안 헤더를 사용하는 것이 중요합니다. 이 예에서는 Gin 애플리케이션에 보안 헤더를 추가하는 방법과 호스트 헤더 인젝션 관련 공격(SSRF, 오픈 리디렉션)을 방지하는 방법을 설명합니다.
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-`curl` 로 테스트할 수 있습니다:
-
-
-```bash
-// 헤더 확인
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// 호스트 헤더 주입 확인
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/ko-kr/docs/examples/serving-data-from-reader.md b/content/ko-kr/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index 62c880b69..000000000
--- a/content/ko-kr/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Reader로 데이터 반환"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/serving-static-files.md b/content/ko-kr/docs/examples/serving-static-files.md
deleted file mode 100644
index 34038711b..000000000
--- a/content/ko-kr/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "정적 파일 반환"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/support-lets-encrypt.md b/content/ko-kr/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index 504f527ac..000000000
--- a/content/ko-kr/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Let's Encrypt 지원"
-draft: false
----
-
-한 줄의 LetsEncrypt HTTPS 서버의 샘플입니다.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-autocert 관리자의 커스텀 예제.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/ko-kr/docs/examples/upload-file/_index.md b/content/ko-kr/docs/examples/upload-file/_index.md
deleted file mode 100644
index 54188ba21..000000000
--- a/content/ko-kr/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "파일 업로드"
-draft: false
----
-
-이 장에는 파일 업로드 API 사용법이 있습니다.
diff --git a/content/ko-kr/docs/examples/upload-file/multiple-file.md b/content/ko-kr/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index e1c64aea7..000000000
--- a/content/ko-kr/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "여러 파일"
-draft: false
----
-
-자세한 내용은 [예제 코드](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple)를 확인하세요.
-
-```go
-func main() {
- router := gin.Default()
- // 멀티파트 폼에 대한 최저 메모리 설정 (기본값 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // 멀티파트 폼
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // 특정 경로(dst)에 파일을 업로드 합니다.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-`curl` 사용방법:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/ko-kr/docs/examples/upload-file/single-file.md b/content/ko-kr/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 38bf32eba..000000000
--- a/content/ko-kr/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "단일 파일"
-draft: false
----
-
-이슈 [#774](https://github.com/gin-gonic/gin/issues/774) 혹은 자세한 [예제 코드](https://github.com/gin-gonic/examples/tree/master/upload-file/single)를 확인하세요.
-
-`file.Filename`은 **신뢰할 수 없습니다.**. MDN의 [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives)과 이슈 [#1693](https://github.com/gin-gonic/gin/issues/1693)를 참조하세요.
-
-> 파일 이름은 항상 선택 사항이며 응용 프로그램에서 맹목적으로 사용해서는 안됩니다. 경로 정보를 제거하고 서버 파일 시스템 규칙으로 변환해야합니다.
-
-```go
-func main() {
- router := gin.Default()
- // 멀티파트 폼에 대한 최저 메모리 설정 (기본값 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // 단일 파일
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // 특정 경로(dst)에 파일을 업로드 합니다.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-`curl` 사용방법:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/ko-kr/docs/examples/using-basicauth-middleware.md b/content/ko-kr/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 934a7f769..000000000
--- a/content/ko-kr/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "기본인증(BasicAuth) 미들웨어 사용하기"
-draft: false
----
-
-```go
-// 개인정보 샘플 데이터
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // gin.BasicAuth() 미들웨어를 사용하여 그룹화 하기
- // gin.Accounts는 map[string]string 타입입니다.
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // 엔드포인트 /admin/secrets
- // "localhost:8080/admin/secrets"로 접근합니다.
- authorized.GET("/secrets", func(c *gin.Context) {
- // BasicAuth 미들웨어를 통해 유저를 설정합니다.
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/examples/using-middleware.md b/content/ko-kr/docs/examples/using-middleware.md
deleted file mode 100644
index ee033e2c2..000000000
--- a/content/ko-kr/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "미들웨어를 사용하기"
-draft: false
----
-
-```go
-func main() {
- // 기본 미들웨어를 포함하지 않는 라우터를 작성합니다.
- r := gin.New()
-
- // Global middleware
- // GIN_MODE=release로 하더라도 Logger 미들웨어는 gin.DefaultWriter에 로그를 기록합니다.
- // 기본값 gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery 미들웨어는 panic이 발생하면 500 에러를 씁니다.
- r.Use(gin.Recovery())
-
- // 각 라우트 당 원하는만큼 미들웨어를 추가 할 수 있습니다.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // 권한 그룹
- // authorized := r.Group("/", AuthRequired())
- // 다음과 동일합니다:
- authorized := r.Group("/")
- // 그룹별로 미들웨어를 사용할 수 있습니다!
- // 이 경우 "authorized"그룹에서만 사용자 정의 생성된 AuthRequired() 미들웨어를 사용합니다.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // 중첩 그룹
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
- r.Run(":8080")
-}
-```
-
diff --git a/content/ko-kr/docs/examples/without-middleware.md b/content/ko-kr/docs/examples/without-middleware.md
deleted file mode 100644
index b95ea10f4..000000000
--- a/content/ko-kr/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "기본 미들웨어를 포함하지 않는 방법"
-draft: false
----
-
-이렇게 사용하세요.
-
-```go
-r := gin.New()
-```
-
-아래와 같은 코드는 기본 미들웨어를 포함합니다.
-
-```go
-// 로거와 복구 미들웨어가 이미 연결된 상태
-r := gin.Default()
-```
diff --git a/content/ko-kr/docs/examples/write-log.md b/content/ko-kr/docs/examples/write-log.md
deleted file mode 100644
index 29ec5aaa0..000000000
--- a/content/ko-kr/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "로그 파일을 작성하는 방법"
-draft: false
----
-
-```go
-func main() {
- // 로그 파일 작성에는 색상이 필요 없으므로, 콘솔 색상을 비활성화 합니다.
- gin.DisableConsoleColor()
-
- // 파일에 로그를 작성합니다.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // 파일과 동시에 콘솔에도 로그를 작성해야 하는 경우에는 다음과 같은 코드를 사용하세요.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ko-kr/docs/faq/_index.md b/content/ko-kr/docs/faq/_index.md
deleted file mode 100644
index 9ca05977e..000000000
--- a/content/ko-kr/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: GitHub 이슈탭에서 자주 받는 질문을 정리하기.
-
diff --git a/content/ko-kr/docs/features/_index.md b/content/ko-kr/docs/features/_index.md
deleted file mode 100644
index dbe4e034f..000000000
--- a/content/ko-kr/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "기능"
-draft: false
-weight: 4
----
-
-## Gin v1 안정판의 기능:
-
-- 동적 메모리 할당이 0인 라우터
-
-- 가장 빠른 http 라우터와 프레임워크
-
-- 단위 테스트가 갖추어져 있음
-
-- 엄격한 테스트를 통과함 (Battle tested)
-
-- API는 고정되어 있고, 새로운 버전이 기존의 코드에 영향을 끼치지 않음
diff --git a/content/ko-kr/docs/introduction/_index.md b/content/ko-kr/docs/introduction/_index.md
deleted file mode 100644
index c7cc25163..000000000
--- a/content/ko-kr/docs/introduction/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "소개"
-draft: false
-weight: 1
----
-
-Gin은 Go로 작성된 웹 프레임워크입니다. Martini와 비슷한 API를 제공하지만, [httprouter](https://github.com/julienschmidt/httprouter) 덕분에 최대 40배 빠른 성능을 제공합니다. 만약 뛰어난 생산성과 퍼포먼스가 필요하다면, Gin을 좋아하게 될 것입니다.
-
-이 페이지에서는 Gin이 무엇이고 또 어떤 문제를 해결하도록 도와주는지, 그리고 어떻게 당신의 프로젝트를 도와주는지 알아보겠습니다.
-
-혹은, 당신의 프로젝트가 Gin을 사용할 준비가 되어 있다면, [퀵 스타트](https://gin-gonic.com/docs/quickstart/)를 봐주세요.
-
-## 기능
-
-### 빠른 속도
-
-기수 트리(Radix tree)를 기반으로 한 라우팅, 적은 메모리 사용량. 리플렉션 미사용. 예측 가능한 API 성능.
-
-### 미들웨어 지원
-
-수신된 HTTP 요청은 미들웨어 체인과 최종적인 액션을 통한 처리가 가능합니다.
-예: Logger, 인증, GZIP 압축, DB에 메시지 전송.
-
-### 충돌방지
-
-Gin은 HTTP 요청 중 발생한 `panic` 을 감지하고 `recover` 할 수 있습니다. 따라서, 서버는 항상 이용 가능한 상태를 유지합니다. 예를 들면, 발생한 `panic` 을 Sentry에 보고 하는 것도 가능합니다!
-
-### JSON 유효성 검사
-
-Gin은 JSON 형식의 요청에 대해 파싱과 유효성 검사를 할 수 있습니다. 예를 들어, 필수값이 들어 있는지 확인 할 수 있습니다.
-
-### 라우팅 그룹화
-
-라우팅 경로를 더 좋게 정리 할 수 있습니다. 인증이 필요한지 아닌지, 버전이 다른 API인지 아닌지 등... 또한, 성능 저하 없이 그룹을 무제한 중첩할 수 있습니다.
-
-### 에러관리
-
-Gin은 HTTP 요청 중에 발생한 모든 에러를 수집하는 편리한 방법을 제공합니다. 이것을 통해 미들웨어는 로그 파일, 데이터베이스에 기록하고 네트워크를 통해 전송할 수 있습니다.
-
-### 렌더링 기능 내장
-
-Gin은 JSON, XML, HTML 렌더링을 위한 사용하기 쉬운 API를 제공합니다.
-
-### 확장 가능
-
-아주 쉽게 새로운 미들웨어를 만들 수 있습니다. 샘플 코드를 확인하세요.
-
diff --git a/content/ko-kr/docs/jsoniter/_index.md b/content/ko-kr/docs/jsoniter/_index.md
deleted file mode 100644
index e31960011..000000000
--- a/content/ko-kr/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## [jsoniter](https://github.com/json-iterator/go)로 빌드하기
-
-Gin은 기본적인 json 패키지로 `encoding/json` 를 사용하지만, 다른 태그로 빌드 하기 위해 [jsoniter](https://github.com/json-iterator/go)를 사용하는 것도 가능합니다.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/ko-kr/docs/quickstart/_index.md b/content/ko-kr/docs/quickstart/_index.md
deleted file mode 100644
index 3fe43137b..000000000
--- a/content/ko-kr/docs/quickstart/_index.md
+++ /dev/null
@@ -1,101 +0,0 @@
----
-title: "퀵 스타트"
-draft: false
-weight: 2
----
-
-이 퀵 스타트에서는, 코드에서 통찰력을 얻고 어떤 식으로 할지 배울 것입니다:
-
-## 요구사항
-
-- Go 1.16 이상
-
-## 설치
-
-Gin을 설치 하기 위해서는, Go 언어를 설치 한 후 Go workspace를 설정해야 합니다.
-
-1. 다운로드 후 설치하기:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. 사용할 코드 내에서 임포트 하기:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (선택사항) `net/http`를 임포트 하기. `http.StatusOK` 와 같은 상수를 사용하는 경우 필요합니다.
-
-```go
-import "net/http"
-```
-
-### [Govendor](https://github.com/kardianos/govendor)같은 vendor 툴을 사용하기
-
-1. `go get` 을 이용하여 govendor 설치
-
-```sh
-$ go get github.com/kardianos/govendor
-```
-2. 프로젝트 디렉토리를 작성 한 후 `cd` 로 이동하기
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-3. Vendor로 프로젝트를 초기화 한 후 Gin을 추가하기
-
-```sh
-$ govendor init
-$ govendor fetch github.com/gin-gonic/gin@v1.3
-```
-
-4. 시작 템플릿을 프로젝트에 복사하기
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-5. 프로젝트 실행하기
-
-```sh
-$ go run main.go
-```
-
-## 시작하기
-
-> Go 코드 작성 및 실행 방법을 잘 모르시나요? [여기를 클릭하세요](https://golang.org/doc/code.html).
-
-우선 `example.go` 파일을 작성합니다.:
-
-```sh
-# 이후 코드는 example.go 파일에 작성합니다.
-$ touch example.go
-```
-
-다음으로, 아래의 코드를 `example.go` 에 작성합니다.:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
-}
-```
-
-그리고, `go run example.go` 로 코드를 실행합니다.:
-
-```sh
-# example.go 를 실행 후, 0.0.0.0:8080/ping 에 접속합니다.
-$ go run example.go
-```
diff --git a/content/ko-kr/docs/testing/_index.md b/content/ko-kr/docs/testing/_index.md
deleted file mode 100644
index 3771fee31..000000000
--- a/content/ko-kr/docs/testing/_index.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: "테스트"
-draft: false
-weight: 7
----
-
-## Gin의 테스트 케이스를 작성하는 방법은?
-
-`net/http/httptest` 패키지 는 HTTP테스트에 선호되는 방법입니다.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-위 예제의 테스트 코드:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
-
-
-
diff --git a/content/ko-kr/docs/users/_index.md b/content/ko-kr/docs/users/_index.md
deleted file mode 100644
index 96c12ee36..000000000
--- a/content/ko-kr/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Gin을 사용하는 곳"
-draft: false
-weight: 8
----
-
-##### [Gin](https://github.com/gin-gonic/gin) 웹 프레임워크를 사용한 멋진 프로젝트 목록:
-
-* [gorush](https://github.com/appleboy/gorush): Go로 작성된 푸시 알림 서버.
-
-* [fnproject](https://github.com/fnproject/fn): 클라우드에 구애받지 않는 컨테이너 네이티브 서버리스 플렛폼.
-
-* [photoprism](https://github.com/photoprism/photoprism): Go와 Google TensorFlow 기반의 개인 사진관리.
-
-* [krakend](https://github.com/devopsfaith/krakend): 미들웨어가 포함된 고성능 API 게이트웨이.
-
-* [picfit](https://github.com/thoas/picfit): Go로 작성된 이미지 크기 조절 서버.
-
-* [gotify](https://github.com/gotify/server): 웹 소켓 당 실시간으로 메시지를 주고받는 간단한 서버.
-
-* [cds](https://github.com/ovh/cds): 엔터프라이즈급 지속적인 서비스 제공(CD) 및 DevOps 자동화 오픈 소스 플랫폼.
diff --git a/content/pt/_index.html b/content/pt/_index.html
deleted file mode 100644
index 3dd3e758a..000000000
--- a/content/pt/_index.html
+++ /dev/null
@@ -1,82 +0,0 @@
-+++
-title = "A Abstração de Web Gin"
-linkTitle = "A Abstração de Web Gin"
-+++
-
-{{< blocks/cover title="A Abstração de Web Gin" image_anchor="top" height="full" color="orange">}}
-
- {{< /blocks/cover>}}
-
-
- {{% blocks/lead color="white" %}}
-
- **O que é a Gin?**
-
- A Gin é uma abstração de web escrita em Golang.
-
- Ela apresenta uma API parecida com a Martini, mais com desempenho mais alto, 40 vezes mais rápida do que a Martini.
-
- Se precisas de desempenho e produtividade, amarás a Gin.
-
- {{% /blocks/lead %}}
-
- {{< blocks/section color="light">}}
-
- {{% blocks/feature icon="fa fa-tachometer-alt" title="Fast" %}}
- Árvore de roteamento baseada em Radix, pouco consumo de memória. Sem reflexão. Desempenho de API previsível.
- {{% /blocks/feature %}}
-
- {{% blocks/feature icon="fa fa-bars" title="Suporte à Intermediário" %}}
- Uma requisição futura de HTTP pode ser manipulada por uma cadeia de intermediários e pela ação final.
- Por exemplo: Registador, Autorização, GZIP e finalmente publicar uma mensagem na BD.
- {{% /blocks/feature %}}
-
- {{% blocks/feature icon="fa fa-life-ring" title="Livre de Avaria" %}}
- A Gin pode capturar um pânico que ocorreu durante uma requisição de HTTP e recuperá-lo. Deste maneira, o teu
- servidor estará sempre disponível. Também é possível informar este pânico ao Sentry por exemplo!
- {{% /blocks/feature %}}
-
- {{< /blocks/section>}}
-
- {{< blocks/section color="white">}}
-
- {{% blocks/feature icon="fa fa-check-circle" title="Validação de JSON" %}}
- A Gin pode analisar e validar o JSON de uma requisição, verificando, por exemplo, a existência de valores
- obrigatórios.
- {{% /blocks/feature %}}
-
- {{% blocks/feature icon="fa fa-users-cog" title="Agrupamento de Rotas" %}}
- Organiza melhor as tuas rotas. Autorização obrigatória vs não obrigatória, diferentes versões de API. Além
- disso, grupos podem ser encaixados infinitamente sem a degradação do desempenho.
- {{% /blocks/feature %}}
-
-
- {{% blocks/feature icon="fa fa-briefcase" title="Gestão de Erro" %}}
- A Gin fornece uma maneira conveniente de coletar todos os erros ocorridos durante uma requisição de HTTP.
- Eventualmente, o intermediário pode escrevê-los em um ficheiro de registo, em uma base de dados e enviá-los
- através da rede.
- {{% /blocks/feature %}}
-
- {{< /blocks/section>}}
-
- {{< blocks/section color="info">}}
-
- {{% blocks/feature icon="fa fa-images" title="Interpretação Embutida" %}}
- A Gin fornece uma API fácil de utilizar para interpretação de JSON, XML e HTML.
- {{% /blocks/feature %}}
-
- {{% blocks/feature icon="fa fa-code" title="Extensível" %}}
- A criação de um novo intermediário é tão fácil, apenas consulte o código de exemplo.
- {{% /blocks/feature %}}
-
- {{< /blocks/section>}}
diff --git a/content/pt/blog/_index.md b/content/pt/blog/_index.md
deleted file mode 100644
index 92284e573..000000000
--- a/content/pt/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blogue"
-linkTitle: "Blogue"
-menu:
- main:
- weight: 30
----
-
-
-Esta é a seção **blogue**. Ela tem duas categorias: Novidades e Lançamentos.
-
-Os ficheiros nestes diretórios serão listados em ordem cronológica inversa.
-
diff --git a/content/pt/blog/news/_index.md b/content/pt/blog/news/_index.md
deleted file mode 100644
index 676125395..000000000
--- a/content/pt/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Novidades"
-linkTitle: "Novidades"
-weight: 20
----
-
-
diff --git a/content/pt/blog/releases/_index.md b/content/pt/blog/releases/_index.md
deleted file mode 100644
index af32c7186..000000000
--- a/content/pt/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Lançamentos"
-linkTitle: "Lançamentos"
-weight: 20
----
-
-
diff --git a/content/pt/docs/_index.md b/content/pt/docs/_index.md
deleted file mode 100644
index 93ced4fff..000000000
--- a/content/pt/docs/_index.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Documentação"
-linkTitle: "Documentação"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## O que é a Gin?
-
-A Gin é uma abstração de web escrita em Go (Golang). Ela apresenta uma API parecida com a Martini, mas com aumento de desempenho 40 vezes mais rápido do que a Martini. Se precisares de desempenho fantástico, sirva-te com algum Gin.
-
-## Como usar a Gin?
-
-Nós fornecemos [exemplos](https://github.com/gin-gonic/examples) de uso da API e listamos alguns [utilizadores de Gin](./users) conhecidos publicamente.
-
-## Como contribuir com a Gin?
-
-* Ajude as pessoas nos fóruns de discussão
-* Conte-nos as tuas histórias de sucesso usando a Gin
-* Conte-nos como podemos melhorar a Gin e ajude-nos a fazê-lo
-* Contribua para com um biblioteca existente
-
diff --git a/content/pt/docs/benchmarks/_index.md b/content/pt/docs/benchmarks/_index.md
deleted file mode 100644
index ee0d1c3f3..000000000
--- a/content/pt/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Analises Comparativas"
-draft: false
-weight: 3
----
-
-A Gin usa uma versão personalizada da [`HttpRouter`](https://github.com/julienschmidt/httprouter).
-
-[Consulte todos os analises comparativas](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md):
-
-| Nome da analise comparativa | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): Repetições Totais alcançadas em tempo constante, quanto mais alto, significa mais segurança do resultado.
-- (2): Duração de Uma Repetição (ns/op), quanto mais baixo, melhor.
-- (3): Amontoar Memória (B/op), quanto mais baixo, melhor.
-- (4): Alocações Média por Repetição (allocs/op), quanto mais baixo, melhor.
diff --git a/content/pt/docs/deployment/_index.md b/content/pt/docs/deployment/_index.md
deleted file mode 100644
index 23c4d1abe..000000000
--- a/content/pt/docs/deployment/_index.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Implementação em Produção"
-draft: false
-weight: 6
----
-
-Os projetos de Gin podem ser implementados em produção facilmente em qualquer provedor da nuvem.
-
-## [Koyeb](https://www.koyeb.com)
-
-A Koyeb é uma plataforma sem servidor amistosa ao programador para implementar as aplicações localmente em produção com a implementação baseada em Git, encriptação de TLS, auto-escalamento nativo, rede de fio global, e malha de rede de serviço e descoberta embutido.
-
-Siga o [guia da Koyeb para implementar em produção os teus projetos de Gin](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
-
-## [Qovery](https://www.qovery.com)
-
-A Qovery fornece hospedagem de nuvem gratuita com bases de dados, SSL, uma CDN global e implementações em produção automáticas com a Git.
-
-Siga o [guia da Qovery para implementar o teu projeto de Gin em produção](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
-
-## [Render](https://render.com)
-
-A Render é uma plataforma da nuvem moderna que oferece suporte nativo para a Go, SSL completamente administrado, bases de dados, implementações em produção com tempo de inatividade zero, HTTP/2, e suporte a websocket.
-
-Siga o [guia da Render para implementação de projetos de Gin em produção](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-A GAE tem duas maneiras de implementar aplicações de Go em produção. O ambiente padrão é mais fácil de usar mas menos personalizável e impedi [syscalls](https://github.com/gin-gonic/gin/issues/1639) por razões de segurança. O ambiente flexível pode executar qualquer abstração ou biblioteca.
-
-Saiba mais e escolha o teu ambiente preferido na [Go sobre a Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/pt/docs/examples/_index.md b/content/pt/docs/examples/_index.md
deleted file mode 100644
index da7fd042f..000000000
--- a/content/pt/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Exemplos"
-draft: false
-weight: 6
----
-
-A seção lista o uso da API.
diff --git a/content/pt/docs/examples/ascii-json.md b/content/pt/docs/examples/ascii-json.md
deleted file mode 100644
index 6c531ff92..000000000
--- a/content/pt/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Usando a `AsciiJSON` para gerar JSON de apenas ASCII com caracteres que não são ASCII escapados:
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // resultará em : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Ouvir e servir na 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/bind-body-into-dirrerent-structs.md b/content/pt/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index 1e342054d..000000000
--- a/content/pt/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: "Tentar vincular o corpo à diferentes estruturas"
-draft: false
----
-
-Os métodos normais para vincular o corpo da requisição consumem a `c.Request.Body` e não podem ser chamados várias vezes:
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // Este c.ShouldBind consume o c.Request.Body e não pode ser reutilizado.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Um erro sempre acontecerá por aqui porque c.Request.Body agora é EOF
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-Para isto, podes usar `c.ShouldBindBodyWith`:
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // Isto lê c.Request.Body e armazena o resultado no contexto.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Neste momento, ela reutiliza o corpo armazenado no contexto.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // E pode aceitar outros formatos
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWidth` armazena o corpo no contexto antes da vinculação. Isto tem um ligeiro impacto no desempenho, então não deverias usar este método se estás bem para chamar a vinculação imediatamente.
-
-* Esta funcionalidade é apenas necessário para alguns formatos -- `JSON`, `XML`, `MsgPack`, `ProtoBuf`. Para outros formatos, `Query`, `Form`, `FormPost`, `FormMultipart`, podem ser chamados pela `c.ShouldBind()` várias vezes sem qualquer dado para o desempenho (consulte a [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/pt/docs/examples/bind-form-data-request-with-custom-struct.md b/content/pt/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 6e56a42c5..000000000
--- a/content/pt/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "Vincular a requisição de dados de formulário com a estrutura personalizada"
-draft: false
----
-
-O seguinte exemplo usando estrutura personalizada:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Usando o comando `url` e resultado do comando:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/pt/docs/examples/bind-html-checkbox.md b/content/pt/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 0593b92d9..000000000
--- a/content/pt/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Vincular caixas de confirmações de HTML"
-draft: false
----
-
-Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092):
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-resultado:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/pt/docs/examples/bind-query-or-post.md b/content/pt/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 685e002e8..000000000
--- a/content/pt/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Vincular a sequência de caracteres de consulta ou publicar dados"
-draft: false
----
-
-Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292):
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // Se `GET`, apenas o motor de vinculação de `Form` (`query`) é usada.
- // Se `POST`, primeiro conferi o `content-type` por `JSON` ou `XML`, depois use o `Form` (`form-data`).
- // Consulte mais na https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Testá-lo com:
-
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/pt/docs/examples/bind-single-binary-with-template.md b/content/pt/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 28cda90d2..000000000
--- a/content/pt/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Construir um único binário com modelos de marcação"
-draft: false
----
-## Usar o pacote de terceiro
-
-Tu podes usar o pacote de terceiro para construir um servidor em um único binário contendo os modelos de marcação usando o [go-assets](https://github.com/jessevdk/go-assets):
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate carrega os modelos de marcação fixado pelo go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-Consulte um exemplo completo no diretório [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/content/pt/docs/examples/bind-uri.md b/content/pt/docs/examples/bind-uri.md
deleted file mode 100644
index c6b64022a..000000000
--- a/content/pt/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Vincular a URI"
-draft: false
----
-
-Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/846):
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Testá-lo com:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/pt/docs/examples/binding-and-validation.md b/content/pt/docs/examples/binding-and-validation.md
deleted file mode 100644
index 573a9fb75..000000000
--- a/content/pt/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,119 +0,0 @@
----
-title: "Vinculação de Modelo e Validação"
-draft: false
----
-
-Para vincular uma corpo de requisição à um tipo, use a vinculação de modelo. Nós atualmente suportamos a vinculação de JSON, XML, YAML e valores de formulário padrão (foo=bar&boo=baz).
-
-A Gin usa [**`go-playground/validator/v10`**](https://github.com/go-playground/validator) para a validação. Consulte a documentação completa sobre o uso de marcadores [nesta ligação](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Nota que precisas de definir o marcador da vinculação correspondente em todos os campos que quiseres vincular. Por exemplo, quando estiveres a vincular a partir de JSON, defina `json:"fieldname"`.
-
-Além disto, a Gin fornece dois conjuntos de métodos para vinculação:
-
-- **Tipo** - Deve vincular
- - **Métodos** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Comportamento** - Estes métodos usam `MustBindWith` nos bastidores. Se houver um erro de vinculação, a requisição é abortada com `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. Isto define o código do estado da resposta para 400 e o cabeçalho `Content-Type` é definido para `text/plain; charset=utf-8`. Nota que se tentares definir o código da resposta depois disto, resultará em um aviso `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. Se desejas ter maior controlo sobre o comportamento, considere usar o método equivalente `ShouldBind`.
-- **Tipo** - Deveria vincular
- - **Métodos** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Comportamento** - Estes métodos usam `ShouldBindWith` nos bastidores. Se houver um erro de vinculação, o erro é retornado e é responsabilidade do programador manipular a requisição e o erro apropriadamente.
-
-Quando estiveres o método `Bind`, a Gin tenta inferir o vinculador dependendo do cabeçalho do `Content-Type`. Se estiveres certo daquilo que estiveres a vincular, podes usar `MustBindWith` ou `ShouldBindWith`.
-
-Tu podes também especificar que os campos específicos são obrigatório. Se um campo for decorado com `binding:"required"` e tiver um valor vazio quando estiveres a vincular, um erro será retornado:
-
-```go
-// Vinculando a partir de JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Exemplo para vincular o JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Exemplo pra vincular o XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Exemplo para vincular um formulário de HTML (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // Isto inferirá qual vinculador usar dependendo do cabeçalho do `content-type`.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Ouvir e servir na 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Requisição Simples
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Saltar a Validação
-
-Quando estiveres a executar o exemplo de cima usando o comando `curl` de cima, isto retorna erro. Porque o exemplo usa `binding:"required"` para `Password`. Se usares `binding:"-"` para `Password`, então este não retornará erro quando estiveres a executar o exemplo de cima novamente.
diff --git a/content/pt/docs/examples/controlling-log-output-coloring.md b/content/pt/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 6fd71a8df..000000000
--- a/content/pt/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Controlando a Colorização da Saída de Registo"
-draft: false
----
-
-Por padrão, a saída de registos na consola deveria ser colorida dependendo do TTY detetado.
-
-Nunca colorir os registos:
-
-```go
-func main() {
- // Desativar a cor do registo
- gin.DisableConsoleColor()
-
- // Criar um roteador de Gin com o intermediário padrão:
- // registador e intermediário de recuperação (livre de avaria)
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Sempre colorir os registos:
-
-```go
-func main() {
- // Forçar a cor do registo
- gin.ForceConsoleColor()
-
- // Criar um roteador de Gin com o intermediário padrão:
- // registador e intermediário de recuperação (livre de avaria)
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/cookie.md b/content/pt/docs/examples/cookie.md
deleted file mode 100644
index 36536e3dc..000000000
--- a/content/pt/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Definir e Recuperar um Cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/pt/docs/examples/custom-http-config.md b/content/pt/docs/examples/custom-http-config.md
deleted file mode 100644
index 20462e80e..000000000
--- a/content/pt/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "Configuração de HTTP Personalizada"
-draft: false
----
-
-Usar o `http.ListenAndServe()` diretamente, desta maneira:
-
-```go
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-
-ou
-
-```go
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/pt/docs/examples/custom-log-format.md b/content/pt/docs/examples/custom-log-format.md
deleted file mode 100644
index ddb156218..000000000
--- a/content/pt/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,39 +0,0 @@
----
-title: "Ficheiro de Registo Personalizado"
-draft: false
----
-
-Por exemplo:
-
-```go
-func main() {
- router := gin.New()
- // O intermediário `LoggerWithFormatter` escreverá os registos para `gin.DefaultWriter`
- // Por padrão `gin.DefaultWriter = os.Stdout`
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // o teu formato personalizado
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Saída de Exemplo**:
-
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/pt/docs/examples/custom-middleware.md b/content/pt/docs/examples/custom-middleware.md
deleted file mode 100644
index 9f8adede5..000000000
--- a/content/pt/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Intermediário Personalizado"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Definir a variável de exemplo
- c.Set("example", "12345")
-
- // antes da requisição
-
- c.Next()
-
- // depois da requisição
- latency := time.Since(t)
- log.Print(latency)
-
- // acessar o estado que estamos a enviar
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // imprimiria: "12345"
- log.Println(example)
- })
-
- // Ouvir e servir na 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/pt/docs/examples/custom-validators.md b/content/pt/docs/examples/custom-validators.md
deleted file mode 100644
index b9360a0b6..000000000
--- a/content/pt/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Validadores Personalizados"
-draft: false
----
-
-Também é possível registar validadores personalizados. Consulte o [código de exemplo](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations):
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// `Booking` (contratação) contém dados vinculados e validados.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-As [validações a nível estrutural](https://github.com/go-playground/validator/releases/tag/v8.7) também podem ser registadas desta maneira.
-Consulte o [exemplo `struct-lvl-validation`](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) para saber mais.
diff --git a/content/pt/docs/examples/define-format-for-the-log-of-routes.md b/content/pt/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 03bcc56ea..000000000
--- a/content/pt/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "Definir o Formato para o Registo de Rotas"
-draft: false
----
-
-O registo padrão de rotas é:
-
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-Se quiseres registar esta informação em dado formato (por exemplo, JSON, valores de chave ou outra coisa), então podes definir este formato com `gin.DebugPrintRouteFunc`.
-No exemplo abaixo, registamos todas as rotas com o pacote de registo padrão mas podes usar uma outra ferramenta de registo adequada as tuas necessidades:
-
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Ouvir e servir na http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/pt/docs/examples/goroutines-inside-a-middleware.md b/content/pt/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 0b5c16c46..000000000
--- a/content/pt/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Rotinas de Go dentro dum Intermediário"
-draft: false
----
-
-Quando começares novas rotinas de Go dentro dum intermediário ou manipulador, **NÃO DEVERIAS** usar o contexto original dentro dele, tens que usar uma cópia de apenas leitura.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // criar cópia a ser usada dentro da rotina de go
- cCp := c.Copy()
- go func() {
- // simular uma tarefa longa com time.Sleep(). 5 segundos
- time.Sleep(5 * time.Second)
-
- // nota que estás a usar o contexto copiado "cCp", IMPORTANTE
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simular uma tarefa longa com time.Sleep(). 5 segundos
- time.Sleep(5 * time.Second)
-
- // já que não estamos a usar uma rotina de Go, não temos que copiar o contexto
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // ouvir e servir na porta 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/graceful-restart-or-stop.md b/content/pt/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 25facd28e..000000000
--- a/content/pt/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,86 +0,0 @@
----
-title: "Reinicialização ou Interrupção Graciosa"
-draft: false
----
-
-Queres reiniciar ou parar graciosamente o teu servidor de web?
-Existem algumas maneiras disto poder ser feito.
-
-Nós podemos usar o [fvbock/endless](https://github.com/fvbock/endless) para substituir o `ListenAndServe` padrão. Consulte a questão [#296](https://github.com/gin-gonic/gin/issues/296) por mais detalhes:
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-Uma alternativa ao `endless`:
-
-* [`manners`](https://github.com/braintree/manners): Um servidor de HTTP de Go delicado que desliga graciosamente.
-* [`graceful`](https://github.com/tylerb/graceful): é uma pacote de Go que ativa a paragem graciosa dum servidor de `http.Handler`.
-* [`grace`](https://github.com/facebookgo/grace): reinicialização graciosa & implementação de produção de tempo de inatividade zero para servidores de Go.
-
-Se usas a Go 1.8, podes não precisar de usar esta biblioteca! Considere usar o método [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) embutido da `http.Server` para paragens graciosas. Consulte o exemplo [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) completo com a Gin:
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // servir conexões ou conexões de serviço
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // espere pelo sinal de interrupção para parar graciosamente o
- // servidor com uma pausa de 5 segundos.
- quit := make(chan os.Signal, 1)
- // "kill" padrão (sem parâmetro) envia "syscanll.SIGTERM"
- // "kill -2" é "syscall.SIGINT"
- // "kill -9" é "syscall.SIGKILL" mas não pode ser capturado,
- // então não precisas adicioná-lo
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // capturar ctx.Done(). pausa de 5 segundos.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/pt/docs/examples/grouping-routes.md b/content/pt/docs/examples/grouping-routes.md
deleted file mode 100644
index 0b5dc634d..000000000
--- a/content/pt/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Agrupamento de Rotas"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // grupo simples: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // grupo simples: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/html-rendering.md b/content/pt/docs/examples/html-rendering.md
deleted file mode 100644
index 98d309d02..000000000
--- a/content/pt/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,151 +0,0 @@
----
-title: "Interpretação do HTML"
-draft: false
----
-
-Usando `LoadHTMLGlob()` ou `LoadHTMLFiles()`:
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Usando modelos de marcação com o mesmo nome em diretórios diferentes:
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Interpretador de Modelo de Marcação Personalizado
-
-Tu podes também usar o teu próprio interpretador de modelo de marcação de HTML:
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Delimitadores Personalizados
-
-Tu podes usar delimitadores personalizados:
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Funções de Modelo de Marcação Personalizado
-
-Consulte os pormenores do [código de exemplo](https://github.com/gin-gonic/examples/tree/master/template):
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Resultado:
-
-```sh
-Date: 2017/07/01
-```
diff --git a/content/pt/docs/examples/http-method.md b/content/pt/docs/examples/http-method.md
deleted file mode 100644
index 88ef8980d..000000000
--- a/content/pt/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Usando o Método de HTTP"
-draft: false
----
-
-```go
-func main() {
- // criar um roteador de gin com intermediário padrão:
- // intermediário registador e de recuperação (livre de avaria)
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // por padrão serve na :8080 a menos que uma
- // variável de ambiente PORT fosse definida.
- router.Run()
- // router.Run(":3000") para uma porta definida manualmente
-}
-```
diff --git a/content/pt/docs/examples/http2-server-push.md b/content/pt/docs/examples/http2-server-push.md
deleted file mode 100644
index c0d038685..000000000
--- a/content/pt/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "Impulso do Servidor de HTTP2"
-draft: false
----
-
-`http.Pusher` é suportado apenas versão **1.8+** de Go. Consulte o [blogue da Golang](https://blog.golang.org/h2push) por informação detalhada:
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // usar pusher.Push() para impulsionar o servidor.
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // ouvir e servir no https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/pt/docs/examples/jsonp.md b/content/pt/docs/examples/jsonp.md
deleted file mode 100644
index 07a3dc4db..000000000
--- a/content/pt/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Usando JSONP para pedir dados dum servidor num domínio diferente. Adicione a função de resposta ao corpo da resposta se a função de resposta do parâmetro da consulta existir:
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- // função de resposta é x
- // resultará em: x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // ouvir e servir no 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/map-as-querystring-or-postform.md b/content/pt/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index b405229ca..000000000
--- a/content/pt/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Mapa como Sequência de Caracteres de Consulta ou Parâmetros de Formulário de Publicação"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/pt/docs/examples/multipart-urlencoded-binding.md b/content/pt/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 92aed40cb..000000000
--- a/content/pt/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,42 +0,0 @@
----
-title: "Vínculo de Várias Partes / URL Codificada"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // tu podes vincular formulário de várias partes com declaração
- // de vínculo explícita: c.ShouldBindWith(&form, binding.Form)
- // ou podes simplesmente usar auto-vinculação com método ShouldBind
- var form LoginForm
- // neste caso o vínculo apropriado será selecionado automaticamente
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Teste-o coom:
-
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/pt/docs/examples/multipart-urlencoded-form.md b/content/pt/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index ed0fb72b2..000000000
--- a/content/pt/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Formulário de Várias Partes / URL Codificada"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/pt/docs/examples/multiple-template.md b/content/pt/docs/examples/multiple-template.md
deleted file mode 100644
index e14d1aa2c..000000000
--- a/content/pt/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Vários Modelos de Marcação"
-draft: false
----
-
-A Gin permite por padrão usar apenas um `html.Template`. Consulte [um interpretador de vários modelos de marcação] para usares funcionalidades como `block template` de Go 1.6.
diff --git a/content/pt/docs/examples/only-bind-query-string.md b/content/pt/docs/examples/only-bind-query-string.md
deleted file mode 100644
index 384011d47..000000000
--- a/content/pt/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Vincular Apenas a Sequência de Caracteres de Consulta"
-draft: false
----
-
-A função `ShouldBindQuery` apenas vincula os parâmetros de consulta e não os dados da publicação. Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017):
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/pt/docs/examples/param-in-path.md b/content/pt/docs/examples/param-in-path.md
deleted file mode 100644
index e3b21b75d..000000000
--- a/content/pt/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "Parâmetros no Caminho"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // este manipulador corresponderá ao "/user/john"
- // mas não corresponderá ao "/user/" ou ao "/user"
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // no entanto, este corresponderá o "/user/john/"
- // e também "/user/john/send"
- // se nenhuma outra rota corresponder ao "/user/john",
- // redirecionará ao "/user/john"
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/pure-json.md b/content/pt/docs/examples/pure-json.md
deleted file mode 100644
index 52ec5b46a..000000000
--- a/content/pt/docs/examples/pure-json.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-Normalmente, a JSON substitui os caracteres de HTML especiais com suas entidades de unicode, por exemplo, `<` torna-se `\u003c`. Se quiseres codificar tais caracteres literalmente, podes usar PureJSON. Esta funcionalidade está indisponível na Go 1.6 para baixo:
-
-```go
-func main() {
- r := gin.Default()
-
- // servir as entidades de unicode
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // servir os caracteres literais
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // ouvir e servir no 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/query-and-post-form.md b/content/pt/docs/examples/query-and-post-form.md
deleted file mode 100644
index d50f68258..000000000
--- a/content/pt/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Consulta e Formulário de Publicação"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/pt/docs/examples/querystring-param.md b/content/pt/docs/examples/querystring-param.md
deleted file mode 100644
index 3f1dc302f..000000000
--- a/content/pt/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: "Parâmetros da Sequência de Consulta"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // os parâmetros da sequência de caracteres de consulta
- // são analisados usando objeto de requisição subjacente existente.
- // a requisição responde à uma URL correspondendo a:
- // /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // atalho para c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/redirects.md b/content/pt/docs/examples/redirects.md
deleted file mode 100644
index 5212c4000..000000000
--- a/content/pt/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirecionamentos"
-draft: false
----
-
-Emitir um redirecionamento de HTTP é fácil. Ambas localizações internas e externas são suportadas:
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Emitir um redirecionamento de HTTP a partir do `POST`. Consulte o problema: [#444](https://github.com/gin-gonic/gin/issues/444):
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Emitir um redirecionamento de roteador, use `HandleContext` como abaixo:
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/pt/docs/examples/rendering.md b/content/pt/docs/examples/rendering.md
deleted file mode 100644
index d5ca12bd1..000000000
--- a/content/pt/docs/examples/rendering.md
+++ /dev/null
@@ -1,55 +0,0 @@
----
-title: "Interpretação de XML/JSON/YAML/ProtoBuf"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // "gin.H" é um atalho para "map[string]interface{}"
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // também podes usar uma estrutura
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // nota que "msg.Name" torna-se "user" na JSON
- // resultará em: {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // a definição específica do protobuf
- // está escrita no ficheiro "testdata/protoexample"
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // nota que os dados tornam-se dados binários na resposta
- // resultará em dados serializados de "protobuf" de "protoexample.Test"
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // ouvir e servir na 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/run-multiple-service.md b/content/pt/docs/examples/run-multiple-service.md
deleted file mode 100644
index 49375e3f8..000000000
--- a/content/pt/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Executar Vários Serviços"
-draft: false
----
-
-Consulte a [questão](https://github.com/gin-gonic/gin/issues/346) e tente seguinte exemplo:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/pt/docs/examples/secure-json.md b/content/pt/docs/examples/secure-json.md
deleted file mode 100644
index 7a4cc3372..000000000
--- a/content/pt/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-Usando SecureJSON para impedir o sequestro do JSON. Por padrão adiciona `"while(1)"` no início do corpo da resposta se a dada estrutura for valores de arranjo:
-
-```go
-func main() {
- r := gin.Default()
-
- // podes também usar o teu próprio prefixo de JSON seguro
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // resultará em: while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // ouvir e servir no 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/security-headers.md b/content/pt/docs/examples/security-headers.md
deleted file mode 100644
index 15f75f58d..000000000
--- a/content/pt/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "Cabeçalhos de segurança"
-draft: false
----
-
-É importante utilizar cabeçalhos de segurança para proteger a sua aplicação Web de vulnerabilidades de segurança comuns. Este exemplo mostra-lhe como adicionar cabeçalhos de segurança à sua aplicação Gin e também como evitar ataques relacionados com a injeção de cabeçalhos de anfitrião (SSRF, Open Redirection).
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-Pode testá-lo através de `curl`:
-
-```bash
-// Verificar cabeçalhos
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// Verificar a injeção do cabeçalho do anfitrião
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/pt/docs/examples/serving-data-from-reader.md b/content/pt/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index af79e780a..000000000
--- a/content/pt/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Servir os Dados a partir do Leitor"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/serving-static-files.md b/content/pt/docs/examples/serving-static-files.md
deleted file mode 100644
index 4d1917cb8..000000000
--- a/content/pt/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "Servir os Ficheiros Estáticos"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // ouvir e servir no 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/support-lets-encrypt.md b/content/pt/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index 63209f021..000000000
--- a/content/pt/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Suportar Let's Encrypt"
-draft: false
----
-
-Exemplo para servidores de HTTP LetsEncrypt de uma linha:
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // manipulador de ping
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-Exemplo para o gestor de certificado automático personalizado:
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // manipulador de ping
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/pt/docs/examples/upload-file/_index.md b/content/pt/docs/examples/upload-file/_index.md
deleted file mode 100644
index 6f1e84de4..000000000
--- a/content/pt/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Carregar Ficheiros"
-draft: false
----
-
-A seção lista o uso da API de carregamento de ficheiro.
diff --git a/content/pt/docs/examples/upload-file/multiple-file.md b/content/pt/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 26050147d..000000000
--- a/content/pt/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Vários Ficheiros"
-draft: false
----
-
-Consulte o [código de exemplo](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple) detalhado.
-
-```go
-func main() {
- router := gin.Default()
- // definir um limite de memória mais baixa
- // para formulários de várias partes (o padrão é 32MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // formulário de várias partes
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // carregar o ficheiro para um destino específico.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-Como testar com a `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/pt/docs/examples/upload-file/single-file.md b/content/pt/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 7314c09e6..000000000
--- a/content/pt/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Único Ficheiro"
-draft: false
----
-
-Consulte a questão [#774](https://github.com/gin-gonic/gin/issues/774) e [exemplo de código](https://github.com/gin-gonic/examples/tree/master/upload-file/single) detalhado.
-
-`file.Filename` **NÃO DEVERIA** ser confiado. Consulte [`Content-Disposition` na MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) e a questão [#1693](https://github.com/gin-gonic/gin/issues/1693).
-
-> O nome do ficheiro sempre é opcional e não deve ser usado cegamente pela aplicação: a informação do caminho deveria ser esvaziada, e a conversão para as regras do sistema de ficheiro do servidor deveria ser feita.
-
-```go
-func main() {
- router := gin.Default()
- // definir um limite de memória mais baixa
- // para formulários de várias partes (o padrão é 32MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // único ficheiro
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // carregar o ficheiro para um destino específico.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-Como testar com a `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/pt/docs/examples/using-basicauth-middleware.md b/content/pt/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 13ffc5602..000000000
--- a/content/pt/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Usar o Intermediário de BasicAuth"
-draft: false
----
-
-```go
-// simular alguns dados privados
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // grupo usando intermediário de "gin.BasicAuth()"
- // "gin.Accounts" é um atalho para "map[string]string"
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // o destino /admin/secrets
- // alcança "localhost:8080/admin/secrets"
- authorized.GET("/secrets", func(c *gin.Context) {
- // receber utilizador, foi definido pelo intermediário de BasicAuth
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // ouvir e servir no 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/pt/docs/examples/using-middleware.md b/content/pt/docs/examples/using-middleware.md
deleted file mode 100644
index db9a819d9..000000000
--- a/content/pt/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "Usar Intermediário"
-draft: false
----
-
-```go
-func main() {
- // criar um roteador sem nenhum intermediário por padrão
- r := gin.New()
-
- // intermediário global
- // intermediário registador escreverá os registos ao "gin.DefaultWriter",
- // mesmo se definires com "GIN_MODE=release".
- // por padrão "gin.DefaultWriter = os.Stdout"
- r.Use(gin.Logger())
-
- // intermediário de recuperação recupera de quaisquer pânicos e
- // escreve um 500 se ouve um.
- r.Use(gin.Recovery())
-
- // intermediário por rota, podes adicionar tanto quanto desejares.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // grupo de autorização
- // authorized := r.Group("/", AuthRequired())
- // exatamente o mesmo que:
- authorized := r.Group("/")
- // intermediário por grupo! neste caso usamos o intermediário
- // "AuthRequired()" criado de maneira personalizada só no
- // grupo "authorized".
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // grupo encaixado
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // ouvir e servir no 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/pt/docs/examples/without-middleware.md b/content/pt/docs/examples/without-middleware.md
deleted file mode 100644
index 8f3256f70..000000000
--- a/content/pt/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Sem Intermediário por Padrão"
-draft: false
----
-
-Use:
-
-```go
-r := gin.New()
-```
-
-Ao invés de:
-
-```go
-// predefine com o intermediário registador e de recuperação já em anexo.
-r := gin.Default()
-```
diff --git a/content/pt/docs/examples/write-log.md b/content/pt/docs/examples/write-log.md
deleted file mode 100644
index d43b5e597..000000000
--- a/content/pt/docs/examples/write-log.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Como Escrever Ficheiro de Registo"
-draft: false
----
-
-```go
-func main() {
- // desativar a cor da consola, não precisas de cor de consola quando
- // escreves registos em um ficheiro.
- gin.DisableConsoleColor()
-
- // registando num ficheiro.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // use o seguinte código se precisares de escrever registos num ficheiro e
- // imprimir na consola ao mesmo tempo.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/pt/docs/faq/_index.md b/content/pt/docs/faq/_index.md
deleted file mode 100644
index 389d1432a..000000000
--- a/content/pt/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: record some frequently asked question from GitHub Issue tab.
-
diff --git a/content/pt/docs/features/_index.md b/content/pt/docs/features/_index.md
deleted file mode 100644
index bbd47ea0d..000000000
--- a/content/pt/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Características"
-draft: false
-weight: 4
----
-
-## Gin v1 estável apresenta:
-
-- Roteador de alocação zero.
-
-- Continua o roteador de HTTP e abstração mais rápida. Desde o roteamento à escrita.
-
-- Conjunto completo de testes unitários.
-
-- Testado em combate.
-
-- API imóvel, novos lançamentos não quebrarão o teu código.
diff --git a/content/pt/docs/introduction/_index.md b/content/pt/docs/introduction/_index.md
deleted file mode 100644
index e5c490425..000000000
--- a/content/pt/docs/introduction/_index.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "Introdução"
-draft: false
-weight: 1
----
-
-A Gin é uma abstração de web escrita em Go (Golang). Ela apresenta uma API parecida com a Martini com desempenho muito melhor, acima de 40 vezes mais rápida graças ao [`httprouter`](https://github.com/julienschmidt/httprouter). Se precisares de desempenho e excelente produtividade, amarás a Gin.
-
-Nesta seção introduziremos o que a Gin é, quais problemas soluciona, e como pode ajudar o teu projeto.
-
-Ou, se estiveres pronto para usar a Gin no teu projeto, visite a [Introdução rápida](https://gin-gonic.com/docs/quickstart/).
-
-## Características
-
-### Rápida
-
-Roteamento baseado na árvore de Radix, pegada de memória pequena. Sem reflexão. Desempenho de API previsível.
-
-### Suporte à Intermediário
-
-Uma requisição de HTTP de chegada pode ser manipulada por uma série de intermediários e a ação final. Por exemplo: Registador, Autorização, GZIP e finalmente publicar uma mensagem na Base de Dados.
-
-### Livre de Avaria
-
-A Gin pode capturar um pânico ocorrido durante uma requisição de HTTP e recuperá-lo. Desta maneira, o teu servidor sempre estará disponível. Como exemplo - também é possível reportar este pânico para a Sentry!
-
-### Validação de JSON
-
-A Gin pode analisar e validar o JSON de uma requisição - por exemplo, verificando a existência de valores obrigatórios.
-
-### Agrupamento de Rotas
-
-Organiza melhor as tuas rotas. Autorização obrigatória vs não obrigatória, diferentes versões de API... Além destes, os grupos podem ser encaixados ilimitadamente sem degradar o desempenho.
-
-### Gestão de Erro
-
-A Gin fornece uma maneira conveniente de reunir todos os erros ocorridos durante uma requisição de HTTP. Eventualmente, um intermediário pode escrevê-los para um ficheiro de registo, para uma base de dados e envia-los através da rede.
-
-### Interpretação Embutida
-
-A Gin fornece uma API fácil de usar para interpretação de JSON, XML e HTML.
-
-### Extensível
-
-A criação de um intermediário é tão fácil, apenas consulte os códigos de exemplo.
-
diff --git a/content/pt/docs/jsoniter/_index.md b/content/pt/docs/jsoniter/_index.md
deleted file mode 100644
index 666e2a837..000000000
--- a/content/pt/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-### Construir com o [`jsoniter`](https://github.com/json-iterator/go)
-
-A Gin usa o módulo `encoding/json` como pacote de JSON padrão mas podes mudar para o [`jsoniter`](https://github.com/json-iterator/go) ao construir a partir de outros marcadores:
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/pt/docs/quickstart/_index.md b/content/pt/docs/quickstart/_index.md
deleted file mode 100644
index dcf21f27d..000000000
--- a/content/pt/docs/quickstart/_index.md
+++ /dev/null
@@ -1,87 +0,0 @@
----
-title: "Introdução Rápida"
-draft: false
-weight: 2
----
-
-Nesta introdução rápida, recolheremos entendimentos a partir de segmentos de código e aprenderemos a como:
-
-## Requisitos
-
-- Go 1.13 ou superior
-
-## Instalação
-
-Para instalar o pacote de Gin, precisas de instalar a Go e definir a tua área de trabalho de Go primeiro:
-
-1. Descarregue e instale-o:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. Importe-o no teu código:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (Opcional) Importe `net/http`. Isto é obrigatório para por exemplo se estiveres a usar constantes tais como `http.StatusOk`:
-
-```go
-import "net/http"
-```
-
-1. Crie a pasta do teu projeto e entre dentro dela com `cd`:
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. Copie um modelo de partida dentro do teu projeto:
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. Execute o teu projeto:
-
-```sh
-$ go run main.go
-```
-
-## Começar
-
-> Inseguro de como escrever e executar o código de Go? [Clique nesta ligação](https://golang.org/doc/code.html).
-
-Primeiro, crie um ficheiro chamado `example.go`:
-
-```sh
-# presuma os seguintes códigos no ficheiro `example.go`
-$ touch example.go
-```
-
-A seguir, coloque o seguinte código dentro do `example.go`:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // oiça e sirva na `0.0.0.0:8080`
-}
-```
-
-E, podes executar o código através de `go run example.go`:
-
-```sh
-# execute `example.go` e visite `0.0.0.0:8080/ping` no navegador
-$ go run example.go
-```
diff --git a/content/pt/docs/testing/_index.md b/content/pt/docs/testing/_index.md
deleted file mode 100644
index 645d71baf..000000000
--- a/content/pt/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "Testagem"
-draft: false
-weight: 7
----
-
-## Como escrever um caso de teste para Gin?
-
-O pacote `net/http/httptest` é a maneira preferível para testagem de HTTP:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-O teste para exemplo de código acima:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/pt/docs/users/_index.md b/content/pt/docs/users/_index.md
deleted file mode 100644
index d3994a534..000000000
--- a/content/pt/docs/users/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Utilizadores"
-draft: false
-weight: 8
----
-
-#### Uma lista projetos incríveis usando a abstração de web [Gin](https://github.com/gin-gonic/gin):
-
-* [gorush](https://github.com/appleboy/gorush): Um servidor de empurrar notificação escrito em Go.
-
-* [fnproject](https://github.com/fnproject/fn): O contentor nativo, plataforma sem servidor agnóstica da nuvem.
-
-* [photoprism](https://github.com/photoprism/photoprism): Gestão de fotografia pessoal alimentada pela Go e Google TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Porta de API radicalmente otimizada com intermediários.
-
-* [picfit](https://github.com/thoas/picfit): Um servidor de redimensionamento de imagem escrito em Go.
-
-* [gotify](https://github.com/gotify/server): Um servidor simples para transmissão e recebimento de mensagens em tempo real por tomada da web (web socket).
-
-* [cds](https://github.com/ovh/cds): Entrega Contínuas de Nível Empresarial e Plataforma de Código Aberto de Automação de DevOps.
-
-* [go-admin](https://github.com/go-admin-team/go-admin): É uma abstração de fundo central baseada na Go.
diff --git a/content/pt/featured-background.jpg b/content/pt/featured-background.jpg
deleted file mode 100644
index 8bb8a4cc6..000000000
Binary files a/content/pt/featured-background.jpg and /dev/null differ
diff --git a/content/pt/search.md b/content/pt/search.md
deleted file mode 100644
index 874676cdf..000000000
--- a/content/pt/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Resultados da Pesquisa
-layout: search
----
-
diff --git a/content/ru/_index.html b/content/ru/_index.html
deleted file mode 100644
index 85c54d4f2..000000000
--- a/content/ru/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-
}}">
- Подробнее
-
-
- Скачать
-
-
Самый быстрый полнофункциональный веб-фреймворк для Go. Кристально чистый.
-
- {{< blocks/link-down color="info" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**Что такое Gin?**
-
-Gin - это веб-фреймворк, написанный на языке Golang.
-
-В нем реализован API, похожий на Martini, но производительность в 40 раз выше, чем у Martini.
-
-Если вам нужна производительность и продуктивность, Gin вам понравится.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Fast" %}}
-Маршрутизация на основе радиксного дерева, малый объем памяти. Никаких отражений. Предсказуемая производительность API.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Middleware support" %}}
-Входящий HTTP-запрос может быть обработан цепочкой промежуточного ПО (Middleware) и конечным действием.
-Например: Логгер, авторизация, GZIP и, наконец, публикация сообщения в БД.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash-free" %}}
-Gin может поймать панику, возникшую во время HTTP-запроса, и восстановить ее. Таким образом, ваш сервер будет всегда доступен. Также можно сообщить об этой панике, например, в Sentry!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON validation" %}}
-Gin может анализировать и проверять JSON-запросы, например, на наличие необходимых значений.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Routes grouping" %}}
-Организуйте свои маршруты лучше. Требуется и не требуется авторизация, разные версии API. Кроме того, группы могут быть вложены бесконечно без снижения производительности.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Error management" %}}
-Gin обеспечивает удобный способ сбора всех ошибок, возникших во время HTTP-запроса. В конечном итоге промежуточное ПО (Middleware) может записывать их в файл журнала, в базу данных и отправлять через сеть.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Rendering built-in" %}}
-Gin предоставляет простой в использовании API для рендеринга JSON, XML и HTML.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Extendable" %}}
-Создать новое промежуточное программное обеспечение очень просто, просто посмотрите пример кода.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/ru/blog/_index.md b/content/ru/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/ru/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/ru/blog/news/_index.md b/content/ru/blog/news/_index.md
deleted file mode 100644
index 3263a4f27..000000000
--- a/content/ru/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Новости"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/ru/blog/releases/_index.md b/content/ru/blog/releases/_index.md
deleted file mode 100644
index c045332fe..000000000
--- a/content/ru/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Релизы"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/ru/docs/_index.md b/content/ru/docs/_index.md
deleted file mode 100644
index b9876b7d0..000000000
--- a/content/ru/docs/_index.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-название: "Документация"
-linkTitle: "Документация"
-вес: 20
-menu:
- main:
- вес: 20
----
-
-## Что такое Gin?
-
-Gin - это HTTP-веб-фреймворк, написанный на языке Go (Golang). В нем реализован API, похожий на Martini, но с производительностью в 40 раз выше, чем у Martini. Если вам нужна потрясающая производительность, купите себе Gin.
-
-## Как использовать Gin?
-
-Мы приводим [примеры] использования API (https://github.com/gin-gonic/examples) и список известных пользователей [Gin](./users).
-
-## Как внести свой вклад в развитие Gin?
-
-* Помогайте людям на дискуссионных форумах.
-* Расскажите нам о своих успехах в использовании Gin
-* Расскажите нам, как мы можем улучшить Gin, и помогите нам в этом.
-* Внести вклад в существующую библиотеку
-
diff --git a/content/ru/docs/benchmarks/_index.md b/content/ru/docs/benchmarks/_index.md
deleted file mode 100644
index c512f9258..000000000
--- a/content/ru/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Контрольные показатели"
-draft: false
-weight: 3
----
-
-Gin использует пользовательскую версию [HttpRouter](https://github.com/julienschmidt/httprouter).
-
-[Посмотреть все контрольные показатели](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): Общее количество повторений, достигнутое за постоянное время, большее количество означает более уверенный результат
-- (2): Длительность одного повторения (ns/op), меньше - лучше
-- (3): Память кучи (B/op), меньше - лучше
-- (4): Среднее количество выделений за повтор (allocs/op), ниже - лучше
diff --git a/content/ru/docs/deployment/_index.md b/content/ru/docs/deployment/_index.md
deleted file mode 100644
index ac691d84a..000000000
--- a/content/ru/docs/deployment/_index.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Deployment"
-draft: false
-weight: 6
----
-
-Проекты Gin могут быть легко развернуты на любом облачном провайдере.
-
-## [Koyeb](https://www.koyeb.com)
-
-Koyeb - это удобная для разработчиков бессерверная платформа для глобального развертывания приложений с развертыванием на основе git, шифрованием TLS, встроенным автомасштабированием, глобальной пограничной сетью и встроенным сервисом mesh & discovery.
-
-Следуйте руководству Koyeb [Guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
-
-## [Qovery](https://www.qovery.com)
-
-Qovery предоставляет бесплатный облачный хостинг с базами данных, SSL, глобальной CDN и автоматическим развертыванием с помощью Git.
-
-Следуйте руководству Qovery, чтобы [развернуть свой проект Gin](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
-
-## [Render](https://render.com)
-
-Render - это современная облачная платформа, которая предлагает встроенную поддержку Go, полностью управляемый SSL, базы данных, деплой с нулевым временем простоя, HTTP/2 и поддержку websocket.
-
-Следуйте рекомендациям Render [руководство по развертыванию проектов Gin](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-В GAE есть два способа развертывания Go-приложений. Стандартная среда проще в использовании, но менее настраиваема и не допускает [syscalls](https://github.com/gin-gonic/gin/issues/1639) по соображениям безопасности. В гибком окружении можно запускать любые фреймворки и библиотеки.
-
-Узнать больше и выбрать предпочтительную среду можно на сайте [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/ru/docs/examples/_index.md b/content/ru/docs/examples/_index.md
deleted file mode 100644
index df13529a2..000000000
--- a/content/ru/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-название: "Примеры"
-черновик: false
-вес: 6
----
-
-Раздел содержит список использования api.
diff --git a/content/ru/docs/examples/ascii-json.md b/content/ru/docs/examples/ascii-json.md
deleted file mode 100644
index 9eb014880..000000000
--- a/content/ru/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-название: "AsciiJSON"
-черновик: false
----
-
-Использование AsciiJSON для генерации ASCII-единственного JSON с экранированными не-ASCII символами.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/bind-body-into-dirrerent-structs.md b/content/ru/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index 008769777..000000000
--- a/content/ru/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-название: "Попытайтесь связать тело в разных структурах"
-draft: false
----
-
-Обычные методы для связывания тела запроса (request body) потребляют `c.Request.Body` и их
-не могут быть вызваны несколько раз.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Always an error is occurred by this because c.Request.Body is EOF now.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-Для этого можно использовать `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // At this time, it reuses body stored in the context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` сохраняет тело в контексте перед привязкой. Это
-небольшое влияние на производительность, поэтому не стоит использовать этот метод, если вы
-достаточно вызвать привязку сразу.
-* Эта возможность необходима только для некоторых форматов - `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. Для других форматов, `Query`, `Form`, `FormPost`, `FormMultipart`,
-могут быть вызваны `c.ShouldBind()` многократно без ущерба для
-производительности (см. [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/ru/docs/examples/bind-form-data-request-with-custom-struct.md b/content/ru/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 4567d90ee..000000000
--- a/content/ru/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-название: "Связывание запроса формы-данных с пользовательской структурой"
-черновик: false
----
-
-Следующий пример с использованием пользовательской структуры:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Результаты при использовании `curl`:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/ru/docs/examples/bind-html-checkbox.md b/content/ru/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 8950b1699..000000000
--- a/content/ru/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Привязка html-флажков"
-draft: false
----
-
-Смотрите [подробную информацию](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-```html
-
-```
-
-Результат:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/ru/docs/examples/bind-single-binary-with-template.md b/content/ru/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index a01a567c7..000000000
--- a/content/ru/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Создание единого бинарного файла с помощью шаблонов"
-draft: false
----
-## Использование стороннего пакета
-
-Вы можете использовать сторонний пакет для сборки сервера в единый бинарник, содержащий шаблоны, используя [go-assets](https://github.com/jessevdk/go-assets).
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate loads templates embedded by go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-Полный пример находится в каталоге [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/content/ru/docs/examples/bind-uri.md b/content/ru/docs/examples/bind-uri.md
deleted file mode 100644
index 654911691..000000000
--- a/content/ru/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-Заголовок: "Связывание Uri"
-draft: false
----
-
-Смотрите [подробную информацию](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err.Error()})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Тестирование:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/ru/docs/examples/binding-and-validation.md b/content/ru/docs/examples/binding-and-validation.md
deleted file mode 100644
index 2f7d35e62..000000000
--- a/content/ru/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-Заголовок: "Связывание и проверка моделей"
-черновик: false
----
-
-Чтобы привязать тело запроса к типу, используйте привязку к модели. В настоящее время мы поддерживаем привязку JSON, XML, YAML и стандартных значений формы (foo=bar&boo=baz).
-
-Для валидации Gin использует [**go-playground/validator/v10**](https://github.com/go-playground/validator). Ознакомьтесь с полной документацией по использованию тегов [здесь](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Обратите внимание, что вам необходимо установить соответствующий тег привязки для всех полей, которые вы хотите привязать. Например, при привязке из JSON установите `json: "fieldname"`.
-
-Кроме того, Gin предоставляет два набора методов для привязки:
-- **Type** - Must bind
- - **Методы** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Поведение** - Эти методы используют `MustBindWith` под капотом. Если произошла ошибка связывания, запрос прерывается с помощью `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. При этом код состояния ответа принимает значение 400, а заголовок `Content-Type` устанавливается на `text/plain; charset=utf-8`. Обратите внимание, что если вы попытаетесь установить код ответа после этого, то это приведет к предупреждению `[GIN-debug] [WARNING] Заголовки уже были записаны. Хотелось отменить код статуса 400 на 422`. Если вы хотите получить больший контроль над поведением, используйте эквивалентный метод `ShouldBind`.
-- **Тип** - Should bind
- - **Методы** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Поведение** - Эти методы используют `ShouldBindWith` под капотом. Если произошла ошибка связывания, возвращается ошибка, и разработчик обязан обработать запрос и ошибку соответствующим образом.
-
-При использовании Bind-метода Gin пытается определить связующее звено в зависимости от заголовка Content-Type. Если вы уверены, что именно вы связываете, вы можете использовать `MustBindWith` или `ShouldBindWith`.
-
-Вы также можете указать, что определенные поля являются обязательными. Если поле украшено `binding: "required"` и при привязке имеет пустое значение, будет возвращена ошибка.
-
-```go
-// Binding from JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Example for binding JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding a HTML form (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Пример запроса
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Пропустить валидацию
-
-При выполнении приведенного выше примера с помощью указанной выше команды `curl` возвращается ошибка. Потому что в примере используется `привязка: "required"` для `Password`. Если использовать `binding:"-"` для `Password`, то при повторном запуске приведенного выше примера ошибка не возникнет.
diff --git a/content/ru/docs/examples/controlling-log-output-coloring.md b/content/ru/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 248c10818..000000000
--- a/content/ru/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Управление раскраской вывода журнала"
-draft: false
----
-
-По умолчанию логи, выводимые на консоль, должны быть окрашены в зависимости от обнаруженного TTY.
-
-Никогда не окрашивать журналы:
-
-```go
-func main() {
- // Disable log's color
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Всегда окрашивайте журналы в разные цвета:
-
-```go
-func main() {
- // Force log's color
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/cookie.md b/content/ru/docs/examples/cookie.md
deleted file mode 100644
index 7cf85e3ca..000000000
--- a/content/ru/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-Название: "Установка и получение cookie"
-черновик: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/ru/docs/examples/custom-http-config.md b/content/ru/docs/examples/custom-http-config.md
deleted file mode 100644
index b6f84b975..000000000
--- a/content/ru/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-Название: "Пользовательская конфигурация HTTP"
-черновик: false
----
-
-Используйте `http.ListenAndServe()` напрямую, например, так:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-or
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/ru/docs/examples/custom-log-format.md b/content/ru/docs/examples/custom-log-format.md
deleted file mode 100644
index 00613371b..000000000
--- a/content/ru/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-Название: "Пользовательский файл журнала"
-черновик: false
----
-
-Например:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
- // By default gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // your custom format
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Образец вывода**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/ru/docs/examples/custom-middleware.md b/content/ru/docs/examples/custom-middleware.md
deleted file mode 100644
index 2ae281da3..000000000
--- a/content/ru/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-название: "Custom Middleware"
-черновик: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Set example variable
- c.Set("example", "12345")
-
- // before request
-
- c.Next()
-
- // after request
- latency := time.Since(t)
- log.Print(latency)
-
- // access the status we are sending
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // it would print: "12345"
- log.Println(example)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/ru/docs/examples/custom-validators.md b/content/ru/docs/examples/custom-validators.md
deleted file mode 100644
index 53790bf18..000000000
--- a/content/ru/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-название: "Пользовательские валидаторы"
-draft: false
----
-
-Также можно зарегистрировать пользовательские валидаторы. Смотрите [пример кода](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking contains binded and validated data.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-[Валидации уровня структуры](https://github.com/go-playground/validator/releases/tag/v8.7) также могут быть зарегистрированы таким образом.
-Смотрите пример [struct-lvl-validation](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations), чтобы узнать больше.
diff --git a/content/ru/docs/examples/define-format-for-the-log-of-routes.md b/content/ru/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 9941d3033..000000000
--- a/content/ru/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Определить формат для журнала маршрутов"
-draft: false
----
-
-
-По умолчанию журнал маршрутов имеет следующий вид:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-Если вы хотите записывать эту информацию в заданном формате (например, JSON, значения ключей или что-то еще), то вы можете определить этот формат с помощью `gin.DebugPrintRouteFunc`.
-В примере ниже мы ведем лог всех маршрутов с помощью стандартного пакета лога, но вы можете использовать другие инструменты лога, которые подходят для ваших нужд.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Listen and Server in http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/ru/docs/examples/goroutines-inside-a-middleware.md b/content/ru/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index da91a0ea4..000000000
--- a/content/ru/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-Заголовок: "Гороутины внутри промежуточного ПО"
-черновик: false
----
-
-При запуске новых Goroutines внутри промежуточного ПО или обработчика, вы **НЕ ДОЛЖНЫ** использовать оригинальный контекст внутри него, вы должны использовать копию, доступную только для чтения.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // create copy to be used inside the goroutine
- cCp := c.Copy()
- go func() {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // note that you are using the copied context "cCp", IMPORTANT
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // since we are NOT using a goroutine, we do not have to copy the context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/graceful-restart-or-stop.md b/content/ru/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 2f5caca7b..000000000
--- a/content/ru/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-Заголовок: "Благодатный перезапуск или остановка"
-черновик: false
----
-
-Вы хотите произвести плавный перезапуск или остановку вашего веб-сервера?
-Есть несколько способов сделать это.
-
-Мы можем использовать [fvbock/endless](https://github.com/fvbock/endless) для замены стандартного `ListenAndServe`. Более подробную информацию см. в выпуске [#296](https://github.com/gin-gonic/gin/issues/296).
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-Альтернатива бесконечности:
-
-* [manners](https://github.com/braintree/manners): Вежливый HTTP-сервер Go, который изящно завершает работу.
-* [graceful](https://github.com/tylerb/graceful): Graceful - это пакет Go, позволяющий изящно завершить работу сервера http.Handler.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy для Go-серверов.
-
-Если вы используете Go 1.8, возможно, вам не понадобится эта библиотека! Лучше используйте встроенный метод http.Server [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) для изящного завершения работы. Посмотрите полный пример [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) с gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router.Handler(),
- }
-
- go func() {
- // service connections
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Wait for interrupt signal to gracefully shutdown the server with
- // a timeout of 5 seconds.
- quit := make(chan os.Signal, 1)
- // kill (no param) default send syscall.SIGTERM
- // kill -2 is syscall.SIGINT
- // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // catching ctx.Done(). timeout of 5 seconds.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/ru/docs/examples/grouping-routes.md b/content/ru/docs/examples/grouping-routes.md
deleted file mode 100644
index 6e23d2e6a..000000000
--- a/content/ru/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-Заголовок: "Группировка маршрутов"
-черновик: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Simple group: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Simple group: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/html-rendering.md b/content/ru/docs/examples/html-rendering.md
deleted file mode 100644
index d489dda4e..000000000
--- a/content/ru/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-Заголовок: "HTML-рендеринг"
-draft: false
----
-
-Использование LoadHTMLGlob() или LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Использование шаблонов с одинаковыми именами в разных каталогах
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Пользовательский рендерер шаблонов
-
-Вы также можете использовать собственный рендерер html-шаблонов
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Пользовательские разделители
-
-Вы можете использовать пользовательские разделители
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Пользовательские функции шаблона
-
-Смотрите подробный [пример кода](https://github.com/gin-gonic/examples/tree/master/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/ru/docs/examples/http-method.md b/content/ru/docs/examples/http-method.md
deleted file mode 100644
index de7199323..000000000
--- a/content/ru/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-Заголовок: "Использование метода HTTP"
-draft: false
----
-
-```go
-func main() {
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // By default it serves on :8080 unless a
- // PORT environment variable was defined.
- router.Run()
- // router.Run(":3000") for a hard coded port
-}
-```
diff --git a/content/ru/docs/examples/http2-server-push.md b/content/ru/docs/examples/http2-server-push.md
deleted file mode 100644
index 22130a359..000000000
--- a/content/ru/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-Заголовок: "HTTP2 server push"
-черновик: false
----
-
-http.Pusher поддерживается только **go1.8+**. Подробную информацию смотрите в [golang blog](https://blog.golang.org/h2push).
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // use pusher.Push() to do server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Listen and Serve in https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/ru/docs/examples/jsonp.md b/content/ru/docs/examples/jsonp.md
deleted file mode 100644
index b5c75a17c..000000000
--- a/content/ru/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-Заголовок: "JSONP"
-черновик: false
----
-
-Использование JSONP для запроса данных с сервера в другом домене. Добавьте обратный вызов в тело ответа, если существует обратный вызов параметра запроса.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/map-as-querystring-or-postform.md b/content/ru/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index dd11f2416..000000000
--- a/content/ru/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-Заголовок: "Структура данных Map виде строки запроса или параметров постформы"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/ru/docs/examples/multipart-urlencoded-binding.md b/content/ru/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 1486ec109..000000000
--- a/content/ru/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-Заголовок: "Связка Multipart/Urlencoded"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // you can bind multipart form with explicit binding declaration:
- // c.ShouldBindWith(&form, binding.Form)
- // or you can simply use autobinding with ShouldBind method:
- var form LoginForm
- // in this case proper binding will be automatically selected
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Тестирование:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/ru/docs/examples/multipart-urlencoded-form.md b/content/ru/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index b9e4b6b6f..000000000
--- a/content/ru/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-Заголовок: "Форма Multipart/Urlencoded"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/ru/docs/examples/multiple-template.md b/content/ru/docs/examples/multiple-template.md
deleted file mode 100644
index 6f3f0b3ea..000000000
--- a/content/ru/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-Заголовок: "Несколько HTML темплейтов"
-черновик: false
----
-
-Gin позволяет по умолчанию использовать только один html.Template. Проверьте [a multitemplate render](https://github.com/gin-contrib/multitemplate) для использования таких возможностей, как go 1.6 `block template`.
diff --git a/content/ru/docs/examples/only-bind-query-string.md b/content/ru/docs/examples/only-bind-query-string.md
deleted file mode 100644
index ffae2c6fc..000000000
--- a/content/ru/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-Заголовок: "Только связывание строки запроса"
-draft: false
----
-
-Функция `ShouldBindQuery` связывает только параметры запроса, но не данные поста. См. [подробную информацию](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/ru/docs/examples/param-in-path.md b/content/ru/docs/examples/param-in-path.md
deleted file mode 100644
index 4cecad160..000000000
--- a/content/ru/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-Заголовок: "Параметры в path"
-черновик: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // This handler will match /user/john but will not match /user/ or /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // However, this one will match /user/john/ and also /user/john/send
- // If no other routers match /user/john, it will redirect to /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/pure-json.md b/content/ru/docs/examples/pure-json.md
deleted file mode 100644
index cf2b94346..000000000
--- a/content/ru/docs/examples/pure-json.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-Заголовок: "PureJSON"
-черновик: false
----
-
-Обычно JSON заменяет специальные HTML-символы их юникодными сущностями, например, `<` становится `\u003c`. Если вы хотите кодировать такие символы буквально, вы можете использовать PureJSON.
-Эта функция недоступна в Go 1.6 и ниже.
-
-```go
-func main() {
- r := gin.Default()
-
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/query-and-post-form.md b/content/ru/docs/examples/query-and-post-form.md
deleted file mode 100644
index 0942d484f..000000000
--- a/content/ru/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-Заголовок: "Форма для запросов и сообщений"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/ru/docs/examples/querystring-param.md b/content/ru/docs/examples/querystring-param.md
deleted file mode 100644
index 80f4920ad..000000000
--- a/content/ru/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-Заголовок: "Параметры строки запроса"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Query string parameters are parsed using the existing underlying request object.
- // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/redirects.md b/content/ru/docs/examples/redirects.md
deleted file mode 100644
index a941d5c4d..000000000
--- a/content/ru/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-Заголовок: "Перенаправления"
-черновик: false
----
-
-Создать HTTP-перенаправление очень просто. Поддерживаются как внутренние, так и внешние расположения.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Выдача HTTP-перенаправления из POST. См. выпуск: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Выдавая перенаправление Router, используйте `HandleContext`, как показано ниже.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/ru/docs/examples/rendering.md b/content/ru/docs/examples/rendering.md
deleted file mode 100644
index 1bb3e6844..000000000
--- a/content/ru/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-Заголовок: "Рендеринг XML/JSON/YAML/ProtoBuf"
-черновик: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H is a shortcut for map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response
- // Will output protoexample.Test protobuf serialized data
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/run-multiple-service.md b/content/ru/docs/examples/run-multiple-service.md
deleted file mode 100644
index 2c581c247..000000000
--- a/content/ru/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-название: "Запустить несколько сервисов"
-черновик: false
----
-
-Посмотрите [вопрос](https://github.com/gin-gonic/gin/issues/346) и попробуйте следующий пример:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/ru/docs/examples/secure-json.md b/content/ru/docs/examples/secure-json.md
deleted file mode 100644
index 56ab23230..000000000
--- a/content/ru/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-название: "SecureJSON"
-черновик: false
----
-
-Использование SecureJSON для предотвращения перехвата json. По умолчанию добавляет `"while(1),"` в тело ответа, если заданная структура представляет собой массив значений.
-
-```go
-func main() {
- r := gin.Default()
-
- // You can also use your own secure json prefix
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/security-headers.md b/content/ru/docs/examples/security-headers.md
deleted file mode 100644
index c6092216f..000000000
--- a/content/ru/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-название: "Заголовки безопасности"
-черновик: false
----
-
-Важно использовать заголовки безопасности, чтобы защитить ваше веб-приложение от распространенных уязвимостей. Этот пример показывает, как добавить заголовки безопасности в ваше приложение Gin, а также как избежать атак, связанных с инъекцией заголовков хоста (SSRF, Open Redirection).
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-Вы можете проверить его с помощью `curl`:
-
-```bash
-// Проверка заголовок
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// Проверка инъекции в заголовок хоста
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/ru/docs/examples/serving-data-from-reader.md b/content/ru/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index af201e164..000000000
--- a/content/ru/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-Заголовок: "Манипуляция данных от читателя"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/serving-static-files.md b/content/ru/docs/examples/serving-static-files.md
deleted file mode 100644
index 308edc0a9..000000000
--- a/content/ru/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-Заголовок: "Использование статических файлов"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/support-lets-encrypt.md b/content/ru/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index c7812db31..000000000
--- a/content/ru/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-Заголовок: "Поддержка Let's Encrypt"
-черновик: false
----
-
-пример для 1-строчных HTTPS-серверов LetsEncrypt.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-пример для пользовательского менеджера автосертификации.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/ru/docs/examples/upload-file/_index.md b/content/ru/docs/examples/upload-file/_index.md
deleted file mode 100644
index 442a9edb9..000000000
--- a/content/ru/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-название: "Загрузить файлы"
-draft: false
----
-
-Раздел содержит список использования api загрузки файлов.
diff --git a/content/ru/docs/examples/upload-file/multiple-file.md b/content/ru/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index d3b486079..000000000
--- a/content/ru/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Multiple files"
-draft: false
----
-
-Смотрите подробности [пример кода](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-Как тестировать с помощью `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/ru/docs/examples/upload-file/single-file.md b/content/ru/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 7c84d6e34..000000000
--- a/content/ru/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,36 +0,0 @@
----
-title: "Single file"
-draft: false
----
-Ссылки на проблему [#774](https://github.com/gin-gonic/gin/issues/774) и деталь [пример кода](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-`file.Filename` **НЕ ДОЛЖНО** быть доверенным. См. [`Content-Disposition` на MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) и [#1693](https://github.com/gin-gonic/gin/issues/1693)
-
-> Имя файла всегда необязательно и не должно использоваться приложением вслепую: информация о пути должна быть удалена, и должно быть выполнено преобразование к правилам файловой системы сервера.
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-Как тестировать с помощью `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/ru/docs/examples/using-basicauth-middleware.md b/content/ru/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 6b83d49c9..000000000
--- a/content/ru/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-Заголовок: "Использование промежуточного ПО BasicAuth"
-черновик: false
----
-
-```go
-// simulate some private data
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Group using gin.BasicAuth() middleware
- // gin.Accounts is a shortcut for map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets endpoint
- // hit "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // get user, it was set by the BasicAuth middleware
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/ru/docs/examples/using-middleware.md b/content/ru/docs/examples/using-middleware.md
deleted file mode 100644
index 00e1e4147..000000000
--- a/content/ru/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-Заголовок: "Использование промежуточного ПО"
-черновик: false
----
-
-```go
-func main() {
- // Creates a router without any middleware by default
- r := gin.New()
-
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- r.Use(gin.Recovery())
-
- // Per route middleware, you can add as many as you desire.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Authorization group
- // authorized := r.Group("/", AuthRequired())
- // exactly the same as:
- authorized := r.Group("/")
- // per group middleware! in this case we use the custom created
- // AuthRequired() middleware just in the "authorized" group.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // nested group
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/ru/docs/examples/without-middleware.md b/content/ru/docs/examples/without-middleware.md
deleted file mode 100644
index e4884ecaa..000000000
--- a/content/ru/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-Заголовок: "Без промежуточного ПО по умолчанию"
-draft: false
----
-
-Используйте
-
-```go
-r := gin.New()
-```
-
-место
-
-```go
-// Default With the Logger and Recovery middleware already attached
-r := gin.Default()
-```
diff --git a/content/ru/docs/examples/write-log.md b/content/ru/docs/examples/write-log.md
deleted file mode 100644
index c42f21c75..000000000
--- a/content/ru/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-Заголовок: "Как записать файл журнала"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color, you don't need console color when writing the logs to file.
- gin.DisableConsoleColor()
-
- // Logging to a file.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Use the following code if you need to write the logs to file and console at the same time.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/ru/docs/faq/_index.md b/content/ru/docs/faq/_index.md
deleted file mode 100644
index 1e0345a1a..000000000
--- a/content/ru/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-Заголовок: "FAQ"
-черновик: false
-вес: 9
----
-
-TODO: записать некоторые часто задаваемые вопросы из вкладки GitHub Issue.
-
diff --git a/content/ru/docs/features/_index.md b/content/ru/docs/features/_index.md
deleted file mode 100644
index 08607d579..000000000
--- a/content/ru/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-Заголовок: "Особенности"
-черновик: false
-вес: 4
----
-
-## Стабильные возможности Gin v1:
-
-- Маршрутизатор с нулевым распределением.
-
-- По-прежнему самый быстрый http-маршрутизатор и фреймворк. От маршрутизации до написания.
-
-- Полный набор модульных тестов.
-
-- Проверено в бою.
-
-- API заморожен, новые релизы не сломают ваш код.
diff --git a/content/ru/docs/introduction/_index.md b/content/ru/docs/introduction/_index.md
deleted file mode 100644
index 1e93bee72..000000000
--- a/content/ru/docs/introduction/_index.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-Заголовок: "Введение"
-черновик: false
-вес: 1
----
-
-Gin - это веб-фреймворк, написанный на языке Go (Golang). В нем реализован мартини-подобный API с гораздо лучшей производительностью, до 40 раз быстрее благодаря [httprouter](https://github.com/julienschmidt/httprouter). Если вам нужна производительность и хорошая продуктивность, вам понравится Gin.
-
-В этом разделе мы расскажем о том, что такое Gin, какие проблемы он решает и как он может помочь вашему проекту.
-
-Если же вы уже готовы использовать Gin в своем проекте, посетите [Quickstart](https://gin-gonic.com/docs/quickstart/).
-
-## Особенности
-
-### Быстрый
-
-Маршрутизация на основе радиксного дерева, малый объем памяти. Никаких отражений. Предсказуемая производительность API.
-
-### Поддержка промежуточного ПО
-
-Входящий HTTP-запрос может быть обработан цепочкой промежуточных программ и завершен конечным действием.
-Например: Логгер, Авторизация, GZIP и, наконец, публикация сообщения в БД.
-
-### Защита от сбоев
-
-Gin может поймать панику, возникшую во время HTTP-запроса, и восстановить ее. Таким образом, ваш сервер будет всегда доступен. В качестве примера - можно также сообщить об этой панике в Sentry!
-
-Переведено с помощью DeepL.com (бесплатная версия)
-
-### Проверка JSON
-
-Gin может анализировать и проверять JSON-запрос - например, проверять наличие необходимых значений.
-
-### Группировка маршрутов
-
-Организуйте свои маршруты лучше. Требуемая и необязательная авторизация, разные версии API... Кроме того, группы могут быть неограниченно вложены друг в друга без снижения производительности.
-
-### Управление ошибками
-
-Gin предоставляет удобный способ сбора всех ошибок, возникших во время HTTP-запроса. В конечном итоге промежуточное ПО может записывать их в лог-файл, в базу данных или отправлять по сети.
-
-### Рендеринг встроенный
-
-Gin предоставляет простой в использовании API для рендеринга JSON, XML и HTML.
-
-### Расширяемость
-
-Создать новое промежуточное ПО очень просто, просто посмотрите примеры кодов.
-
diff --git a/content/ru/docs/jsoniter/_index.md b/content/ru/docs/jsoniter/_index.md
deleted file mode 100644
index 0d88e1de7..000000000
--- a/content/ru/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-название: "Jsoniter"
-черновик: false
-вес: 5
----
-
-## Сборка с [jsoniter](https://github.com/json-iterator/go)
-
-Gin использует `encoding/json` как пакет json по умолчанию, но вы можете изменить его на [jsoniter](https://github.com/json-iterator/go), собирая из других тегов.
-
-``sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/ru/docs/quickstart/_index.md b/content/ru/docs/quickstart/_index.md
deleted file mode 100644
index 080171f06..000000000
--- a/content/ru/docs/quickstart/_index.md
+++ /dev/null
@@ -1,87 +0,0 @@
----
-название: "Быстрый старт"
-черновик: false
-вес: 2
----
-
-В этом кратком руководстве мы извлечем уроки из сегментов кода и узнаем, как:
-
-## Требования
-
-- Go 1.16 или выше
-
-## Установка
-
-Чтобы установить пакет Gin, необходимо сначала установить Go и настроить рабочее пространство Go.
-
-1. Скачайте и установите его:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. Импортируйте его в свой код:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (Необязательно) Импортируйте `net/http`. Это необходимо, например, при использовании таких констант, как `http.StatusOK`.
-
-```go
-import "net/http"
-```
-
-1. Создайте папку проекта и `cd` в ней
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. Скопируйте начальный шаблон в свой проект
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. Запустите свой проект
-
-```sh
-$ go run main.go
-```
-
-## Начало работы
-
-> Не знаете, как написать и выполнить код Go? [Нажмите здесь](https://golang.org/doc/code.html).
-
-Сначала создайте файл с именем `example.go`:
-
-```sh
-# assume the following codes in example.go file
-$ touch example.go
-```
-
-Затем поместите следующий код в файл `example.go`:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-И вы можете запустить код с помощью `go run example.go`:
-
-```sh
-# run example.go and visit 0.0.0.0:8080/ping on browser
-$ go run example.go
-```
diff --git a/content/ru/docs/testing/_index.md b/content/ru/docs/testing/_index.md
deleted file mode 100644
index f175db7e2..000000000
--- a/content/ru/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-название: "Тестирование"
-черновик: false
-вес: 7
----
-
-## Как написать тестовый пример для Gin?
-
-Пакет `net/http/httptest` является предпочтительным способом для тестирования HTTP.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-Тест для примера кода, приведенного выше:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/ru/docs/users/_index.md b/content/ru/docs/users/_index.md
deleted file mode 100644
index c3c973b91..000000000
--- a/content/ru/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Users"
-draft: false
-weight: 8
----
-
-##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
-
-* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
-
-* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
-
-* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
-
-* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
-
-* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
-
-* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/content/ru/featured-background.jpg b/content/ru/featured-background.jpg
deleted file mode 100644
index 8bb8a4cc6..000000000
Binary files a/content/ru/featured-background.jpg and /dev/null differ
diff --git a/content/ru/search.md b/content/ru/search.md
deleted file mode 100644
index ec487e522..000000000
--- a/content/ru/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Результаты поиска
-layout: поиск
----
-
diff --git a/content/tr/_index.html b/content/tr/_index.html
deleted file mode 100644
index 04904a8b3..000000000
--- a/content/tr/_index.html
+++ /dev/null
@@ -1,76 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-
}}">
- Daha Fazla Öğren
-
-
- İndir
-
-
Go ile yazılmış, en hızlı, tam teşekküllü ve kristal berraklığında bir web çerçevesi.
-
- {{< blocks/link-down color="info" >}}
-
-{{< /blocks/cover >}}
-
-
-{{% blocks/lead color="white" %}}
-
-**Gin nedir??**
-
-Gin, Golang'da yazılmış bir web çerçevesidir.
-
-Martini benzeri bir API'ye sahiptir, ancak performans açısından Martini'den 40 kata kadar daha hızlıdır.
-
-Performans ve üretkenliğe ihtiyacınız varsa Gin'i seveceksiniz.
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="Hızlı" %}}
-Radix ağacı tabanlı routing, küçük bellek ayak izi. Reflection yok. Öngörülebilir API performansı.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="Middleware desteği" %}}
-Gelen bir HTTP isteği, bir middleware zinciri ve son eylem tarafından işlenebilir. Örneğin: Logger, Authorization, GZIP ve son olarak veritabanına bir mesaj gönderin.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Çökmeye Dirençli" %}}
-Gin, bir HTTP isteği sırasında oluşan bir paniği yakalayabilir ve düzeltebilir. Bu şekilde sunucunuz her zaman çalışacaktır. Ayrıca bir paniği Sentry'ye bildirmek de mümkündür.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON doğrulama" %}}
-Gin, bir isteğin JSON'ını ayrıştırabilir ve doğrulayabilir. Örneğin gerekli değerlerin varlığını kontrol edebilir.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="Route gruplama" %}}
-Routelarınızı daha iyi düzenleyin. Authorization gerektiren veya gerektirmeyen, farklı API sürümlerini kolayca düzenleyin. Ayrıca, gruplar performansı düşürmeden sınırsız olarak iç içe yerleştirilebilir.
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="Hata yönetimi" %}}
-Gin, bir HTTP isteği sırasında meydana gelen tüm hataları toplamak için uygun bir yol sağlar. Sonunda, middleware bunları bir log dosyasına veya bir veritabanına yazabilir ve ağ üzerinden gönderebilir.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="Hazır rendering" %}}
-Gin, JSON, XML ve HTML işleme için kullanımı kolay bir API sağlar.
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="Genişletilebilir" %}}
-Yeni middleware oluşturmak çok kolaydır, sadece örnek kodları inceleyin.
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
diff --git a/content/tr/blog/_index.md b/content/tr/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/tr/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/tr/blog/news/_index.md b/content/tr/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/tr/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/tr/blog/releases/_index.md b/content/tr/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/tr/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/tr/docs/_index.md b/content/tr/docs/_index.md
deleted file mode 100644
index fc8c8ed68..000000000
--- a/content/tr/docs/_index.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "Dokümantasyon"
-linkTitle: "Dokümantasyon"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin nedir?
-
-Gin, Go (Golang) ile yazılmış bir HTTP web çerçevesidir. Martini benzeri bir API'ye sahiptir, ancak performans açısından Martini'den 40 kata kadar daha hızlıdır. Çarpıcı bir performansa ihtiyacınız varsa, kendinize biraz Gin alın.
-
-## Gin'i nasıl kullanmalı?
-
-API kullanım [örnekleri](https://github.com/gin-gonic/examples) sunuyoruz ve bilinen bazı [Gin kullanıcılarını](./users) listeliyoruz.
-
-## Gin'e nasıl katkıda bulunmalı?
-
-* Tartışma forumlarında insanlara yardım edin
-* Gin kullanarak bize başarı hikayelerinizi anlatın
-* Bize Gin'i nasıl iyileştirebileceğimizi söyleyin ve bunu yapmamıza yardımcı olun
-* Mevcut bir kütüphaneye katkıda bulunun
-
diff --git a/content/tr/docs/benchmarks/_index.md b/content/tr/docs/benchmarks/_index.md
deleted file mode 100644
index 3f5ef0df1..000000000
--- a/content/tr/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Kalite Testleri"
-draft: false
-weight: 3
----
-
-Gin, [HttpRouter](https://github.com/julienschmidt/httprouter)'ın özel bir sürümünü kullanır
-
-[Tüm kalite testlerini görün](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Kalite Testi Adı | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1): Sabit sürede elde edilen Toplam Tekrar, daha yüksek, daha emin sonuç anlamına gelir
-- (2): Tek Tekrar Süresi (ns/op), daha düşük daha iyidir
-- (3): Heap Memory (B/op), daha düşük daha iyidir
-- (4): Tekrar Başına Ortalama Allocations (allocs/op), daha düşük daha iyidir
diff --git a/content/tr/docs/deployment/_index.md b/content/tr/docs/deployment/_index.md
deleted file mode 100644
index 51539a786..000000000
--- a/content/tr/docs/deployment/_index.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Deploy etme"
-draft: false
-weight: 6
----
-
-Gin projeleri herhangi bir bulut sağlayıcısına kolayca deploy edilebilir.
-
-## [Koyeb](https://www.koyeb.com)
-
-Koyeb, git tabanlı, TLS şifreleme, yerel otomatik ölçeklendirme, küresel uç ağ ve yerleşik hizmet ağı ve keşfi ile uygulamaları küresel olarak dağıtmak/deploy etmek için geliştirici dostu sunucusuz bir platformdur.
-
-Koyeb'i takip edin [guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
-
-## [Qovery](https://www.qovery.com)
-
-Qovery; veri tabanı, SSL'i, küresel CDN'i olan ve Git ile otomatik deploy için ücretsiz bulut ortamı sağlar.
-
-[Gin projenizi deploy etmek](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/) için Qovery kılavuzunu izleyin.
-
-## [Render](https://render.com)
-
-Render; Go, tam yönetilebilen SSL, veritabanları, sıfır kesintili deploy, HTTP/2 ve websocket desteği için yerel destek sunan modern bir bulut platformudur.
-
-Render'ı takip edin [Gin projelerini dağıtma kılavuzu.](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE, Go uygulamalarını dağıtmanın iki yönteme sahiptir. Standart ortamın kullanımı daha kolaydır ancak daha az özelleştirilebilir ve güvenlik nedenleriyle [syscalls](https://github.com/gin-gonic/gin/issues/1639) gibi sistem çağrılarını önler.
-
-Daha fazla bilgi edinin ve tercih ettiğiniz ortamı şuradan seçin: [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/content/tr/docs/examples/_index.md b/content/tr/docs/examples/_index.md
deleted file mode 100644
index c25460175..000000000
--- a/content/tr/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "Örnekler"
-draft: false
-weight: 6
----
-
-Bu bölüm, api kullanımını listeler.
diff --git a/content/tr/docs/examples/ascii-json.md b/content/tr/docs/examples/ascii-json.md
deleted file mode 100644
index 82ab48d2a..000000000
--- a/content/tr/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/bind-body-into-dirrerent-structs.md b/content/tr/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index c685ccaba..000000000
--- a/content/tr/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Try to bind body into different structs"
-draft: false
----
-
-The normal methods for binding request body consumes `c.Request.Body` and they
-cannot be called multiple times.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Always an error is occurred by this because c.Request.Body is EOF now.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-For this, you can use `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // At this time, it reuses body stored in the context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` stores body into the context before binding. This has
-a slight impact to performance, so you should not use this method if you are
-enough to call binding at once.
-* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
-can be called by `c.ShouldBind()` multiple times without any damage to
-performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/tr/docs/examples/bind-form-data-request-with-custom-struct.md b/content/tr/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index 2882e8656..000000000
--- a/content/tr/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,77 +0,0 @@
----
-title: "Bind form-data request with custom struct"
-draft: false
----
-
-The follow example using custom struct:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Using the command `curl` command result:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
diff --git a/content/tr/docs/examples/bind-html-checkbox.md b/content/tr/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index ae63e1f60..000000000
--- a/content/tr/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Bind html checkboxes"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-result:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/tr/docs/examples/bind-query-or-post.md b/content/tr/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 7ebbe739c..000000000
--- a/content/tr/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "Bind query string or post data"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // If `GET`, only `Form` binding engine (`query`) used.
- // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
- // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Test it with:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/tr/docs/examples/bind-single-binary-with-template.md b/content/tr/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 36f0bb212..000000000
--- a/content/tr/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Build a single binary with templates"
-draft: false
----
-## Use the third-party package
-
-You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate loads templates embedded by go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/content/tr/docs/examples/bind-uri.md b/content/tr/docs/examples/bind-uri.md
deleted file mode 100644
index 743074b69..000000000
--- a/content/tr/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Bind Uri"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-Test it with:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/tr/docs/examples/binding-and-validation.md b/content/tr/docs/examples/binding-and-validation.md
deleted file mode 100644
index 41a564a3e..000000000
--- a/content/tr/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Model binding and validation"
-draft: false
----
-
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
-
-Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
-
-Also, Gin provides two sets of methods for binding:
-- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
-- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
-
-When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
-
-You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
-
-```go
-// Binding from JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Example for binding JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding a HTML form (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-### Sample request
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-### Skip validate
-
-When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/content/tr/docs/examples/controlling-log-output-coloring.md b/content/tr/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 81f27efe9..000000000
--- a/content/tr/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Controlling Log output coloring"
-draft: false
----
-
-By default, logs output on console should be colorized depending on the detected TTY.
-
-Never colorize logs:
-
-```go
-func main() {
- // Disable log's color
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Always colorize logs:
-
-```go
-func main() {
- // Force log's color
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/cookie.md b/content/tr/docs/examples/cookie.md
deleted file mode 100644
index 231473ca5..000000000
--- a/content/tr/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Set and get a cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/tr/docs/examples/custom-http-config.md b/content/tr/docs/examples/custom-http-config.md
deleted file mode 100644
index e9a679361..000000000
--- a/content/tr/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Custom HTTP configuration"
-draft: false
----
-
-Use `http.ListenAndServe()` directly, like this:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-or
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/tr/docs/examples/custom-log-format.md b/content/tr/docs/examples/custom-log-format.md
deleted file mode 100644
index f9ea8b6a7..000000000
--- a/content/tr/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "Custom log file"
-draft: false
----
-
-For example:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
- // By default gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // your custom format
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**Sample Output**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/tr/docs/examples/custom-middleware.md b/content/tr/docs/examples/custom-middleware.md
deleted file mode 100644
index dd7407b07..000000000
--- a/content/tr/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Custom Middleware"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Set example variable
- c.Set("example", "12345")
-
- // before request
-
- c.Next()
-
- // after request
- latency := time.Since(t)
- log.Print(latency)
-
- // access the status we are sending
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // it would print: "12345"
- log.Println(example)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/tr/docs/examples/custom-validators.md b/content/tr/docs/examples/custom-validators.md
deleted file mode 100644
index f777436cc..000000000
--- a/content/tr/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "Custom validators"
-draft: false
----
-
-It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking contains binded and validated data.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
-{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
-```
-
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
-See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/content/tr/docs/examples/define-format-for-the-log-of-routes.md b/content/tr/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 6cfdaa68f..000000000
--- a/content/tr/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Define format for the log of routes"
-draft: false
----
-
-The default log of routes is:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
-In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Listen and Server in http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/tr/docs/examples/goroutines-inside-a-middleware.md b/content/tr/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 122593a1b..000000000
--- a/content/tr/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Goroutines inside a middleware"
-draft: false
----
-
-When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // create copy to be used inside the goroutine
- cCp := c.Copy()
- go func() {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // note that you are using the copied context "cCp", IMPORTANT
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // since we are NOT using a goroutine, we do not have to copy the context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/graceful-restart-or-stop.md b/content/tr/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 87ca178c2..000000000
--- a/content/tr/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,85 +0,0 @@
----
-title: "Graceful restart or stop"
-draft: false
----
-
-Do you want to graceful restart or stop your web server?
-There are some ways this can be done.
-
-We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-An alternative to endless:
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "syscall"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // service connections
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Wait for interrupt signal to gracefully shutdown the server with
- // a timeout of 5 seconds.
- quit := make(chan os.Signal, 1)
- // kill (no param) default send syscanll.SIGTERM
- // kill -2 is syscall.SIGINT
- // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
- signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- // catching ctx.Done(). timeout of 5 seconds.
- select {
- case <-ctx.Done():
- log.Println("timeout of 5 seconds.")
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/tr/docs/examples/grouping-routes.md b/content/tr/docs/examples/grouping-routes.md
deleted file mode 100644
index a480aa325..000000000
--- a/content/tr/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Grouping routes"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Simple group: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Simple group: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/html-rendering.md b/content/tr/docs/examples/html-rendering.md
deleted file mode 100644
index cfa8e825a..000000000
--- a/content/tr/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML rendering"
-draft: false
----
-
-Using LoadHTMLGlob() or LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Using templates with same name in different directories
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-### Custom Template renderer
-
-You can also use your own html template render
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-### Custom Delimiters
-
-You may use custom delims
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-### Custom Template Funcs
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/tr/docs/examples/http-method.md b/content/tr/docs/examples/http-method.md
deleted file mode 100644
index 6678e155f..000000000
--- a/content/tr/docs/examples/http-method.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "Using HTTP method"
-draft: false
----
-
-```go
-func main() {
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // By default it serves on :8080 unless a
- // PORT environment variable was defined.
- router.Run()
- // router.Run(":3000") for a hard coded port
-}
-```
diff --git a/content/tr/docs/examples/http2-server-push.md b/content/tr/docs/examples/http2-server-push.md
deleted file mode 100644
index 00bbd12d8..000000000
--- a/content/tr/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server push"
-draft: false
----
-
-http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // use pusher.Push() to do server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Listen and Server in https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/tr/docs/examples/jsonp.md b/content/tr/docs/examples/jsonp.md
deleted file mode 100644
index 63c7dc551..000000000
--- a/content/tr/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/map-as-querystring-or-postform.md b/content/tr/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index fa733e2ef..000000000
--- a/content/tr/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Map as querystring or postform parameters"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/tr/docs/examples/multipart-urlencoded-binding.md b/content/tr/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 767fc6576..000000000
--- a/content/tr/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded binding"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // you can bind multipart form with explicit binding declaration:
- // c.ShouldBindWith(&form, binding.Form)
- // or you can simply use autobinding with ShouldBind method:
- var form LoginForm
- // in this case proper binding will be automatically selected
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Test it with:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/tr/docs/examples/multipart-urlencoded-form.md b/content/tr/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 774662b1e..000000000
--- a/content/tr/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded form"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/tr/docs/examples/multiple-template.md b/content/tr/docs/examples/multiple-template.md
deleted file mode 100644
index 0bcf46858..000000000
--- a/content/tr/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Multitemplate"
-draft: false
----
-
-Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/content/tr/docs/examples/only-bind-query-string.md b/content/tr/docs/examples/only-bind-query-string.md
deleted file mode 100644
index d6d4e33cc..000000000
--- a/content/tr/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Only bind query string"
-draft: false
----
-
-`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/tr/docs/examples/param-in-path.md b/content/tr/docs/examples/param-in-path.md
deleted file mode 100644
index 6e29a59c7..000000000
--- a/content/tr/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Parameters in path"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // This handler will match /user/john but will not match /user/ or /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // However, this one will match /user/john/ and also /user/john/send
- // If no other routers match /user/john, it will redirect to /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/pure-json.md b/content/tr/docs/examples/pure-json.md
deleted file mode 100644
index d91f905ef..000000000
--- a/content/tr/docs/examples/pure-json.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
-This feature is unavailable in Go 1.6 and lower.
-
-```go
-func main() {
- r := gin.Default()
-
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/query-and-post-form.md b/content/tr/docs/examples/query-and-post-form.md
deleted file mode 100644
index 0d7b18e51..000000000
--- a/content/tr/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Query and post form"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/tr/docs/examples/querystring-param.md b/content/tr/docs/examples/querystring-param.md
deleted file mode 100644
index bcf8b55f2..000000000
--- a/content/tr/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "Query string parameters"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Query string parameters are parsed using the existing underlying request object.
- // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/redirects.md b/content/tr/docs/examples/redirects.md
deleted file mode 100644
index f7d823eca..000000000
--- a/content/tr/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirects"
-draft: false
----
-
-Issuing a HTTP redirect is easy. Both internal and external locations are supported.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Issuing a Router redirect, use `HandleContext` like below.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/tr/docs/examples/rendering.md b/content/tr/docs/examples/rendering.md
deleted file mode 100644
index a9fa75b5f..000000000
--- a/content/tr/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf rendering"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H is a shortcut for map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response
- // Will output protoexample.Test protobuf serialized data
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/run-multiple-service.md b/content/tr/docs/examples/run-multiple-service.md
deleted file mode 100644
index ebe6223a0..000000000
--- a/content/tr/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Run multiple service"
-draft: false
----
-
-See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "message": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/tr/docs/examples/secure-json.md b/content/tr/docs/examples/secure-json.md
deleted file mode 100644
index 9f5642167..000000000
--- a/content/tr/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
-
-```go
-func main() {
- r := gin.Default()
-
- // You can also use your own secure json prefix
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/security-headers.md b/content/tr/docs/examples/security-headers.md
deleted file mode 100644
index 89dabcce9..000000000
--- a/content/tr/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "Güvenlik Üst Bilgileri"
-draft: false
----
-
-Web uygulamanızı yaygın güvenlik açıklarından korumak için güvenlik başlıklarını kullanmak önemlidir. Bu örnek, Gin uygulamanıza güvenlik başlıklarını nasıl ekleyeceğinizi ve ayrıca Host Header Injection ile ilgili saldırılardan (SSRF, Open Redirection) nasıl kaçınacağınızı gösterir.
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-You can test it via `curl`:
-
-```bash
-// Başlıkları Kontrol Edin
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// Ana Bilgisayar Başlık Enjeksiyonunu Kontrol Et
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/tr/docs/examples/serving-data-from-reader.md b/content/tr/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index f5546a8c6..000000000
--- a/content/tr/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Serving data from reader"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/serving-static-files.md b/content/tr/docs/examples/serving-static-files.md
deleted file mode 100644
index e296ead02..000000000
--- a/content/tr/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "Serving static files"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/support-lets-encrypt.md b/content/tr/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index c66288e87..000000000
--- a/content/tr/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Support Let's Encrypt"
-draft: false
----
-
-example for 1-line LetsEncrypt HTTPS servers.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-example for custom autocert manager.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/tr/docs/examples/upload-file/_index.md b/content/tr/docs/examples/upload-file/_index.md
deleted file mode 100644
index 1810e3253..000000000
--- a/content/tr/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Upload files"
-draft: false
----
-
-The section lists upload file api usage.
diff --git a/content/tr/docs/examples/upload-file/multiple-file.md b/content/tr/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 912472dd3..000000000
--- a/content/tr/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Multiple files"
-draft: false
----
-
-See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/tr/docs/examples/upload-file/single-file.md b/content/tr/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 22ac899f8..000000000
--- a/content/tr/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Single file"
-draft: false
----
-
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
-
-> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/tr/docs/examples/using-basicauth-middleware.md b/content/tr/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 318aca232..000000000
--- a/content/tr/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Using BasicAuth middleware"
-draft: false
----
-
-```go
-// simulate some private data
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Group using gin.BasicAuth() middleware
- // gin.Accounts is a shortcut for map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets endpoint
- // hit "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // get user, it was set by the BasicAuth middleware
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/tr/docs/examples/using-middleware.md b/content/tr/docs/examples/using-middleware.md
deleted file mode 100644
index 2a3159cc3..000000000
--- a/content/tr/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Using middleware"
-draft: false
----
-
-```go
-func main() {
- // Creates a router without any middleware by default
- r := gin.New()
-
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- r.Use(gin.Recovery())
-
- // Per route middleware, you can add as many as you desire.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Authorization group
- // authorized := r.Group("/", AuthRequired())
- // exactly the same as:
- authorized := r.Group("/")
- // per group middleware! in this case we use the custom created
- // AuthRequired() middleware just in the "authorized" group.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // nested group
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/tr/docs/examples/without-middleware.md b/content/tr/docs/examples/without-middleware.md
deleted file mode 100644
index ce7b81fbb..000000000
--- a/content/tr/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Without middleware by default"
-draft: false
----
-
-Use
-
-```go
-r := gin.New()
-```
-
-instead of
-
-```go
-// Default With the Logger and Recovery middleware already attached
-r := gin.Default()
-```
diff --git a/content/tr/docs/examples/write-log.md b/content/tr/docs/examples/write-log.md
deleted file mode 100644
index 261b8d26a..000000000
--- a/content/tr/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "How to write log file"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color, you don't need console color when writing the logs to file.
- gin.DisableConsoleColor()
-
- // Logging to a file.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Use the following code if you need to write the logs to file and console at the same time.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/tr/docs/faq/_index.md b/content/tr/docs/faq/_index.md
deleted file mode 100644
index 389d1432a..000000000
--- a/content/tr/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: record some frequently asked question from GitHub Issue tab.
-
diff --git a/content/tr/docs/features/_index.md b/content/tr/docs/features/_index.md
deleted file mode 100644
index ad7e314cb..000000000
--- a/content/tr/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Özellikler"
-draft: false
-weight: 4
----
-
-## Gin v1 sabit özellikler:
-
-- Sıfır allocation router.
-
-- Routingden http isteklerini yanıtlamaya kadar hala en hızlı http router ve framework.
-
-- Eksiksiz unit testleri paketi.
-
-- Güçlü bir biçimde test edilmiş.
-
-- API donsa dahi, yeni sürümler kodunuzu bozmaz ve çalışmaya devam eder.
diff --git a/content/tr/docs/introduction/_index.md b/content/tr/docs/introduction/_index.md
deleted file mode 100644
index c96e8defd..000000000
--- a/content/tr/docs/introduction/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "Giriş"
-draft: false
-weight: 1
----
-
-Gin, Go (Golang) ile yazılmış bir web çerçevesidir. Martini benzeri bir API'ye sahiptir ama [httprouter](https://github.com/julienschmidt/httprouter) sayesinde 40 kata kadar daha hızlı, çok daha iyi performansa sahiptir. Performansa ve iyi üretkenliğe ihtiyacınız varsa, Gin'i seveceksiniz.
-
-Bu bölümde Gin'in ne olduğunu, hangi sorunları çözdüğünü ve projenize nasıl yardımcı olabileceğini inceleyeceğiz.
-
-Veya projenizde Gin'i kullanmaya hazırsanız [Hızlı Başlangıç](https://gin-gonic.com/tr/docs/quickstart/)'ı ziyaret edin.
-
-## Özellikler
-
-### Hızlı
-
-Radix ağacı tabanlı routing, küçük bellek ayak izi. Reflection yok. Öngörülebilir API performansı.
-
-### Middleware desteği
-
-Gelen bir HTTP isteği, bir middleware zinciri ve son eylem tarafından işlenebilir. Örneğin: Logger, Authorization, GZIP ve son olarak veritabanına bir mesaj gönderin.
-
-### Çökmeye Dirençli
-
-Gin, bir HTTP isteği sırasında oluşan bir paniği yakalayabilir ve düzeltebilir. Bu şekilde sunucunuz her zaman çalışacaktır. Ayrıca bir paniği Sentry'ye bildirmek de mümkündür.
-
-### JSON doğrulama
-
-Gin, bir isteğin JSON'ını ayrıştırabilir ve doğrulayabilir. Örneğin gerekli değerlerin varlığını kontrol edebilir.
-
-### Route gruplama
-
-Routelarınızı daha iyi düzenleyin. Authorization gerektiren veya gerektirmeyen, farklı API sürümlerini kolayca düzenleyin. Ayrıca, gruplar performansı düşürmeden sınırsız olarak iç içe yerleştirilebilir.
-
-### Hata yönetimi
-
-Gin, bir HTTP isteği sırasında meydana gelen tüm hataları toplamak için uygun bir yol sağlar. Sonunda, middleware bunları bir log dosyasına veya bir veritabanına yazabilir ve ağ üzerinden gönderebilir.
-
-
-### Hazır rendering
-
-Gin, JSON, XML ve HTML işleme için kullanımı kolay bir API sağlar.
-
-### Genişletilebilir
-
-Yeni middleware oluşturmak çok kolaydır, sadece örnek kodları inceleyin.
-
diff --git a/content/tr/docs/jsoniter/_index.md b/content/tr/docs/jsoniter/_index.md
deleted file mode 100644
index 0072f703a..000000000
--- a/content/tr/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-## [jsoniter](https://github.com/json-iterator/go) ile oluşturun
-
-Gin, varsayılan json paketi olarak `encoding/json` kullanır, ancak diğer etiketlerden derleyerek varsayılanı [jsoniter](https://github.com/json-iterator/go) olarak değiştirebilirsiniz.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/tr/docs/quickstart/_index.md b/content/tr/docs/quickstart/_index.md
deleted file mode 100644
index 0c72603e2..000000000
--- a/content/tr/docs/quickstart/_index.md
+++ /dev/null
@@ -1,86 +0,0 @@
----
-title: "Hızlı Başlangıç"
-draft: false
-weight: 2
----
-
-Bu hızlı başlangıçta, kod parçacıklarından içgörüler toplayacağız ve aşağıda belirtilen adımları nasıl yapacağımızı öğreneceğiz:
-
-## Gereksinimler
-
-- Go 1.16 veya üzeri
-
-## Kurulum
-
-Gin paketini kurmak için önce Go'yu kurmanız ve Go çalışma alanınızı ayarlamanız gerekir.
-
-1. İndirin ve kurun:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. Kodunuzda import edin:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (İsteğe bağlı) `net/http` paketini import edin. Bu, `http.StatusOK` gibi statü belirten ifadeler kullanılıyorsa gereklidir.
-
-```go
-import "net/http"
-```
-
-1. Proje klasörünüzü oluşturun ve `cd` komutu ile içine girin
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. Projenizin içine bir başlangıç şablonu kopyalayın
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. Projenizi çalıştırın
-
-```sh
-$ go run main.go
-```
-
-## Başlarken
-> Go kodunu nasıl yazıp çalıştıracağınızdan emin değil misiniz? [Buraya tıklayın](https://golang.org/doc/code.html).
-
-İlk olarak, `example.go` adlı bir dosya oluşturun
-
-```sh
-# aşağıdaki kodları example.go dosyasında varsayalım
-$ touch example.go
-```
-
-Ardından, aşağıdaki kodu `example.go` dosyasının içine yerleştirin
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // 0.0.0.0:8080 adresini dinleyin ve servis edin
-}
-```
-
-Ve, kodu şu şekilde çalıştırabilirsiniz : `go run example.go`:
-
-```sh
-# example.go dosyasını çalıştırın ve tarayıcıda 0.0.0.0:8080/ping adresini ziyaret edin
-$ go run example.go
-```
diff --git a/content/tr/docs/testing/_index.md b/content/tr/docs/testing/_index.md
deleted file mode 100644
index fcb04a896..000000000
--- a/content/tr/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "Test"
-draft: false
-weight: 7
----
-
-## Gin için nasıl test yazılır?
-
-`net/http/httptest` HTTP testi için tercih edilen pakettir.
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-Yukarıdaki kod örneği için test:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/tr/docs/users/_index.md b/content/tr/docs/users/_index.md
deleted file mode 100644
index 2ea96ac86..000000000
--- a/content/tr/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "Kullanıcılar"
-draft: false
-weight: 8
----
-
-##### [Gin](https://github.com/gin-gonic/gin) web çerçevesini kullanan harika proje listeleri:
-
-* [gorush](https://github.com/appleboy/gorush): Go'da yazılmış bir anında iletme bildirim sunucusu.
-
-* [fnproject](https://github.com/fnproject/fn): Container native, buluttan bağımsız sunucusuz platform.
-
-* [photoprism](https://github.com/photoprism/photoprism): Go ve Google TensorFlow tarafından desteklenen kişisel fotoğraf yönetimi.
-
-* [krakend](https://github.com/devopsfaith/krakend): Middlewarelere sahip ultra performanslı API Gateway'i.
-
-* [picfit](https://github.com/thoas/picfit): Go'da yazılmış bir görüntü yeniden boyutlandırma sunucusu.
-
-* [gotify](https://github.com/gotify/server): Web soketi başına gerçek zamanlı olarak mesaj göndermek ve almak için basit bir sunucu.
-
-* [cds](https://github.com/ovh/cds): Kurumsal Düzeyde Continuous Delivery ve DevOps Otomasyonu Açık Kaynak Platformu.
diff --git a/content/tr/search.md b/content/tr/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/tr/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/content/zh-cn/_index.html b/content/zh-cn/_index.html
deleted file mode 100644
index 8610720a4..000000000
--- a/content/zh-cn/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-{{% blocks/lead color="white" %}}
-
-**什么是Gin?**
-
-Gin是一个使用Go语言开发的Web框架。
-
-它提供类似Martini的API,但性能更佳,速度提升高达40倍。
-
-如果你是性能和高效的追求者, 你会爱上 Gin。
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="快速" %}}
-基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="支持中间件" %}}
-传入的 HTTP 请求可以由一系列中间件和最终操作来处理。
-例如:Logger,Authorization,GZIP,最终操作 DB。
-
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash 处理" %}}
-Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON 验证" %}}
-Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="路由组" %}}
-Gin帮助您更好地组织您的路由,例如,按照需要授权和不需要授权和不同API版本进行分组。此外,路由分组可以无限嵌套而不降低性能。
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="错误管理" %}}
-Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="内置渲染" %}}
-Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="可扩展性" %}}
-新建一个中间件非常简单,去查看[示例代码](https://gin-gonic.com/zh-cn/docs/examples/using-middleware/)吧。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
\ No newline at end of file
diff --git a/content/zh-cn/blog/_index.md b/content/zh-cn/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/zh-cn/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/zh-cn/blog/news/_index.md b/content/zh-cn/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/zh-cn/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/zh-cn/blog/releases/_index.md b/content/zh-cn/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/zh-cn/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/zh-cn/docs/_index.md b/content/zh-cn/docs/_index.md
deleted file mode 100644
index 186c58595..000000000
--- a/content/zh-cn/docs/_index.md
+++ /dev/null
@@ -1,24 +0,0 @@
----
-title: "文档"
-linkTitle: "文档"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin 是什么?
-
-Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧。
-
-## 如何使用 Gin?
-
-我们提供了一些 API 的使用[示例](https://gin-gonic.com/zh-cn/docs/examples/) 并罗列了一些众所周知的 [Gin 用户](./users).
-
-## 如何为 Gin 做贡献?
-
-* 在社区帮助其他人
-* 告诉我们你使用 Gin 的成功案例
-* 告诉我们如何改善 Gin 并帮助我们实现它
-* 为已有的库做贡献
-
diff --git a/content/zh-cn/docs/benchmarks/_index.md b/content/zh-cn/docs/benchmarks/_index.md
deleted file mode 100644
index 01befee0a..000000000
--- a/content/zh-cn/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "基准测试"
-draft: false
-weight: 3
----
-
-Gin 使用了自定义版本的 [HttpRouter](https://github.com/julienschmidt/httprouter)
-
-[查看所有基准测试](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1):在一定的时间内实现的总调用数,越高越好
-- (2):单次操作耗时(ns/op),越低越好
-- (3):堆内存分配 (B/op), 越低越好
-- (4):每次操作的平均内存分配次数(allocs/op),越低越好
diff --git a/content/zh-cn/docs/deployment/_index.md b/content/zh-cn/docs/deployment/_index.md
deleted file mode 100644
index b21a73cb1..000000000
--- a/content/zh-cn/docs/deployment/_index.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "部署"
-draft: false
-weight: 6
----
-
-Gin 项目可以轻松部署在任何云提供商上。
-
-## [Render](https://render.com)
-
-Render 是一个原生支持 Go 的现代化云平台,并支持全托管 SSL、数据库、不停机部署、HTTP/2 和 websocket。
-
-参考 Render [Gin 项目部署指南](https://render.com/docs/deploy-go-gin)。
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE 提供了两种方式部署 Go 应用。标准环境,简单易用但可定制性较低,且出于安全考虑禁止 [syscalls](https://github.com/gin-gonic/gin/issues/1639)。灵活环境,可以运行任何框架和库。
-
-前往 [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/) 了解更多并选择你喜欢的环境。
diff --git a/content/zh-cn/docs/examples/_index.md b/content/zh-cn/docs/examples/_index.md
deleted file mode 100644
index 3d51b25b6..000000000
--- a/content/zh-cn/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "示例"
-draft: false
-weight: 6
----
-
-该节列出了 api 的用法。
diff --git a/content/zh-cn/docs/examples/ascii-json.md b/content/zh-cn/docs/examples/ascii-json.md
deleted file mode 100644
index cf4f4ee27..000000000
--- a/content/zh-cn/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-使用 AsciiJSON 生成具有转义的非 ASCII 字符的 ASCII-only JSON。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // 输出 : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md b/content/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index 12ae2352b..000000000
--- a/content/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,56 +0,0 @@
----
-title: "将 request body 绑定到不同的结构体中"
-draft: false
----
-
-一般通过调用 `c.Request.Body` 方法绑定数据,但不能多次调用这个方法。
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // c.ShouldBind 使用了 c.Request.Body,不可重用。
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // 因为现在 c.Request.Body 是 EOF,所以这里会报错。
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-要想多次绑定,可以使用 `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // 读取 c.Request.Body 并将结果存入上下文。
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // 这时, 复用存储在上下文中的 body。
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // 可以接受其他格式
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
-* 只有某些格式需要此功能,如 `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`。 对于其他格式, 如 `Query`, `Form`, `FormPost`, `FormMultipart`
-可以多次调用 `c.ShouldBind()` 而不会造成任任何性能损失 (详见 [#1341](https://github.com/gin-gonic/gin/pull/1341))。
diff --git a/content/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md b/content/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index cc69d2ccd..000000000
--- a/content/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,95 +0,0 @@
----
-title: "绑定表单数据至自定义结构体"
-draft: false
----
-
-以下示例使用自定义结构体:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-使用 `curl` 命令结果:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
-**注意**:不支持以下格式结构体:
-
-```go
-type StructX struct {
- X struct {} `form:"name_x"` // 有 form
-}
-
-type StructY struct {
- Y StructX `form:"name_y"` // 有 form
-}
-
-type StructZ struct {
- Z *StructZ `form:"name_z"` // 有 form
-}
-```
-
-总之, 目前仅支持没有 form 的嵌套结构体。
-
diff --git a/content/zh-cn/docs/examples/bind-html-checkbox.md b/content/zh-cn/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index 7585a646c..000000000
--- a/content/zh-cn/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "绑定 HTML 复选框"
-draft: false
----
-
-参见[详细信息](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-结果:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/zh-cn/docs/examples/bind-query-or-post.md b/content/zh-cn/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 6e2496a50..000000000
--- a/content/zh-cn/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "绑定查询字符串或表单数据"
-draft: false
----
-
-查看[详细信息](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292)。
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
- // 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON` 或 `XML`,然后再使用 `Form`(`form-data`)。
- // 查看更多:https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L88
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-测试:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/zh-cn/docs/examples/bind-single-binary-with-template.md b/content/zh-cn/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index ebcce3e94..000000000
--- a/content/zh-cn/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "静态资源嵌入"
-draft: false
----
-
-你可以使用 [go-assets](https://github.com/jessevdk/go-assets) 将静态资源打包到可执行文件中。
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate 加载由 go-assets-builder 嵌入的模板
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-请参阅 [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) 目录中的完整示例。
diff --git a/content/zh-cn/docs/examples/bind-uri.md b/content/zh-cn/docs/examples/bind-uri.md
deleted file mode 100644
index aaeca42b7..000000000
--- a/content/zh-cn/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "绑定 Uri"
-draft: false
----
-
-查看[详细信息](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err.Error()})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-测试:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/zh-cn/docs/examples/binding-and-validation.md b/content/zh-cn/docs/examples/binding-and-validation.md
deleted file mode 100644
index fae0de8c9..000000000
--- a/content/zh-cn/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,119 +0,0 @@
----
-title: "模型绑定和验证"
-draft: false
----
-
-要将请求体绑定到结构体中,使用模型绑定。 Gin目前支持JSON、XML、YAML和标准表单值的绑定(foo=bar&boo=baz)。
-
-Gin使用 [**go-playground/validator/v10**](https://github.com/go-playground/validator) 进行验证。 查看标签用法的全部[文档](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-使用时,需要在要绑定的所有字段上,设置相应的tag。 例如,使用 JSON 绑定时,设置字段标签为 `json:"fieldname"`。
-
-Gin提供了两类绑定方法:
-
-- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Behavior** - 这些方法属于 `MustBindWith` 的具体调用。 如果发生绑定错误,则请求终止,并触发 `c.AbortWithError(400, err).SetType(ErrorTypeBind)`。响应状态码被设置为 400 并且 `Content-Type` 被设置为 `text/plain; charset=utf-8`。 如果您在此之后尝试设置响应状态码,Gin会输出日志 `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`。 如果您希望更好地控制绑定,考虑使用 `ShouldBind` 等效方法。
-- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Behavior** - 这些方法属于 `ShouldBindWith` 的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。
-
-使用 Bind 方法时,Gin 会尝试根据 Content-Type 推断如何绑定。 如果你明确知道要绑定什么,可以使用 `MustBindWith` 或 `ShouldBindWith`。
-
-你也可以指定必须绑定的字段。 如果一个字段的 tag 加上了 `binding:"required"`,但绑定时是空值, Gin 会报错。
-
-```go
-// 绑定 JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // 绑定 JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // 绑定 XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // 绑定 HTML 表单 (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // 根据 Content-Type Header 推断使用哪个绑定器。
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- router.Run(":8080")
-}
-```
-
-#### 示例请求
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-#### 忽略验证
-
-使用上述的 `curl` 命令运行上面的示例时会返回错误。 因为示例中 `Password` 使用了 `binding:"required"`。 如果 `Password` 使用 `binding:"-"`, 再次运行上面的示例就不会返回错误。
diff --git a/content/zh-cn/docs/examples/controlling-log-output-coloring.md b/content/zh-cn/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 5d8788a33..000000000
--- a/content/zh-cn/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "控制日志输出颜色"
-draft: false
----
-
-根据检测到的 TTY,控制台的日志输出默认是有颜色的。
-
-禁止日志颜色化:
-
-```go
-func main() {
- // 禁止日志的颜色
- gin.DisableConsoleColor()
-
- // 用默认中间件创建一个 gin 路由:
- // 日志和恢复(无崩溃)中间件
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-日志颜色化:
-
-```go
-func main() {
- // 强制日志颜色化
- gin.ForceConsoleColor()
-
- // 用默认中间件创建一个 gin 路由:
- // 日志和恢复(无崩溃)中间件
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/cookie.md b/content/zh-cn/docs/examples/cookie.md
deleted file mode 100644
index 0f7bb56ac..000000000
--- a/content/zh-cn/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "设置和获取 Cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/zh-cn/docs/examples/custom-http-config.md b/content/zh-cn/docs/examples/custom-http-config.md
deleted file mode 100644
index bd0a2775f..000000000
--- a/content/zh-cn/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "自定义 HTTP 配置"
-draft: false
----
-
-直接使用 `http.ListenAndServe()`,如下所示:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-或
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/zh-cn/docs/examples/custom-log-format.md b/content/zh-cn/docs/examples/custom-log-format.md
deleted file mode 100644
index 10ad03a1b..000000000
--- a/content/zh-cn/docs/examples/custom-log-format.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "自定义日志文件"
-draft: false
----
-
-示例:
-
-```go
-func main() {
- router := gin.New()
- // LoggerWithFormatter 中间件会写入日志到 gin.DefaultWriter
- // 默认 gin.DefaultWriter = os.Stdout
- router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
- // 你的自定义格式
- return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
- param.ClientIP,
- param.TimeStamp.Format(time.RFC1123),
- param.Method,
- param.Path,
- param.Request.Proto,
- param.StatusCode,
- param.Latency,
- param.Request.UserAgent(),
- param.ErrorMessage,
- )
- }))
- router.Use(gin.Recovery())
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- router.Run(":8080")
-}
-```
-
-**输出**
-```
-::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
-```
diff --git a/content/zh-cn/docs/examples/custom-middleware.md b/content/zh-cn/docs/examples/custom-middleware.md
deleted file mode 100644
index 608be9498..000000000
--- a/content/zh-cn/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "自定义中间件"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // 设置 example 变量
- c.Set("example", "12345")
-
- // 请求前
-
- c.Next()
-
- // 请求后
- latency := time.Since(t)
- log.Print(latency)
-
- // 获取发送的 status
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // 打印:"12345"
- log.Println(example)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/custom-validators.md b/content/zh-cn/docs/examples/custom-validators.md
deleted file mode 100644
index 568704b02..000000000
--- a/content/zh-cn/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,67 +0,0 @@
----
-title: "自定义验证器"
-draft: false
----
-
-注册自定义验证器,查看[示例代码](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
-
-```go
-package main
-
-import (
- "net/http"
- "reflect"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking 包含绑定和验证的数据。
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
- date, ok := fl.Field().Interface().(time.Time)
- if ok {
- today := time.Now()
- if today.After(date) {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
-{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
-```
-
-[结构体级别的验证器](https://github.com/go-playground/validator/releases/tag/v8.7) 也可以通过其他的方式注册。更多信息请参阅 [struct-lvl-validation 示例](examples/struct-lvl-validations)。
diff --git a/content/zh-cn/docs/examples/define-format-for-the-log-of-routes.md b/content/zh-cn/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 9112801fe..000000000
--- a/content/zh-cn/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "定义路由日志的格式"
-draft: false
----
-
-默认的路由日志格式:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-如果你想要以指定的格式(例如 JSON,key values 或其他格式)记录信息,则可以使用 `gin.DebugPrintRouteFunc` 指定格式。
-在下面的示例中,我们使用标准日志包记录所有路由,但你可以使用其他满足你需求的日志工具。
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run()
-}
-```
diff --git a/content/zh-cn/docs/examples/goroutines-inside-a-middleware.md b/content/zh-cn/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index f5d367be8..000000000
--- a/content/zh-cn/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "在中间件中使用 Goroutine"
-draft: false
----
-
-当在中间件或 handler 中启动新的 Goroutine 时,**不能**使用原始的上下文,必须使用只读副本。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // 创建在 goroutine 中使用的副本
- cCp := c.Copy()
- go func() {
- // 用 time.Sleep() 模拟一个长任务。
- time.Sleep(5 * time.Second)
-
- // 请注意您使用的是复制的上下文 "cCp",这一点很重要
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // 用 time.Sleep() 模拟一个长任务。
- time.Sleep(5 * time.Second)
-
- // 因为没有使用 goroutine,不需要拷贝上下文
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/graceful-restart-or-stop.md b/content/zh-cn/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 11d2cb789..000000000
--- a/content/zh-cn/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,74 +0,0 @@
----
-title: "优雅地重启或停止"
-draft: false
----
-
-你想优雅地重启或停止 web 服务器吗?有一些方法可以做到这一点。
-
-我们可以使用 [fvbock/endless](https://github.com/fvbock/endless) 来替换默认的 `ListenAndServe`。更多详细信息,请参阅 issue [#296](https://github.com/gin-gonic/gin/issues/296)。
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-替代方案:
-
-* [manners](https://github.com/braintree/manners):可以优雅关机的 Go Http 服务器。
-* [graceful](https://github.com/tylerb/graceful):Graceful 是一个 Go 扩展包,可以优雅地关闭 http.Handler 服务器。
-* [grace](https://github.com/facebookgo/grace):Go 服务器平滑重启和零停机时间部署。
-
-如果你使用的是 Go 1.8,可以不需要这些库!考虑使用 http.Server 内置的 [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) 方法优雅地关机. 请参阅 gin 完整的 [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) 示例。
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // 服务连接
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
- quit := make(chan os.Signal, 1)
- signal.Notify(quit, os.Interrupt)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/grouping-routes.md b/content/zh-cn/docs/examples/grouping-routes.md
deleted file mode 100644
index 8df0d145a..000000000
--- a/content/zh-cn/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "路由组"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // 简单的路由组: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // 简单的路由组: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/html-rendering.md b/content/zh-cn/docs/examples/html-rendering.md
deleted file mode 100644
index a648697c5..000000000
--- a/content/zh-cn/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML 渲染"
-draft: false
----
-
-使用 LoadHTMLGlob() 或者 LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-使用不同目录下名称相同的模板
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-#### 自定义模板渲染器
-
-你可以使用自定义的 html 模板渲染
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-#### 自定义分隔符
-
-你可以使用自定义分隔
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-#### 自定义模板功能
-
-查看详细[示例代码](https://github.com/gin-gonic/examples/tree/master/template)。
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-结果:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/zh-cn/docs/examples/http-method.md b/content/zh-cn/docs/examples/http-method.md
deleted file mode 100644
index 31ec65a2c..000000000
--- a/content/zh-cn/docs/examples/http-method.md
+++ /dev/null
@@ -1,26 +0,0 @@
----
-title: "使用 HTTP 方法"
-draft: false
----
-
-```go
-func main() {
- // 禁用控制台颜色
- // gin.DisableConsoleColor()
-
- // 使用默认中间件(logger 和 recovery 中间件)创建 gin 路由
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // 默认在 8080 端口启动服务,除非定义了一个 PORT 的环境变量。
- router.Run()
- // router.Run(":3000") hardcode 端口号
-}
-```
diff --git a/content/zh-cn/docs/examples/http2-server-push.md b/content/zh-cn/docs/examples/http2-server-push.md
deleted file mode 100644
index bd24d4478..000000000
--- a/content/zh-cn/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server 推送"
-draft: false
----
-
-http.Pusher 仅支持 **go1.8+**。 更多信息,请查阅 [golang blog](https://blog.golang.org/h2push)。
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // 使用 pusher.Push() 做服务器推送
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // 监听并在 https://127.0.0.1:8080 上启动服务
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/jsonp.md b/content/zh-cn/docs/examples/jsonp.md
deleted file mode 100644
index e418dc218..000000000
--- a/content/zh-cn/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-使用 JSONP 向不同域的服务器请求数据。如果查询参数存在回调,则将回调添加到响应体中。
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- // /JSONP?callback=x
- // 将输出:x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/map-as-querystring-or-postform.md b/content/zh-cn/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index c4907a091..000000000
--- a/content/zh-cn/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "映射查询字符串或表单参数"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/zh-cn/docs/examples/multipart-urlencoded-binding.md b/content/zh-cn/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 1f2ceb48a..000000000
--- a/content/zh-cn/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded 绑定"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // 你可以使用显式绑定声明绑定 multipart form:
- // c.ShouldBindWith(&form, binding.Form)
- // 或者简单地使用 ShouldBind 方法自动绑定:
- var form LoginForm
- // 在这种情况下,将自动选择合适的绑定
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-测试:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/zh-cn/docs/examples/multipart-urlencoded-form.md b/content/zh-cn/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 0daac79b2..000000000
--- a/content/zh-cn/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded 表单"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/multiple-template.md b/content/zh-cn/docs/examples/multiple-template.md
deleted file mode 100644
index 9e7e7120f..000000000
--- a/content/zh-cn/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "多模板"
-draft: false
----
-
-Gin 默认允许只使用一个 html 模板。 查看[多模板渲染](https://github.com/gin-contrib/multitemplate) 以使用 go 1.6 `block template` 等功能。
diff --git a/content/zh-cn/docs/examples/only-bind-query-string.md b/content/zh-cn/docs/examples/only-bind-query-string.md
deleted file mode 100644
index 99a392bc4..000000000
--- a/content/zh-cn/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "只绑定 url 查询字符串"
-draft: false
----
-
-`ShouldBindQuery` 函数只绑定 url 查询参数而忽略 post 数据。参阅[详细信息](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/zh-cn/docs/examples/param-in-path.md b/content/zh-cn/docs/examples/param-in-path.md
deleted file mode 100644
index 3e710c813..000000000
--- a/content/zh-cn/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "路由参数"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // 此 handler 将匹配 /user/john 但不会匹配 /user/ 或者 /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // 此 handler 将匹配 /user/john/ 和 /user/john/send
- // 如果没有其他路由匹配 /user/john,它将重定向到 /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/pure-json.md b/content/zh-cn/docs/examples/pure-json.md
deleted file mode 100644
index c634f70d7..000000000
--- a/content/zh-cn/docs/examples/pure-json.md
+++ /dev/null
@@ -1,29 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-通常,JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c。如果要按字面对这些字符进行编码,则可以使用 PureJSON。Go 1.6 及更低版本无法使用此功能。
-
-```go
-func main() {
- r := gin.Default()
-
- // 提供 unicode 实体
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // 提供字面字符
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/query-and-post-form.md b/content/zh-cn/docs/examples/query-and-post-form.md
deleted file mode 100644
index 3893085af..000000000
--- a/content/zh-cn/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Query 和 post form"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/zh-cn/docs/examples/querystring-param.md b/content/zh-cn/docs/examples/querystring-param.md
deleted file mode 100644
index 0dc252880..000000000
--- a/content/zh-cn/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "查询字符串参数"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // 使用现有的基础请求对象解析查询字符串参数。
- // 示例 URL: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname") 的一种快捷方式
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/redirects.md b/content/zh-cn/docs/examples/redirects.md
deleted file mode 100644
index 5f6c243f7..000000000
--- a/content/zh-cn/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "重定向"
-draft: false
----
-
-HTTP 重定向很容易。 内部、外部重定向均支持。
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-通过 POST 方法进行 HTTP 重定向。请参考 issue:[#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-路由重定向,使用 `HandleContext`:
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/zh-cn/docs/examples/rendering.md b/content/zh-cn/docs/examples/rendering.md
deleted file mode 100644
index 83e49f39e..000000000
--- a/content/zh-cn/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf 渲染"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H 是 map[string]interface{} 的一种快捷方式
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // 你也可以使用一个结构体
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // 注意 msg.Name 在 JSON 中变成了 "user"
- // 将输出:{"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // protobuf 的具体定义写在 testdata/protoexample 文件中。
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // 请注意,数据在响应中变为二进制数据
- // 将输出被 protoexample.Test protobuf 序列化了的数据
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/run-multiple-service.md b/content/zh-cn/docs/examples/run-multiple-service.md
deleted file mode 100644
index a4f32c2c8..000000000
--- a/content/zh-cn/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "运行多个服务"
-draft: false
----
-
-请参阅 [issues](https://github.com/gin-gonic/gin/issues/346) 并尝试以下示例:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/zh-cn/docs/examples/secure-json.md b/content/zh-cn/docs/examples/secure-json.md
deleted file mode 100644
index a85559976..000000000
--- a/content/zh-cn/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-使用 SecureJSON 防止 json 劫持。如果给定的结构是数组值,则默认预置 `"while(1),"` 到响应体。
-
-```go
-func main() {
- r := gin.Default()
-
- // 你也可以使用自己的 SecureJSON 前缀
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // 将输出:while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/security-headers.md b/content/zh-cn/docs/examples/security-headers.md
deleted file mode 100644
index d3cf79085..000000000
--- a/content/zh-cn/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "安全页眉"
-draft: false
----
-
-使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-您可以通过 `curl` 进行测试。
-
-```bash
-// 检查页眉
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// 检查主机标头注入
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/zh-cn/docs/examples/serving-data-from-reader.md b/content/zh-cn/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index 2f0baadbd..000000000
--- a/content/zh-cn/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "从 reader 读取数据"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/serving-static-files.md b/content/zh-cn/docs/examples/serving-static-files.md
deleted file mode 100644
index d96099df0..000000000
--- a/content/zh-cn/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "静态文件服务"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // 监听并在 0.0.0.0:8080 上启动服务
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/support-lets-encrypt.md b/content/zh-cn/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index 54707824a..000000000
--- a/content/zh-cn/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "支持 Let's Encrypt"
-draft: false
----
-
-一行代码支持 LetsEncrypt HTTPS servers 示例。
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-自定义 autocert manager 示例。
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/zh-cn/docs/examples/upload-file/_index.md b/content/zh-cn/docs/examples/upload-file/_index.md
deleted file mode 100644
index 4cc95382b..000000000
--- a/content/zh-cn/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "上传文件"
-draft: false
----
-
-本节列出了上传图片的 api 用法。
diff --git a/content/zh-cn/docs/examples/upload-file/multiple-file.md b/content/zh-cn/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 3196c76a8..000000000
--- a/content/zh-cn/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,38 +0,0 @@
----
-title: "多文件"
-draft: false
----
-
-查看详细[示例代码](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // 上传文件至指定目录
- dst := "./" + file.Filename
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-如何使用 `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/zh-cn/docs/examples/upload-file/single-file.md b/content/zh-cn/docs/examples/upload-file/single-file.md
deleted file mode 100644
index d0c6ed594..000000000
--- a/content/zh-cn/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,34 +0,0 @@
----
-title: "单文件"
-draft: false
----
-
-参考 issue [#774](https://github.com/gin-gonic/gin/issues/774) 和详细[示例代码](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
-
-```go
-func main() {
- router := gin.Default()
- // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // 单文件
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- dst := "./" + file.Filename
- // 上传文件至指定的完整文件路径
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-如何使用 `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/zh-cn/docs/examples/using-basicauth-middleware.md b/content/zh-cn/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index e0aad8033..000000000
--- a/content/zh-cn/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "使用 BasicAuth 中间件"
-draft: false
----
-
-```go
-// 模拟一些私人数据
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // 路由组使用 gin.BasicAuth() 中间件
- // gin.Accounts 是 map[string]string 的一种快捷方式
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets 端点
- // 触发 "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // 获取用户,它是由 BasicAuth 中间件设置的
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/examples/using-middleware.md b/content/zh-cn/docs/examples/using-middleware.md
deleted file mode 100644
index 3d2ab1b47..000000000
--- a/content/zh-cn/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "使用中间件"
-draft: false
----
-
-```go
-func main() {
- // 新建一个没有任何默认中间件的路由
- r := gin.New()
-
- // 全局中间件
- // Logger 中间件将日志写入 gin.DefaultWriter,即使你将 GIN_MODE 设置为 release。
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500。
- r.Use(gin.Recovery())
-
- // 你可以为每个路由添加任意数量的中间件。
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // 认证路由组
- // authorized := r.Group("/", AuthRequired())
- // 和使用以下两行代码的效果完全一样:
- authorized := r.Group("/")
- // 路由组中间件! 在此例中,我们在 "authorized" 路由组中使用自定义创建的
- // AuthRequired() 中间件
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // 嵌套路由组
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // 监听并在 0.0.0.0:8080 上启动服务
- r.Run(":8080")
-}
-```
-
diff --git a/content/zh-cn/docs/examples/without-middleware.md b/content/zh-cn/docs/examples/without-middleware.md
deleted file mode 100644
index 17ebcbb64..000000000
--- a/content/zh-cn/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "不使用默认的中间件"
-draft: false
----
-
-使用
-
-```go
-r := gin.New()
-```
-
-代替
-
-```go
-// Default 使用 Logger 和 Recovery 中间件
-r := gin.Default()
-```
diff --git a/content/zh-cn/docs/examples/write-log.md b/content/zh-cn/docs/examples/write-log.md
deleted file mode 100644
index 133c7fa94..000000000
--- a/content/zh-cn/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "如何记录日志"
-draft: false
----
-
-```go
-func main() {
- // 禁用控制台颜色,将日志写入文件时不需要控制台颜色。
- gin.DisableConsoleColor()
-
- // 记录到文件。
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // 如果需要同时将日志写入文件和控制台,请使用以下代码。
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-cn/docs/faq/_index.md b/content/zh-cn/docs/faq/_index.md
deleted file mode 100644
index 8ceb3210a..000000000
--- a/content/zh-cn/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO:记录 GitHub Issue 中的一些常见问题。
-
diff --git a/content/zh-cn/docs/features/_index.md b/content/zh-cn/docs/features/_index.md
deleted file mode 100644
index 561e5a135..000000000
--- a/content/zh-cn/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "特性"
-draft: false
-weight: 4
----
-
-##### Gin v1 稳定的特性:
-
-- 零分配路由。
-
-- 仍然是最快的 http 路由器和框架。
-
-- 完整的单元测试支持。
-
-- 实战考验。
-
-- API 冻结,新版本的发布不会破坏你的代码。
diff --git a/content/zh-cn/docs/introduction/_index.md b/content/zh-cn/docs/introduction/_index.md
deleted file mode 100644
index 9fb679eb4..000000000
--- a/content/zh-cn/docs/introduction/_index.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "介绍"
-draft: false
-weight: 1
----
-Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 [httprouter](https://github.com/julienschmidt/httprouter),速度提高了 40 倍。 如果您需要性能和良好的生产力,您一定会喜欢 Gin。
-
-在本节中,我们将介绍 Gin 是什么,它解决了哪些问题,以及它如何帮助你的项目。
-
-或者, 如果你已经准备在项目中使用 Gin,请访问[快速入门](https://gin-gonic.com/zh-cn/docs/quickstart/).
-
-## 特性
-
-### 快速
-
-基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
-
-### 支持中间件
-
-传入的 HTTP 请求可以由一系列中间件和最终操作来处理。
-例如:Logger,Authorization,GZIP,最终操作 DB。
-
-### Crash 处理
-
-Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!
-
-### JSON 验证
-
-Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
-
-### 路由组
-
-更好地组织路由。是否需要授权,不同的 API 版本...... 此外,这些组可以无限制地嵌套而不会降低性能。
-
-### 错误管理
-
-Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
-
-### 内置渲染
-
-Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
-
-### 可扩展性
-
-新建一个中间件非常简单,去查看[示例代码](https://gin-gonic.com/zh-cn/docs/examples/using-middleware/)吧。
diff --git a/content/zh-cn/docs/jsoniter/_index.md b/content/zh-cn/docs/jsoniter/_index.md
deleted file mode 100644
index 29580cc1e..000000000
--- a/content/zh-cn/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-#### 使用 [jsoniter](https://github.com/json-iterator/go) 编译
-
-Gin 使用 `encoding/json` 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 [jsoniter](https://github.com/json-iterator/go)。
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/zh-cn/docs/quickstart/_index.md b/content/zh-cn/docs/quickstart/_index.md
deleted file mode 100644
index ba76a0d02..000000000
--- a/content/zh-cn/docs/quickstart/_index.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "快速入门"
-draft: false
-weight: 2
----
-
-## 要求
-
-- Go 1.16 及以上版本
-
-## 安装
-
-要安装 Gin 软件包,需要先安装 Go 并设置 Go 工作区。
-
-1.下载并安装 gin:
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2.将 gin 引入到代码中:
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3.(可选)如果使用诸如 `http.StatusOK` 之类的常量,则需要引入 `net/http` 包:
-
-```go
-import "net/http"
-```
-
-1. 创建你的项目文件夹并 `cd` 进去
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
-```
-
-2. 拷贝一个初始模板到你的项目里
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-3. 运行你的项目
-
-```sh
-$ go run main.go
-```
-
-## 开始
-
-> 不确定如何编写和执行 Go 代码? [点击这里](https://golang.org/doc/code.html).
-
-首先,创建一个名为 `example.go` 的文件
-
-```sh
-$ touch example.go
-```
-
-接下来, 将如下的代码写入 `example.go` 中:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // 监听并在 0.0.0.0:8080 上启动服务
-}
-```
-
-然后, 执行 `go run example.go` 命令来运行代码:
-
-```sh
-# 运行 example.go 并且在浏览器中访问 HOST_IP:8080/ping
-$ go run example.go
-```
diff --git a/content/zh-cn/docs/testing/_index.md b/content/zh-cn/docs/testing/_index.md
deleted file mode 100644
index afa66e6aa..000000000
--- a/content/zh-cn/docs/testing/_index.md
+++ /dev/null
@@ -1,92 +0,0 @@
----
-title: "测试"
-draft: false
-weight: 7
----
-
-##### 怎样编写 Gin 的测试用例
-
-HTTP 测试首选 `net/http/httptest` 包。
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-上面这段代码的测试用例:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
-
-
-
diff --git a/content/zh-cn/docs/users/_index.md b/content/zh-cn/docs/users/_index.md
deleted file mode 100644
index 0a7ecc649..000000000
--- a/content/zh-cn/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "用户"
-draft: false
-weight: 8
----
-
-##### 使用 [Gin](https://github.com/gin-gonic/gin) web 框架的知名项目:
-
-* [gorush](https://github.com/appleboy/gorush):Go 编写的通知推送服务器。
-
-* [fnproject](https://github.com/fnproject/fn):原生容器,云 serverless 平台。
-
-* [photoprism](https://github.com/photoprism/photoprism):由 Go 和 Google TensorFlow 提供支持的个人照片管理工具。
-
-* [krakend](https://github.com/devopsfaith/krakend):拥有中间件的超高性能 API 网关。
-
-* [picfit](https://github.com/thoas/picfit):Go 编写的图像尺寸调整服务器。
-
-* [gotify](https://github.com/gotify/server):使用实时 web socket 做消息收发的简单服务器。
-
-* [cds](https://github.com/ovh/cds):企业级持续交付和 DevOps 自动化开源平台。
diff --git a/content/zh-cn/search.md b/content/zh-cn/search.md
deleted file mode 100644
index 40963495f..000000000
--- a/content/zh-cn/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: 搜索结果
-layout: search
----
-
diff --git a/content/zh-tw/_index.html b/content/zh-tw/_index.html
deleted file mode 100644
index ec687dee2..000000000
--- a/content/zh-tw/_index.html
+++ /dev/null
@@ -1,77 +0,0 @@
-+++
-title = "Gin Web Framework"
-linkTitle = "Gin Web Framework"
-+++
-
-{{< blocks/cover title="Gin Web Framework" image_anchor="top" height="full" color="orange" >}}
-
-{{< /blocks/cover >}}
-
-{{% blocks/lead color="white" %}}
-
-**什麼是Gin?**
-
-Gin是一個使用Go語言開發的Web框架。
-
-它提供類似Martini的API,但性能更佳,速度提升高達40倍。
-
-如果你是性能和高效的追求者, 你會愛上 Gin。
-
-{{% /blocks/lead %}}
-
-{{< blocks/section color="light" >}}
-
-{{% blocks/feature icon="fa fa-tachometer-alt" title="快速" %}}
-基於 Radix 樹的路由,小內存佔用。沒有反射。可預測的 API 性能。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-bars" title="支持中間件" %}}
-傳入的 HTTP 請求可以由一系列中間件和最終操作來處理。
-例如:Logger,Authorization,GZIP,最終操作 DB。
-
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-life-ring" title="Crash 處理" %}}
-Gin 可以 catch 一個發生在 HTTP 請求中的 panic 並 recover 它。這樣,你的服務器將始終可用。例如,你可以向 Sentry 報告這個 panic!
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="white" >}}
-
-{{% blocks/feature icon="fa fa-check-circle" title="JSON 驗證" %}}
-Gin 可以解析並驗證請求的 JSON,例如檢查所需值的存在。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-users-cog" title="路由組" %}}
-Gin幫助您更好地組織您的路由,例如,按照需要授權和不需要授權和不同API版本進行分組。此外,路由分組可以無限嵌套而不降低性能。
-{{% /blocks/feature %}}
-
-
-{{% blocks/feature icon="fa fa-briefcase" title="錯誤管理" %}}
-Gin 提供了一種方便的方法來收集 HTTP 請求期間發生的所有錯誤。最終,中間件可以將它們寫入日誌文件,數據庫並通過網絡發送。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
-
-{{< blocks/section color="info" >}}
-
-{{% blocks/feature icon="fa fa-images" title="內置渲染" %}}
-Gin 為 JSON,XML 和 HTML 渲染提供了易於使用的 API。
-{{% /blocks/feature %}}
-
-{{% blocks/feature icon="fa fa-code" title="可擴展性" %}}
-新建一個中間件非常簡單,去查看[示例代碼](https://gin-gonic.com/zh-tw/docs/examples/using-middleware/)吧。
-{{% /blocks/feature %}}
-
-{{< /blocks/section >}}
\ No newline at end of file
diff --git a/content/zh-tw/blog/_index.md b/content/zh-tw/blog/_index.md
deleted file mode 100644
index bfe08e93d..000000000
--- a/content/zh-tw/blog/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Blog"
-linkTitle: "Blog"
-menu:
- main:
- weight: 30
----
-
-
-This is the **blog** section. It has two categories: News and Releases.
-
-Files in these directories will be listed in reverse chronological order.
-
diff --git a/content/zh-tw/blog/news/_index.md b/content/zh-tw/blog/news/_index.md
deleted file mode 100644
index 6d6f3ad0a..000000000
--- a/content/zh-tw/blog/news/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "News"
-linkTitle: "News"
-weight: 20
----
-
-
diff --git a/content/zh-tw/blog/releases/_index.md b/content/zh-tw/blog/releases/_index.md
deleted file mode 100644
index 2e7b975d9..000000000
--- a/content/zh-tw/blog/releases/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
-
----
-title: "Releases"
-linkTitle: "Releases"
-weight: 20
----
-
-
diff --git a/content/zh-tw/docs/_index.md b/content/zh-tw/docs/_index.md
deleted file mode 100644
index 3ab17ab71..000000000
--- a/content/zh-tw/docs/_index.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "文件"
-linkTitle: "文件"
-weight: 20
-menu:
- main:
- weight: 20
----
-
-## Gin 是什麼?
-
-Gin 是一個使用 Go (Golang) 寫的 HTTP Web 框架。它提供類似 Martini 的 API,但擁有更好的效能——速度快上了 40 倍。如果你需要震撼性的效能,給自己來點 Gin 吧。
-
-## 如何使用 Gin?
-
-我們提供了一些 API 使用 [範例](https://github.com/gin-gonic/examples) 並列出一些知名的 [Gin 使用者](./users).
-
-## 如何對 Gin 做出貢獻?
-
-* 在論壇上幫助人們
-* 告訴我們你使用 Gin 的成功故事
-* 告訴我們如何可以改進 Gin 並且幫助我們達成
-* 貢獻現有程式庫
diff --git a/content/zh-tw/docs/benchmarks/_index.md b/content/zh-tw/docs/benchmarks/_index.md
deleted file mode 100644
index dabba65c8..000000000
--- a/content/zh-tw/docs/benchmarks/_index.md
+++ /dev/null
@@ -1,47 +0,0 @@
----
-title: "效能評估"
-draft: false
-weight: 3
----
-
-Gin 使用自訂版本的 [HttpRouter](https://github.com/julienschmidt/httprouter)
-
-[查看所有效能評估](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
-
-| Benchmark name | (1) | (2) | (3) | (4) |
-| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
-| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
-| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
-| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
-| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
-| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
-| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
-| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
-| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
-| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
-| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
-| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
-| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
-| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
-| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
-| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
-| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
-| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
-| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
-| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
-| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
-| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
-| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
-| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
-| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
-| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
-| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
-
-- (1)在固定時間內達到的重複執行次數,數值越高代表對結果越有信心
-- (2)單次執行所需時間(ns/op),數值越低越好
-- (3)使用的 Heap 記憶體(B/op),數值越低越好
-- (4)每次執行的平均配置次數(allocs/op),數值越低越好
diff --git a/content/zh-tw/docs/deployment/_index.md b/content/zh-tw/docs/deployment/_index.md
deleted file mode 100644
index 93066dc31..000000000
--- a/content/zh-tw/docs/deployment/_index.md
+++ /dev/null
@@ -1,19 +0,0 @@
----
-title: "部署"
-draft: false
-weight: 6
----
-
-Gin 專案可以輕鬆部署到任意雲主機商。
-
-## [Render](https://render.com)
-
-Render 是一個原生支援 Go 語言的現代化雲平台,並支持管理 SSL、資料庫、不停機部署、HTTP/2 和 websocket。
-
-請參考 Render 文件[部署 Gin 專案](https://render.com/docs/deploy-go-gin).
-
-## [Google App Engine](https://cloud.google.com/appengine/)
-
-GAE 提供兩種方式部署 Go 應用。標準環境簡單使用但是比較客製化,且出於安全考量禁止使用 [syscalls](https://github.com/gin-gonic/gin/issues/1639)。在靈活的還輕可以運行任何框架跟套件。
-
-前往 [Google App Engine](https://cloud.google.com/appengine/docs/go/) 了解更多並選擇您喜歡的環境。
diff --git a/content/zh-tw/docs/examples/_index.md b/content/zh-tw/docs/examples/_index.md
deleted file mode 100644
index 172163f92..000000000
--- a/content/zh-tw/docs/examples/_index.md
+++ /dev/null
@@ -1,7 +0,0 @@
----
-title: "範例"
-draft: false
-weight: 6
----
-
-這個章節列出一些 API 使用方法。
diff --git a/content/zh-tw/docs/examples/ascii-json.md b/content/zh-tw/docs/examples/ascii-json.md
deleted file mode 100644
index 82ab48d2a..000000000
--- a/content/zh-tw/docs/examples/ascii-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "AsciiJSON"
-draft: false
----
-
-Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/someJSON", func(c *gin.Context) {
- data := map[string]interface{}{
- "lang": "GO语言",
- "tag": "
",
- }
-
- // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
- c.AsciiJSON(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md b/content/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md
deleted file mode 100644
index c685ccaba..000000000
--- a/content/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md
+++ /dev/null
@@ -1,61 +0,0 @@
----
-title: "Try to bind body into different structs"
-draft: false
----
-
-The normal methods for binding request body consumes `c.Request.Body` and they
-cannot be called multiple times.
-
-```go
-type formA struct {
- Foo string `json:"foo" xml:"foo" binding:"required"`
-}
-
-type formB struct {
- Bar string `json:"bar" xml:"bar" binding:"required"`
-}
-
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
- if errA := c.ShouldBind(&objA); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // Always an error is occurred by this because c.Request.Body is EOF now.
- } else if errB := c.ShouldBind(&objB); errB == nil {
- c.String(http.StatusOK, `the body should be formB`)
- } else {
- ...
- }
-}
-```
-
-For this, you can use `c.ShouldBindBodyWith`.
-
-```go
-func SomeHandler(c *gin.Context) {
- objA := formA{}
- objB := formB{}
- // This reads c.Request.Body and stores the result into the context.
- if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
- c.String(http.StatusOK, `the body should be formA`)
- // At this time, it reuses body stored in the context.
- } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
- c.String(http.StatusOK, `the body should be formB JSON`)
- // And it can accepts other formats
- } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
- c.String(http.StatusOK, `the body should be formB XML`)
- } else {
- ...
- }
-}
-```
-
-* `c.ShouldBindBodyWith` stores body into the context before binding. This has
-a slight impact to performance, so you should not use this method if you are
-enough to call binding at once.
-* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
-`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
-can be called by `c.ShouldBind()` multiple times without any damage to
-performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
-
diff --git a/content/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md b/content/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md
deleted file mode 100644
index a6a04815e..000000000
--- a/content/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md
+++ /dev/null
@@ -1,95 +0,0 @@
----
-title: "Bind form-data request with custom struct"
-draft: false
----
-
-The follow example using custom struct:
-
-```go
-type StructA struct {
- FieldA string `form:"field_a"`
-}
-
-type StructB struct {
- NestedStruct StructA
- FieldB string `form:"field_b"`
-}
-
-type StructC struct {
- NestedStructPointer *StructA
- FieldC string `form:"field_c"`
-}
-
-type StructD struct {
- NestedAnonyStruct struct {
- FieldX string `form:"field_x"`
- }
- FieldD string `form:"field_d"`
-}
-
-func GetDataB(c *gin.Context) {
- var b StructB
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStruct,
- "b": b.FieldB,
- })
-}
-
-func GetDataC(c *gin.Context) {
- var b StructC
- c.Bind(&b)
- c.JSON(200, gin.H{
- "a": b.NestedStructPointer,
- "c": b.FieldC,
- })
-}
-
-func GetDataD(c *gin.Context) {
- var b StructD
- c.Bind(&b)
- c.JSON(200, gin.H{
- "x": b.NestedAnonyStruct,
- "d": b.FieldD,
- })
-}
-
-func main() {
- r := gin.Default()
- r.GET("/getb", GetDataB)
- r.GET("/getc", GetDataC)
- r.GET("/getd", GetDataD)
-
- r.Run()
-}
-```
-
-Using the command `curl` command result:
-
-```
-$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
-{"a":{"FieldA":"hello"},"b":"world"}
-$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
-{"a":{"FieldA":"hello"},"c":"world"}
-$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
-{"d":"world","x":{"FieldX":"hello"}}
-```
-
-**NOTE**: NOT support the follow style struct:
-
-```go
-type StructX struct {
- X struct {} `form:"name_x"` // HERE have form
-}
-
-type StructY struct {
- Y StructX `form:"name_y"` // HERE have form
-}
-
-type StructZ struct {
- Z *StructZ `form:"name_z"` // HERE have form
-}
-```
-
-In a word, only support nested custom struct which have no `form` now.
-
diff --git a/content/zh-tw/docs/examples/bind-html-checkbox.md b/content/zh-tw/docs/examples/bind-html-checkbox.md
deleted file mode 100644
index ae63e1f60..000000000
--- a/content/zh-tw/docs/examples/bind-html-checkbox.md
+++ /dev/null
@@ -1,49 +0,0 @@
----
-title: "Bind html checkboxes"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
-
-main.go
-
-```go
-...
-
-type myForm struct {
- Colors []string `form:"colors[]"`
-}
-
-...
-
-func formHandler(c *gin.Context) {
- var fakeForm myForm
- c.ShouldBind(&fakeForm)
- c.JSON(200, gin.H{"color": fakeForm.Colors})
-}
-
-...
-
-```
-
-form.html
-
-```html
-
-```
-
-result:
-
-```sh
-{"color":["red","green","blue"]}
-```
-
diff --git a/content/zh-tw/docs/examples/bind-query-or-post.md b/content/zh-tw/docs/examples/bind-query-or-post.md
deleted file mode 100644
index 7ebbe739c..000000000
--- a/content/zh-tw/docs/examples/bind-query-or-post.md
+++ /dev/null
@@ -1,48 +0,0 @@
----
-title: "Bind query string or post data"
-draft: false
----
-
-See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
-
-```go
-package main
-
-import (
- "log"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
- Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- // If `GET`, only `Form` binding engine (`query`) used.
- // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
- // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
- if c.ShouldBind(&person) == nil {
- log.Println(person.Name)
- log.Println(person.Address)
- log.Println(person.Birthday)
- }
-
- c.String(200, "Success")
-}
-```
-
-Test it with:
-```sh
-$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
-```
diff --git a/content/zh-tw/docs/examples/bind-single-binary-with-template.md b/content/zh-tw/docs/examples/bind-single-binary-with-template.md
deleted file mode 100644
index 018e05816..000000000
--- a/content/zh-tw/docs/examples/bind-single-binary-with-template.md
+++ /dev/null
@@ -1,46 +0,0 @@
----
-title: "Build a single binary with templates"
-draft: false
----
-
-You can build a server into a single binary containing templates by using [go-assets][].
-
-[go-assets]: https://github.com/jessevdk/go-assets
-
-```go
-func main() {
- r := gin.New()
-
- t, err := loadTemplate()
- if err != nil {
- panic(err)
- }
- r.SetHTMLTemplate(t)
-
- r.GET("/", func(c *gin.Context) {
- c.HTML(http.StatusOK, "/html/index.tmpl", nil)
- })
- r.Run(":8080")
-}
-
-// loadTemplate loads templates embedded by go-assets-builder
-func loadTemplate() (*template.Template, error) {
- t := template.New("")
- for name, file := range Assets.Files {
- if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
- continue
- }
- h, err := ioutil.ReadAll(file)
- if err != nil {
- return nil, err
- }
- t, err = t.New(name).Parse(string(h))
- if err != nil {
- return nil, err
- }
- }
- return t, nil
-}
-```
-
-See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/content/zh-tw/docs/examples/bind-uri.md b/content/zh-tw/docs/examples/bind-uri.md
deleted file mode 100644
index ec1211cb7..000000000
--- a/content/zh-tw/docs/examples/bind-uri.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Bind Uri"
-draft: false
----
-
-查看[詳細訊息](https://github.com/gin-gonic/gin/issues/846).
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type Person struct {
- ID string `uri:"id" binding:"required,uuid"`
- Name string `uri:"name" binding:"required"`
-}
-
-func main() {
- route := gin.Default()
- route.GET("/:name/:id", func(c *gin.Context) {
- var person Person
- if err := c.ShouldBindUri(&person); err != nil {
- c.JSON(400, gin.H{"msg": err})
- return
- }
- c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
- })
- route.Run(":8088")
-}
-```
-
-測試:
-
-```sh
-$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
-$ curl -v localhost:8088/thinkerou/not-uuid
-```
diff --git a/content/zh-tw/docs/examples/binding-and-validation.md b/content/zh-tw/docs/examples/binding-and-validation.md
deleted file mode 100644
index a45fa875f..000000000
--- a/content/zh-tw/docs/examples/binding-and-validation.md
+++ /dev/null
@@ -1,118 +0,0 @@
----
-title: "Model binding and validation"
-draft: false
----
-
-To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
-
-Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
-
-Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
-
-Also, Gin provides two sets of methods for binding:
-- **Type** - Must bind
- - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
- - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
-- **Type** - Should bind
- - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
- - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
-
-When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
-
-You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
-
-```go
-// Binding from JSON
-type Login struct {
- User string `form:"user" json:"user" xml:"user" binding:"required"`
- Password string `form:"password" json:"password" xml:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
-
- // Example for binding JSON ({"user": "manu", "password": "123"})
- router.POST("/loginJSON", func(c *gin.Context) {
- var json Login
- if err := c.ShouldBindJSON(&json); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if json.User != "manu" || json.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding XML (
- //
- //
- // manu
- // 123
- // )
- router.POST("/loginXML", func(c *gin.Context) {
- var xml Login
- if err := c.ShouldBindXML(&xml); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if xml.User != "manu" || xml.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Example for binding a HTML form (user=manu&password=123)
- router.POST("/loginForm", func(c *gin.Context) {
- var form Login
- // This will infer what binder to use depending on the content-type header.
- if err := c.ShouldBind(&form); err != nil {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- return
- }
-
- if form.User != "manu" || form.Password != "123" {
- c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
- return
- }
-
- c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
- })
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
-
-#### Sample request
-
-```sh
-$ curl -v -X POST \
- http://localhost:8080/loginJSON \
- -H 'content-type: application/json' \
- -d '{ "user": "manu" }'
-> POST /loginJSON HTTP/1.1
-> Host: localhost:8080
-> User-Agent: curl/7.51.0
-> Accept: */*
-> content-type: application/json
-> Content-Length: 18
->
-* upload completely sent off: 18 out of 18 bytes
-< HTTP/1.1 400 Bad Request
-< Content-Type: application/json; charset=utf-8
-< Date: Fri, 04 Aug 2017 03:51:31 GMT
-< Content-Length: 100
-<
-{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
-```
-
-#### Skip validate
-
-When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/content/zh-tw/docs/examples/controlling-log-output-coloring.md b/content/zh-tw/docs/examples/controlling-log-output-coloring.md
deleted file mode 100644
index 2edb50591..000000000
--- a/content/zh-tw/docs/examples/controlling-log-output-coloring.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "Controlling Log output coloring"
-draft: false
----
-
-By default, logs output on console should be colorized depending on the detected TTY.
-
-Never colorize logs:
-
-```go
-func main() {
- // Disable log's color
- gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
-Always colorize logs:
-
-```go
-func main() {
- // Force log's color
- gin.ForceConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/cookie.md b/content/zh-tw/docs/examples/cookie.md
deleted file mode 100644
index 231473ca5..000000000
--- a/content/zh-tw/docs/examples/cookie.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Set and get a cookie"
-draft: false
----
-
-```go
-import (
- "fmt"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
-
- router := gin.Default()
-
- router.GET("/cookie", func(c *gin.Context) {
-
- cookie, err := c.Cookie("gin_cookie")
-
- if err != nil {
- cookie = "NotSet"
- c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
- }
-
- fmt.Printf("Cookie value: %s \n", cookie)
- })
-
- router.Run()
-}
-```
diff --git a/content/zh-tw/docs/examples/custom-http-config.md b/content/zh-tw/docs/examples/custom-http-config.md
deleted file mode 100644
index e9a679361..000000000
--- a/content/zh-tw/docs/examples/custom-http-config.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Custom HTTP configuration"
-draft: false
----
-
-Use `http.ListenAndServe()` directly, like this:
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
- http.ListenAndServe(":8080", router)
-}
-```
-or
-
-```go
-import "net/http"
-
-func main() {
- router := gin.Default()
-
- s := &http.Server{
- Addr: ":8080",
- Handler: router,
- ReadTimeout: 10 * time.Second,
- WriteTimeout: 10 * time.Second,
- MaxHeaderBytes: 1 << 20,
- }
- s.ListenAndServe()
-}
-```
diff --git a/content/zh-tw/docs/examples/custom-middleware.md b/content/zh-tw/docs/examples/custom-middleware.md
deleted file mode 100644
index dd7407b07..000000000
--- a/content/zh-tw/docs/examples/custom-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Custom Middleware"
-draft: false
----
-
-```go
-func Logger() gin.HandlerFunc {
- return func(c *gin.Context) {
- t := time.Now()
-
- // Set example variable
- c.Set("example", "12345")
-
- // before request
-
- c.Next()
-
- // after request
- latency := time.Since(t)
- log.Print(latency)
-
- // access the status we are sending
- status := c.Writer.Status()
- log.Println(status)
- }
-}
-
-func main() {
- r := gin.New()
- r.Use(Logger())
-
- r.GET("/test", func(c *gin.Context) {
- example := c.MustGet("example").(string)
-
- // it would print: "12345"
- log.Println(example)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/custom-validators.md b/content/zh-tw/docs/examples/custom-validators.md
deleted file mode 100644
index f69372982..000000000
--- a/content/zh-tw/docs/examples/custom-validators.md
+++ /dev/null
@@ -1,70 +0,0 @@
----
-title: "Custom validators"
-draft: false
----
-
-It is also possible to register custom validators. See the [example code](examples/custom-validation/server.go).
-
-```go
-package main
-
-import (
- "net/http"
- "reflect"
- "time"
-
- "github.com/gin-gonic/gin"
- "github.com/gin-gonic/gin/binding"
- "github.com/go-playground/validator/v10"
-)
-
-// Booking contains binded and validated data.
-type Booking struct {
- CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
- CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
-}
-
-func bookableDate(
- v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
- field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
-) bool {
- if date, ok := field.Interface().(time.Time); ok {
- today := time.Now()
- if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
- return false
- }
- }
- return true
-}
-
-func main() {
- route := gin.Default()
-
- if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
- v.RegisterValidation("bookabledate", bookableDate)
- }
-
- route.GET("/bookable", getBookable)
- route.Run(":8085")
-}
-
-func getBookable(c *gin.Context) {
- var b Booking
- if err := c.ShouldBindWith(&b, binding.Query); err == nil {
- c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
- } else {
- c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
- }
-}
-```
-
-```sh
-$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
-{"message":"Booking dates are valid!"}
-
-$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
-{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
-```
-
-[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
-See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
diff --git a/content/zh-tw/docs/examples/define-format-for-the-log-of-routes.md b/content/zh-tw/docs/examples/define-format-for-the-log-of-routes.md
deleted file mode 100644
index 6cfdaa68f..000000000
--- a/content/zh-tw/docs/examples/define-format-for-the-log-of-routes.md
+++ /dev/null
@@ -1,44 +0,0 @@
----
-title: "Define format for the log of routes"
-draft: false
----
-
-The default log of routes is:
-```
-[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
-[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
-[GIN-debug] GET /status --> main.main.func3 (3 handlers)
-```
-
-If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
-In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
-```go
-import (
- "log"
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
- gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
- log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
- }
-
- r.POST("/foo", func(c *gin.Context) {
- c.JSON(http.StatusOK, "foo")
- })
-
- r.GET("/bar", func(c *gin.Context) {
- c.JSON(http.StatusOK, "bar")
- })
-
- r.GET("/status", func(c *gin.Context) {
- c.JSON(http.StatusOK, "ok")
- })
-
- // Listen and Server in http://0.0.0.0:8080
- r.Run()
-}
-```
diff --git a/content/zh-tw/docs/examples/goroutines-inside-a-middleware.md b/content/zh-tw/docs/examples/goroutines-inside-a-middleware.md
deleted file mode 100644
index 122593a1b..000000000
--- a/content/zh-tw/docs/examples/goroutines-inside-a-middleware.md
+++ /dev/null
@@ -1,35 +0,0 @@
----
-title: "Goroutines inside a middleware"
-draft: false
----
-
-When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/long_async", func(c *gin.Context) {
- // create copy to be used inside the goroutine
- cCp := c.Copy()
- go func() {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // note that you are using the copied context "cCp", IMPORTANT
- log.Println("Done! in path " + cCp.Request.URL.Path)
- }()
- })
-
- r.GET("/long_sync", func(c *gin.Context) {
- // simulate a long task with time.Sleep(). 5 seconds
- time.Sleep(5 * time.Second)
-
- // since we are NOT using a goroutine, we do not have to copy the context
- log.Println("Done! in path " + c.Request.URL.Path)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/graceful-restart-or-stop.md b/content/zh-tw/docs/examples/graceful-restart-or-stop.md
deleted file mode 100644
index 5b87a0621..000000000
--- a/content/zh-tw/docs/examples/graceful-restart-or-stop.md
+++ /dev/null
@@ -1,76 +0,0 @@
----
-title: "Graceful restart or stop"
-draft: false
----
-
-Do you want to graceful restart or stop your web server?
-There are some ways this can be done.
-
-We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
-
-```go
-router := gin.Default()
-router.GET("/", handler)
-// [...]
-endless.ListenAndServe(":4242", router)
-```
-
-An alternative to endless:
-
-* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
-* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
-* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
-
-If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](./examples/graceful-shutdown) example with gin.
-
-```go
-// +build go1.8
-
-package main
-
-import (
- "context"
- "log"
- "net/http"
- "os"
- "os/signal"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- router := gin.Default()
- router.GET("/", func(c *gin.Context) {
- time.Sleep(5 * time.Second)
- c.String(http.StatusOK, "Welcome Gin Server")
- })
-
- srv := &http.Server{
- Addr: ":8080",
- Handler: router,
- }
-
- go func() {
- // service connections
- if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
- log.Fatalf("listen: %s\n", err)
- }
- }()
-
- // Wait for interrupt signal to gracefully shutdown the server with
- // a timeout of 5 seconds.
- quit := make(chan os.Signal, 1)
- signal.Notify(quit, os.Interrupt)
- <-quit
- log.Println("Shutdown Server ...")
-
- ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
- defer cancel()
- if err := srv.Shutdown(ctx); err != nil {
- log.Fatal("Server Shutdown:", err)
- }
- log.Println("Server exiting")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/grouping-routes.md b/content/zh-tw/docs/examples/grouping-routes.md
deleted file mode 100644
index a480aa325..000000000
--- a/content/zh-tw/docs/examples/grouping-routes.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Grouping routes"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Simple group: v1
- v1 := router.Group("/v1")
- {
- v1.POST("/login", loginEndpoint)
- v1.POST("/submit", submitEndpoint)
- v1.POST("/read", readEndpoint)
- }
-
- // Simple group: v2
- v2 := router.Group("/v2")
- {
- v2.POST("/login", loginEndpoint)
- v2.POST("/submit", submitEndpoint)
- v2.POST("/read", readEndpoint)
- }
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/html-rendering.md b/content/zh-tw/docs/examples/html-rendering.md
deleted file mode 100644
index df2e1450a..000000000
--- a/content/zh-tw/docs/examples/html-rendering.md
+++ /dev/null
@@ -1,150 +0,0 @@
----
-title: "HTML rendering"
-draft: false
----
-
-Using LoadHTMLGlob() or LoadHTMLFiles()
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/*")
- //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
- router.GET("/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "index.tmpl", gin.H{
- "title": "Main website",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/index.tmpl
-
-```html
-
-
- {{ .title }}
-
-
-```
-
-Using templates with same name in different directories
-
-```go
-func main() {
- router := gin.Default()
- router.LoadHTMLGlob("templates/**/*")
- router.GET("/posts/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
- "title": "Posts",
- })
- })
- router.GET("/users/index", func(c *gin.Context) {
- c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
- "title": "Users",
- })
- })
- router.Run(":8080")
-}
-```
-
-templates/posts/index.tmpl
-
-```html
-{{ define "posts/index.tmpl" }}
-
- {{ .title }}
-
-Using posts/index.tmpl
-
-{{ end }}
-```
-
-templates/users/index.tmpl
-
-```html
-{{ define "users/index.tmpl" }}
-
- {{ .title }}
-
-Using users/index.tmpl
-
-{{ end }}
-```
-
-#### Custom Template renderer
-
-You can also use your own html template render
-
-```go
-import "html/template"
-
-func main() {
- router := gin.Default()
- html := template.Must(template.ParseFiles("file1", "file2"))
- router.SetHTMLTemplate(html)
- router.Run(":8080")
-}
-```
-
-#### Custom Delimiters
-
-You may use custom delims
-
-```go
- r := gin.Default()
- r.Delims("{[{", "}]}")
- r.LoadHTMLGlob("/path/to/templates")
-```
-
-#### Custom Template Funcs
-
-See the detail [example code](examples/template).
-
-main.go
-
-```go
-import (
- "fmt"
- "html/template"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
-)
-
-func formatAsDate(t time.Time) string {
- year, month, day := t.Date()
- return fmt.Sprintf("%d/%02d/%02d", year, month, day)
-}
-
-func main() {
- router := gin.Default()
- router.Delims("{[{", "}]}")
- router.SetFuncMap(template.FuncMap{
- "formatAsDate": formatAsDate,
- })
- router.LoadHTMLFiles("./testdata/template/raw.tmpl")
-
- router.GET("/raw", func(c *gin.Context) {
- c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
- "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
- })
- })
-
- router.Run(":8080")
-}
-
-```
-
-raw.tmpl
-
-```sh
-Date: {[{.now | formatAsDate}]}
-```
-
-Result:
-```sh
-Date: 2017/07/01
-```
diff --git a/content/zh-tw/docs/examples/http-method.md b/content/zh-tw/docs/examples/http-method.md
deleted file mode 100644
index f4b681991..000000000
--- a/content/zh-tw/docs/examples/http-method.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Using HTTP method"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color
- // gin.DisableConsoleColor()
-
- // Creates a gin router with default middleware:
- // logger and recovery (crash-free) middleware
- router := gin.Default()
-
- router.GET("/someGet", getting)
- router.POST("/somePost", posting)
- router.PUT("/somePut", putting)
- router.DELETE("/someDelete", deleting)
- router.PATCH("/somePatch", patching)
- router.HEAD("/someHead", head)
- router.OPTIONS("/someOptions", options)
-
- // By default it serves on :8080 unless a
- // PORT environment variable was defined.
- router.Run()
- // router.Run(":3000") for a hard coded port
-}
-```
diff --git a/content/zh-tw/docs/examples/http2-server-push.md b/content/zh-tw/docs/examples/http2-server-push.md
deleted file mode 100644
index 00bbd12d8..000000000
--- a/content/zh-tw/docs/examples/http2-server-push.md
+++ /dev/null
@@ -1,51 +0,0 @@
----
-title: "HTTP2 server push"
-draft: false
----
-
-http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
-
-```go
-package main
-
-import (
- "html/template"
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-var html = template.Must(template.New("https").Parse(`
-
-
- Https Test
-
-
-
- Welcome, Ginner!
-
-
-`))
-
-func main() {
- r := gin.Default()
- r.Static("/assets", "./assets")
- r.SetHTMLTemplate(html)
-
- r.GET("/", func(c *gin.Context) {
- if pusher := c.Writer.Pusher(); pusher != nil {
- // use pusher.Push() to do server push
- if err := pusher.Push("/assets/app.js", nil); err != nil {
- log.Printf("Failed to push: %v", err)
- }
- }
- c.HTML(200, "https", gin.H{
- "status": "success",
- })
- })
-
- // Listen and Server in https://127.0.0.1:8080
- r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/jsonp.md b/content/zh-tw/docs/examples/jsonp.md
deleted file mode 100644
index 63c7dc551..000000000
--- a/content/zh-tw/docs/examples/jsonp.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "JSONP"
-draft: false
----
-
-Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
-
-```go
-func main() {
- r := gin.Default()
-
- r.GET("/JSONP?callback=x", func(c *gin.Context) {
- data := map[string]interface{}{
- "foo": "bar",
- }
-
- //callback is x
- // Will output : x({\"foo\":\"bar\"})
- c.JSONP(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/map-as-querystring-or-postform.md b/content/zh-tw/docs/examples/map-as-querystring-or-postform.md
deleted file mode 100644
index fa733e2ef..000000000
--- a/content/zh-tw/docs/examples/map-as-querystring-or-postform.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: "Map as querystring or postform parameters"
-draft: false
----
-
-```sh
-POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-names[first]=thinkerou&names[second]=tianou
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- ids := c.QueryMap("ids")
- names := c.PostFormMap("names")
-
- fmt.Printf("ids: %v; names: %v", ids, names)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
-```
-
diff --git a/content/zh-tw/docs/examples/multipart-urlencoded-binding.md b/content/zh-tw/docs/examples/multipart-urlencoded-binding.md
deleted file mode 100644
index 767fc6576..000000000
--- a/content/zh-tw/docs/examples/multipart-urlencoded-binding.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Multipart/Urlencoded binding"
-draft: false
----
-
-```go
-package main
-
-import (
- "github.com/gin-gonic/gin"
-)
-
-type LoginForm struct {
- User string `form:"user" binding:"required"`
- Password string `form:"password" binding:"required"`
-}
-
-func main() {
- router := gin.Default()
- router.POST("/login", func(c *gin.Context) {
- // you can bind multipart form with explicit binding declaration:
- // c.ShouldBindWith(&form, binding.Form)
- // or you can simply use autobinding with ShouldBind method:
- var form LoginForm
- // in this case proper binding will be automatically selected
- if c.ShouldBind(&form) == nil {
- if form.User == "user" && form.Password == "password" {
- c.JSON(200, gin.H{"status": "you are logged in"})
- } else {
- c.JSON(401, gin.H{"status": "unauthorized"})
- }
- }
- })
- router.Run(":8080")
-}
-```
-
-Test it with:
-```sh
-$ curl -v --form user=user --form password=password http://localhost:8080/login
-```
diff --git a/content/zh-tw/docs/examples/multipart-urlencoded-form.md b/content/zh-tw/docs/examples/multipart-urlencoded-form.md
deleted file mode 100644
index 774662b1e..000000000
--- a/content/zh-tw/docs/examples/multipart-urlencoded-form.md
+++ /dev/null
@@ -1,23 +0,0 @@
----
-title: "Multipart/Urlencoded form"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/form_post", func(c *gin.Context) {
- message := c.PostForm("message")
- nick := c.DefaultPostForm("nick", "anonymous")
-
- c.JSON(200, gin.H{
- "status": "posted",
- "message": message,
- "nick": nick,
- })
- })
- router.Run(":8080")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/multiple-template.md b/content/zh-tw/docs/examples/multiple-template.md
deleted file mode 100644
index 0bcf46858..000000000
--- a/content/zh-tw/docs/examples/multiple-template.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Multitemplate"
-draft: false
----
-
-Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/content/zh-tw/docs/examples/only-bind-query-string.md b/content/zh-tw/docs/examples/only-bind-query-string.md
deleted file mode 100644
index d6d4e33cc..000000000
--- a/content/zh-tw/docs/examples/only-bind-query-string.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Only bind query string"
-draft: false
----
-
-`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/gin"
-)
-
-type Person struct {
- Name string `form:"name"`
- Address string `form:"address"`
-}
-
-func main() {
- route := gin.Default()
- route.Any("/testing", startPage)
- route.Run(":8085")
-}
-
-func startPage(c *gin.Context) {
- var person Person
- if c.ShouldBindQuery(&person) == nil {
- log.Println("====== Only Bind By Query String ======")
- log.Println(person.Name)
- log.Println(person.Address)
- }
- c.String(200, "Success")
-}
-```
diff --git a/content/zh-tw/docs/examples/param-in-path.md b/content/zh-tw/docs/examples/param-in-path.md
deleted file mode 100644
index 6e29a59c7..000000000
--- a/content/zh-tw/docs/examples/param-in-path.md
+++ /dev/null
@@ -1,27 +0,0 @@
----
-title: "Parameters in path"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // This handler will match /user/john but will not match /user/ or /user
- router.GET("/user/:name", func(c *gin.Context) {
- name := c.Param("name")
- c.String(http.StatusOK, "Hello %s", name)
- })
-
- // However, this one will match /user/john/ and also /user/john/send
- // If no other routers match /user/john, it will redirect to /user/john/
- router.GET("/user/:name/*action", func(c *gin.Context) {
- name := c.Param("name")
- action := c.Param("action")
- message := name + " is " + action
- c.String(http.StatusOK, message)
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/pure-json.md b/content/zh-tw/docs/examples/pure-json.md
deleted file mode 100644
index d91f905ef..000000000
--- a/content/zh-tw/docs/examples/pure-json.md
+++ /dev/null
@@ -1,30 +0,0 @@
----
-title: "PureJSON"
-draft: false
----
-
-Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
-This feature is unavailable in Go 1.6 and lower.
-
-```go
-func main() {
- r := gin.Default()
-
- // Serves unicode entities
- r.GET("/json", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // Serves literal characters
- r.GET("/purejson", func(c *gin.Context) {
- c.PureJSON(200, gin.H{
- "html": "Hello, world!",
- })
- })
-
- // listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/query-and-post-form.md b/content/zh-tw/docs/examples/query-and-post-form.md
deleted file mode 100644
index 0d7b18e51..000000000
--- a/content/zh-tw/docs/examples/query-and-post-form.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Query and post form"
-draft: false
----
-
-```sh
-POST /post?id=1234&page=1 HTTP/1.1
-Content-Type: application/x-www-form-urlencoded
-
-name=manu&message=this_is_great
-```
-
-```go
-func main() {
- router := gin.Default()
-
- router.POST("/post", func(c *gin.Context) {
-
- id := c.Query("id")
- page := c.DefaultQuery("page", "0")
- name := c.PostForm("name")
- message := c.PostForm("message")
-
- fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
- })
- router.Run(":8080")
-}
-```
-
-```sh
-id: 1234; page: 1; name: manu; message: this_is_great
-```
diff --git a/content/zh-tw/docs/examples/querystring-param.md b/content/zh-tw/docs/examples/querystring-param.md
deleted file mode 100644
index bcf8b55f2..000000000
--- a/content/zh-tw/docs/examples/querystring-param.md
+++ /dev/null
@@ -1,20 +0,0 @@
----
-title: "Query string parameters"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
-
- // Query string parameters are parsed using the existing underlying request object.
- // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
- router.GET("/welcome", func(c *gin.Context) {
- firstname := c.DefaultQuery("firstname", "Guest")
- lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
-
- c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/redirects.md b/content/zh-tw/docs/examples/redirects.md
deleted file mode 100644
index f7d823eca..000000000
--- a/content/zh-tw/docs/examples/redirects.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: "Redirects"
-draft: false
----
-
-Issuing a HTTP redirect is easy. Both internal and external locations are supported.
-
-```go
-r.GET("/test", func(c *gin.Context) {
- c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
-})
-```
-
-Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
-
-```go
-r.POST("/test", func(c *gin.Context) {
- c.Redirect(http.StatusFound, "/foo")
-})
-```
-
-Issuing a Router redirect, use `HandleContext` like below.
-
-``` go
-r.GET("/test", func(c *gin.Context) {
- c.Request.URL.Path = "/test2"
- r.HandleContext(c)
-})
-r.GET("/test2", func(c *gin.Context) {
- c.JSON(200, gin.H{"hello": "world"})
-})
-```
diff --git a/content/zh-tw/docs/examples/rendering.md b/content/zh-tw/docs/examples/rendering.md
deleted file mode 100644
index a9fa75b5f..000000000
--- a/content/zh-tw/docs/examples/rendering.md
+++ /dev/null
@@ -1,54 +0,0 @@
----
-title: "XML/JSON/YAML/ProtoBuf rendering"
-draft: false
----
-
-```go
-func main() {
- r := gin.Default()
-
- // gin.H is a shortcut for map[string]interface{}
- r.GET("/someJSON", func(c *gin.Context) {
- c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/moreJSON", func(c *gin.Context) {
- // You also can use a struct
- var msg struct {
- Name string `json:"user"`
- Message string
- Number int
- }
- msg.Name = "Lena"
- msg.Message = "hey"
- msg.Number = 123
- // Note that msg.Name becomes "user" in the JSON
- // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
- c.JSON(http.StatusOK, msg)
- })
-
- r.GET("/someXML", func(c *gin.Context) {
- c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someYAML", func(c *gin.Context) {
- c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
- })
-
- r.GET("/someProtoBuf", func(c *gin.Context) {
- reps := []int64{int64(1), int64(2)}
- label := "test"
- // The specific definition of protobuf is written in the testdata/protoexample file.
- data := &protoexample.Test{
- Label: &label,
- Reps: reps,
- }
- // Note that data becomes binary data in the response
- // Will output protoexample.Test protobuf serialized data
- c.ProtoBuf(http.StatusOK, data)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/run-multiple-service.md b/content/zh-tw/docs/examples/run-multiple-service.md
deleted file mode 100644
index d933823e3..000000000
--- a/content/zh-tw/docs/examples/run-multiple-service.md
+++ /dev/null
@@ -1,84 +0,0 @@
----
-title: "Run multiple service"
-draft: false
----
-
-See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
-
-```go
-package main
-
-import (
- "log"
- "net/http"
- "time"
-
- "github.com/gin-gonic/gin"
- "golang.org/x/sync/errgroup"
-)
-
-var (
- g errgroup.Group
-)
-
-func router01() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 01",
- },
- )
- })
-
- return e
-}
-
-func router02() http.Handler {
- e := gin.New()
- e.Use(gin.Recovery())
- e.GET("/", func(c *gin.Context) {
- c.JSON(
- http.StatusOK,
- gin.H{
- "code": http.StatusOK,
- "error": "Welcome server 02",
- },
- )
- })
-
- return e
-}
-
-func main() {
- server01 := &http.Server{
- Addr: ":8080",
- Handler: router01(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- server02 := &http.Server{
- Addr: ":8081",
- Handler: router02(),
- ReadTimeout: 5 * time.Second,
- WriteTimeout: 10 * time.Second,
- }
-
- g.Go(func() error {
- return server01.ListenAndServe()
- })
-
- g.Go(func() error {
- return server02.ListenAndServe()
- })
-
- if err := g.Wait(); err != nil {
- log.Fatal(err)
- }
-}
-```
-
diff --git a/content/zh-tw/docs/examples/secure-json.md b/content/zh-tw/docs/examples/secure-json.md
deleted file mode 100644
index 9f5642167..000000000
--- a/content/zh-tw/docs/examples/secure-json.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "SecureJSON"
-draft: false
----
-
-Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
-
-```go
-func main() {
- r := gin.Default()
-
- // You can also use your own secure json prefix
- // r.SecureJsonPrefix(")]}',\n")
-
- r.GET("/someJSON", func(c *gin.Context) {
- names := []string{"lena", "austin", "foo"}
-
- // Will output : while(1);["lena","austin","foo"]
- c.SecureJSON(http.StatusOK, names)
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/security-headers.md b/content/zh-tw/docs/examples/security-headers.md
deleted file mode 100644
index d3cf79085..000000000
--- a/content/zh-tw/docs/examples/security-headers.md
+++ /dev/null
@@ -1,75 +0,0 @@
----
-title: "安全页眉"
-draft: false
----
-
-使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。
-
-```go
-package main
-
-import (
- "net/http"
-
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- expectedHost := "localhost:8080"
-
- // Setup Security Headers
- r.Use(func(c *gin.Context) {
- if c.Request.Host != expectedHost {
- c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
- return
- }
- c.Header("X-Frame-Options", "DENY")
- c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
- c.Header("X-XSS-Protection", "1; mode=block")
- c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
- c.Header("Referrer-Policy", "strict-origin")
- c.Header("X-Content-Type-Options", "nosniff")
- c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
- c.Next()
- })
-
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
-
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-您可以通过 `curl` 进行测试。
-
-```bash
-// 检查页眉
-
-curl localhost:8080/ping -I
-
-HTTP/1.1 404 Not Found
-Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
-Content-Type: text/plain
-Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
-Referrer-Policy: strict-origin
-Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
-X-Content-Type-Options: nosniff
-X-Frame-Options: DENY
-X-Xss-Protection: 1; mode=block
-Date: Sat, 30 Mar 2024 08:20:44 GMT
-Content-Length: 18
-
-// 检查主机标头注入
-
-curl localhost:8080/ping -I -H "Host:neti.ee"
-
-HTTP/1.1 400 Bad Request
-Content-Type: application/json; charset=utf-8
-Date: Sat, 30 Mar 2024 08:21:09 GMT
-Content-Length: 31
-```
\ No newline at end of file
diff --git a/content/zh-tw/docs/examples/serving-data-from-reader.md b/content/zh-tw/docs/examples/serving-data-from-reader.md
deleted file mode 100644
index f5546a8c6..000000000
--- a/content/zh-tw/docs/examples/serving-data-from-reader.md
+++ /dev/null
@@ -1,28 +0,0 @@
----
-title: "Serving data from reader"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.GET("/someDataFromReader", func(c *gin.Context) {
- response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
- if err != nil || response.StatusCode != http.StatusOK {
- c.Status(http.StatusServiceUnavailable)
- return
- }
-
- reader := response.Body
- contentLength := response.ContentLength
- contentType := response.Header.Get("Content-Type")
-
- extraHeaders := map[string]string{
- "Content-Disposition": `attachment; filename="gopher.png"`,
- }
-
- c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
- })
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/serving-static-files.md b/content/zh-tw/docs/examples/serving-static-files.md
deleted file mode 100644
index e296ead02..000000000
--- a/content/zh-tw/docs/examples/serving-static-files.md
+++ /dev/null
@@ -1,16 +0,0 @@
----
-title: "Serving static files"
-draft: false
----
-
-```go
-func main() {
- router := gin.Default()
- router.Static("/assets", "./assets")
- router.StaticFS("/more_static", http.Dir("my_file_system"))
- router.StaticFile("/favicon.ico", "./resources/favicon.ico")
-
- // Listen and serve on 0.0.0.0:8080
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/support-lets-encrypt.md b/content/zh-tw/docs/examples/support-lets-encrypt.md
deleted file mode 100644
index c66288e87..000000000
--- a/content/zh-tw/docs/examples/support-lets-encrypt.md
+++ /dev/null
@@ -1,60 +0,0 @@
----
-title: "Support Let's Encrypt"
-draft: false
----
-
-example for 1-line LetsEncrypt HTTPS servers.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
-}
-```
-
-example for custom autocert manager.
-
-```go
-package main
-
-import (
- "log"
-
- "github.com/gin-gonic/autotls"
- "github.com/gin-gonic/gin"
- "golang.org/x/crypto/acme/autocert"
-)
-
-func main() {
- r := gin.Default()
-
- // Ping handler
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- m := autocert.Manager{
- Prompt: autocert.AcceptTOS,
- HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
- Cache: autocert.DirCache("/var/www/.cache"),
- }
-
- log.Fatal(autotls.RunWithManager(r, &m))
-}
-```
-
diff --git a/content/zh-tw/docs/examples/upload-file/_index.md b/content/zh-tw/docs/examples/upload-file/_index.md
deleted file mode 100644
index 1810e3253..000000000
--- a/content/zh-tw/docs/examples/upload-file/_index.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-title: "Upload files"
-draft: false
----
-
-The section lists upload file api usage.
diff --git a/content/zh-tw/docs/examples/upload-file/multiple-file.md b/content/zh-tw/docs/examples/upload-file/multiple-file.md
deleted file mode 100644
index 83db10a01..000000000
--- a/content/zh-tw/docs/examples/upload-file/multiple-file.md
+++ /dev/null
@@ -1,37 +0,0 @@
----
-title: "Multiple files"
-draft: false
----
-
-See the detail [example code](examples/upload-file/multiple).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // Multipart form
- form, _ := c.MultipartForm()
- files := form.File["upload[]"]
-
- for _, file := range files {
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
- }
- c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "upload[]=@/Users/appleboy/test1.zip" \
- -F "upload[]=@/Users/appleboy/test2.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/zh-tw/docs/examples/upload-file/single-file.md b/content/zh-tw/docs/examples/upload-file/single-file.md
deleted file mode 100644
index 99f38f28e..000000000
--- a/content/zh-tw/docs/examples/upload-file/single-file.md
+++ /dev/null
@@ -1,33 +0,0 @@
----
-title: "Single file"
-draft: false
----
-
-References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single).
-
-```go
-func main() {
- router := gin.Default()
- // Set a lower memory limit for multipart forms (default is 32 MiB)
- router.MaxMultipartMemory = 8 << 20 // 8 MiB
- router.POST("/upload", func(c *gin.Context) {
- // single file
- file, _ := c.FormFile("file")
- log.Println(file.Filename)
-
- // Upload the file to specific dst.
- c.SaveUploadedFile(file, dst)
-
- c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
- })
- router.Run(":8080")
-}
-```
-
-How to `curl`:
-
-```sh
-curl -X POST http://localhost:8080/upload \
- -F "file=@/Users/appleboy/test.zip" \
- -H "Content-Type: multipart/form-data"
-```
diff --git a/content/zh-tw/docs/examples/using-basicauth-middleware.md b/content/zh-tw/docs/examples/using-basicauth-middleware.md
deleted file mode 100644
index 318aca232..000000000
--- a/content/zh-tw/docs/examples/using-basicauth-middleware.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: "Using BasicAuth middleware"
-draft: false
----
-
-```go
-// simulate some private data
-var secrets = gin.H{
- "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
- "austin": gin.H{"email": "austin@example.com", "phone": "666"},
- "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
-}
-
-func main() {
- r := gin.Default()
-
- // Group using gin.BasicAuth() middleware
- // gin.Accounts is a shortcut for map[string]string
- authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
- "foo": "bar",
- "austin": "1234",
- "lena": "hello2",
- "manu": "4321",
- }))
-
- // /admin/secrets endpoint
- // hit "localhost:8080/admin/secrets
- authorized.GET("/secrets", func(c *gin.Context) {
- // get user, it was set by the BasicAuth middleware
- user := c.MustGet(gin.AuthUserKey).(string)
- if secret, ok := secrets[user]; ok {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
- } else {
- c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
- }
- })
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/examples/using-middleware.md b/content/zh-tw/docs/examples/using-middleware.md
deleted file mode 100644
index 2a3159cc3..000000000
--- a/content/zh-tw/docs/examples/using-middleware.md
+++ /dev/null
@@ -1,43 +0,0 @@
----
-title: "Using middleware"
-draft: false
----
-
-```go
-func main() {
- // Creates a router without any middleware by default
- r := gin.New()
-
- // Global middleware
- // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
- // By default gin.DefaultWriter = os.Stdout
- r.Use(gin.Logger())
-
- // Recovery middleware recovers from any panics and writes a 500 if there was one.
- r.Use(gin.Recovery())
-
- // Per route middleware, you can add as many as you desire.
- r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
-
- // Authorization group
- // authorized := r.Group("/", AuthRequired())
- // exactly the same as:
- authorized := r.Group("/")
- // per group middleware! in this case we use the custom created
- // AuthRequired() middleware just in the "authorized" group.
- authorized.Use(AuthRequired())
- {
- authorized.POST("/login", loginEndpoint)
- authorized.POST("/submit", submitEndpoint)
- authorized.POST("/read", readEndpoint)
-
- // nested group
- testing := authorized.Group("testing")
- testing.GET("/analytics", analyticsEndpoint)
- }
-
- // Listen and serve on 0.0.0.0:8080
- r.Run(":8080")
-}
-```
-
diff --git a/content/zh-tw/docs/examples/without-middleware.md b/content/zh-tw/docs/examples/without-middleware.md
deleted file mode 100644
index ce7b81fbb..000000000
--- a/content/zh-tw/docs/examples/without-middleware.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "Without middleware by default"
-draft: false
----
-
-Use
-
-```go
-r := gin.New()
-```
-
-instead of
-
-```go
-// Default With the Logger and Recovery middleware already attached
-r := gin.Default()
-```
diff --git a/content/zh-tw/docs/examples/write-log.md b/content/zh-tw/docs/examples/write-log.md
deleted file mode 100644
index 261b8d26a..000000000
--- a/content/zh-tw/docs/examples/write-log.md
+++ /dev/null
@@ -1,25 +0,0 @@
----
-title: "How to write log file"
-draft: false
----
-
-```go
-func main() {
- // Disable Console Color, you don't need console color when writing the logs to file.
- gin.DisableConsoleColor()
-
- // Logging to a file.
- f, _ := os.Create("gin.log")
- gin.DefaultWriter = io.MultiWriter(f)
-
- // Use the following code if you need to write the logs to file and console at the same time.
- // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
-
- router := gin.Default()
- router.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
-
- router.Run(":8080")
-}
-```
diff --git a/content/zh-tw/docs/faq/_index.md b/content/zh-tw/docs/faq/_index.md
deleted file mode 100644
index 389d1432a..000000000
--- a/content/zh-tw/docs/faq/_index.md
+++ /dev/null
@@ -1,8 +0,0 @@
----
-title: "FAQ"
-draft: false
-weight: 9
----
-
-TODO: record some frequently asked question from GitHub Issue tab.
-
diff --git a/content/zh-tw/docs/features/_index.md b/content/zh-tw/docs/features/_index.md
deleted file mode 100644
index b768bf872..000000000
--- a/content/zh-tw/docs/features/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: "特色"
-draft: false
-weight: 4
----
-
-##### Gin v1 穩定功能
-
-- 零配置的路由器。
-
-- 仍然是最快的 HTTP 路由器和 Web 框架。從路由到紀錄。
-
-- 完整的單元測試套件。
-
-- 經過實戰測試。
-
-- API frozen。新版本發布不會破壞你的程式碼。
diff --git a/content/zh-tw/docs/introduction/_index.md b/content/zh-tw/docs/introduction/_index.md
deleted file mode 100644
index 138046bff..000000000
--- a/content/zh-tw/docs/introduction/_index.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-title: "介紹"
-draft: false
-weight: 1
----
-
-Gin 是一個使用 Go (Golang) 寫的 Web 框架。它提供類似 Martini 的 API,但擁有更好的效能,感謝 [httprouter](https://github.com/julienschmidt/httprouter),速度快上了 40 倍。如果你需要效能和高生產力,你將會愛上 Gin。
-
-在這個章節當中,我們會介紹什麼是 Gin,它解決了什麼問題,還有他如何幫助你的專案。
-
-或者,如果你已經準備好要在你的專案中使用 Gin,請前往 [快速入門](/quickstart)。
-
-## 特色
-
-### 快速
-
-以 Radix tree 為基礎的路由,記憶體使用量小。沒有使用 reflection。可預測的 API 效能。
-
-### 支援 Middleware
-
-傳入的請求可以由一系列的 Middleware 和最終行為來處理。例如:Logger、Authorization、GZIP,最後送訊息到資料庫。
-
-### Crash-free
-
-Gin 可以攔截發生在 HTTP 請求期間的 panic 並回復它。這樣的話,伺服器將永遠是可用狀態。舉例來說,它可以選擇回報 panic 給 Sentry。
-
-### JSON 驗證
-
-Gin 可以剖析和驗證請求裡的 JSON,例如檢查必要值。
-
-### 路由群組
-
-更好地組織你的路由。需不需要授權或不同的 API 版本。此外,這些群組可以無限制地巢狀嵌套而不會降低效能。
-
-### 錯誤管理
-
-Gin 提供了一種方便的方法來收集 HTTP 請求期間發生的所有錯誤。 最後, Middleware 可以將它們寫入日誌檔案、寫入資料庫,並透過網路傳送。
-
-### 內建渲染
-
-Gin 提供易使用的 API 來渲染 JSON、XML 和 HTML。
-
-### 可擴展性
-
-建立新的 Middleware 很簡單,直接查看範例程式碼即可。
diff --git a/content/zh-tw/docs/jsoniter/_index.md b/content/zh-tw/docs/jsoniter/_index.md
deleted file mode 100644
index c46530a73..000000000
--- a/content/zh-tw/docs/jsoniter/_index.md
+++ /dev/null
@@ -1,13 +0,0 @@
----
-title: "Jsoniter"
-draft: false
-weight: 5
----
-
-#### Build with [jsoniter](https://github.com/json-iterator/go)
-
-Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
-
-```sh
-$ go build -tags=jsoniter .
-```
diff --git a/content/zh-tw/docs/quickstart/_index.md b/content/zh-tw/docs/quickstart/_index.md
deleted file mode 100644
index d3df6ea73..000000000
--- a/content/zh-tw/docs/quickstart/_index.md
+++ /dev/null
@@ -1,104 +0,0 @@
----
-title: "快速入門"
-draft: false
-weight: 2
----
-
-- [需求](#需求)
-- [安裝](#安裝)
-- [開始使用](#開始使用)
-
-## 需求
-
-- Go 1.16 及更新版本
-
-## 安裝
-
-安裝 Gin 套件前, 你需要先安裝 Go 和準備好你的工作環境。
-
-1. 下載並安裝
-
-```sh
-$ go get -u github.com/gin-gonic/gin
-```
-
-2. 在程式碼當中匯入套件
-
-```go
-import "github.com/gin-gonic/gin"
-```
-
-3. (可選的)如果你想要使用像是 `http.StatusOK` 的常數,你會需要匯入 `net/http` 套件
-
-```go
-import "net/http"
-```
-
-### 使用 vendor 工具像是 [Govendor](https://github.com/kardianos/govendor)
-
-1. `go get` govendor
-
-```sh
-$ go get github.com/kardianos/govendor
-```
-
-2. 新增你的專案資料夾並 `cd` 進入
-
-```sh
-$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
- ```
-
-3. Vendor init 專案並加入 gin
-
-```sh
-$ govendor init
-$ govendor fetch github.com/gin-gonic/gin@v1.3
-```
-
-4. 複製範本到你的專案
-
-```sh
-$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
-```
-
-5. 執行你的專案
-
-```sh
-$ go run main.go
-```
-
-## 開始使用
-
-> 不確定如何寫和執行 Go 程式碼? [Click here](https://golang.org/doc/code.html).
-
-第一步,新增一個檔案 `example.go`:
-
-```sh
-# assume the following codes in example.go file
-$ touch example.go
-```
-
-接下來,將下列程式碼放進 `example.go`:
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-func main() {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.JSON(200, gin.H{
- "message": "pong",
- })
- })
- r.Run() // listen and serve on 0.0.0.0:8080
-}
-```
-
-然後,你可以透過 `go run example.go` 來執行這個程式碼:
-
-```shell
-# run example.go and visit 0.0.0.0:8080/ping on browser
-$ go run example.go
-```
diff --git a/content/zh-tw/docs/testing/_index.md b/content/zh-tw/docs/testing/_index.md
deleted file mode 100644
index b001ce108..000000000
--- a/content/zh-tw/docs/testing/_index.md
+++ /dev/null
@@ -1,89 +0,0 @@
----
-title: "測試"
-draft: false
-weight: 7
----
-
-##### 如何為 Gin 寫測試案例?
-
-傾向使用 `net/http/httptest` 套件來做 HTTP 測試。
-
-```go
-package main
-
-import "github.com/gin-gonic/gin"
-
-type User struct {
- Username string `json:"username"`
- Gender string `json:"gender"`
-}
-
-func setupRouter() *gin.Engine {
- r := gin.Default()
- r.GET("/ping", func(c *gin.Context) {
- c.String(200, "pong")
- })
- return r
-}
-
-func postUser(r *gin.Engine) *gin.Engine {
- r.POST("/user/add", func(c *gin.Context) {
- var user User
- c.BindJSON(&user)
- c.JSON(200, user)
- })
- return r
-}
-
-func main() {
- r := setupRouter()
- r = postUser(r)
- r.Run(":8080")
-}
-```
-
-為上面程式碼所寫的測試:
-
-```go
-package main
-
-import (
- "net/http"
- "net/http/httptest"
- "testing"
-
- "github.com/stretchr/testify/assert"
-)
-
-func TestPingRoute(t *testing.T) {
- router := setupRouter()
-
- w := httptest.NewRecorder()
- req, _ := http.NewRequest("GET", "/ping", nil)
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- assert.Equal(t, "pong", w.Body.String())
-}
-
-// Test for POST /user/add
-func TestPostUser(t *testing.T) {
- router := setupRouter()
- router = postUser(router)
-
- w := httptest.NewRecorder()
-
- // Create an example user for testing
- exampleUser := User{
- Username: "test_name",
- Gender: "male",
- }
- userJson, _ := json.Marshal(exampleUser)
- req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
- router.ServeHTTP(w, req)
-
- assert.Equal(t, 200, w.Code)
- // Compare the response body with the json data of exampleUser
- assert.Equal(t, string(userJson), w.Body.String())
-}
-```
diff --git a/content/zh-tw/docs/users/_index.md b/content/zh-tw/docs/users/_index.md
deleted file mode 100644
index 4e088120a..000000000
--- a/content/zh-tw/docs/users/_index.md
+++ /dev/null
@@ -1,21 +0,0 @@
----
-title: "使用者"
-draft: false
-weight: 8
----
-
-##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
-
-* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
-
-* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
-
-* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
-
-* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
-
-* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
-
-* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
-
-* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/content/zh-tw/search.md b/content/zh-tw/search.md
deleted file mode 100644
index 4cde3a93d..000000000
--- a/content/zh-tw/search.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-title: Search Results
-layout: search
----
-
diff --git a/hugo.toml b/hugo.toml
deleted file mode 100644
index f97f392a5..000000000
--- a/hugo.toml
+++ /dev/null
@@ -1,260 +0,0 @@
-baseURL = "https://gin-gonic.com/"
-title = "Gin Web Framework"
-
-enableRobotsTXT = true
-
-# Will give values to .Lastmod etc.
-enableGitInfo = true
-
-# Language settings
-contentDir = "content/en"
-defaultContentLanguage = "en"
-defaultContentLanguageInSubdir = false
-# Useful when translating.
-enableMissingTranslationPlaceholders = true
-
-disableKinds = ["RSS", "taxonomy"]
-
-# Highlighting config
-pygmentsCodeFences = true
-pygmentsUseClasses = false
-# Use the new Chroma Go highlighter in Hugo.
-pygmentsUseClassic = false
-#pygmentsOptions = "linenos=table"
-# See https://help.farbox.com/pygments.html
-pygmentsStyle = "tango"
-
-# First one is picked as the Twitter card image if not set on page.
-#images = ["images/project-illustration.png"]
-
-#disqusShortname = "gin-gonic"
-
-# Configure how URLs look like per section.
-[permalinks]
-blog = "/:section/:year/:month/:day/:slug/"
-
-## Configuration for BlackFriday markdown parser: https://github.com/russross/blackfriday
-[blackfriday]
-plainIDAnchors = true
-hrefTargetBlank = true
-angledQuotes = false
-latexDashes = true
-
-# Image processing configuration.
-[imaging]
-resampleFilter = "CatmullRom"
-quality = 75
-anchor = "smart"
-
-[services]
-[services.googleAnalytics]
-# Comment out the next line to disable GA tracking. Also disables the feature described in [params.ui.feedback].
-id = "UA-42425385-2"
-
-# Language configuration
-
-[languages]
-[languages.en]
-title = "Gin Web Framework"
-languageName = "English"
-# Weight used for sorting.
-weight = 1
-[languages.en.params]
-description = "Gin Web Framework"
-
-[languages.zh-cn]
-title = "Gin Web Framework"
-languageName = "简体中文"
-contentDir = "content/zh-cn"
-[languages.zh-cn.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.zh-tw]
-title = "Gin Web Framework"
-languageName = "繁體中文"
-contentDir = "content/zh-tw"
-[languages.zh-tw.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.ja]
-title = "Gin Web Framework"
-languageName = "日本語"
-contentDir = "content/ja"
-[languages.ja.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.ko-kr]
-title = "Gin Web Framework"
-languageName = "한국어"
-contentDir = "content/ko-kr"
-[languages.ko-kr.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.es]
-title = "Gin Web Framework"
-languageName = "Español"
-contentDir = "content/es"
-[languages.es.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.fa]
-title = "Gin Web Framework"
-languageName = "Persian"
-contentDir = "content/fa"
-[languages.fa.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.tr]
-title = "Gin Web Framework"
-languageName = "Turkish"
-contentDir = "content/tr"
-[languages.tr.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.pt]
-title = "Gin Web Framework"
-languageName = "Português"
-contentDir = "content/pt"
-[languages.pt.params]
-description = "A Abstração de Web Gin"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[languages.ru]
-title = "Gin Web Framework"
-languageName = "Russian"
-contentDir = "content/ru"
-[languages.ru.params]
-description = "Gin Web Framework"
-time_format_default = "02.01.2006"
-time_format_blog = "02.01.2006"
-
-[markup]
- [markup.goldmark]
- [markup.goldmark.renderer]
- unsafe = true
-
-# Everything below this are Site Params
-
-[params]
-copyright = "Gin Team"
-#privacy_policy = "https://policies.google.com/privacy"
-
-# First one is picked as the Twitter card image if not set on page.
-# images = ["images/project-illustration.png"]
-
-# Menu title if your navbar has a versions selector to access old versions of your site.
-# This menu appears only if you have at least one [params.versions] set.
-version_menu = "Releases"
-
-# Flag used in the "version-banner" partial to decide whether to display a
-# banner on every page indicating that this is an archived version of the docs.
-# Set this flag to "true" if you want to display the banner.
-archived_version = false
-
-# The version number for the version of the docs represented in this doc set.
-# Used in the "version-banner" partial to display a version number for the
-# current doc set.
-version = "0.0"
-
-# A link to latest version of the docs. Used in the "version-banner" partial to
-# point people to the main doc site.
-url_latest_version = "https://example.com"
-
-# Repository configuration (URLs for in-page links to opening issues and suggesting changes)
-github_repo = "https://github.com/gin-gonic/website"
-# An optional link to a related project repo. For example, the sibling repository where your product code lives.
-github_project_repo = "https://github.com/google/docsy"
-
-# Specify a value here if you have would like to reference a different branch for the other github settings like Edit this page or Create project issue.
-github_branch = "master"
-
-# Specify a value here if your content directory is not in your repo's root directory
-# github_subdir = ""
-
-# Google Custom Search Engine ID. Remove or comment out to disable search.
-gcs_engine_id = "005538359705255204576:q0elqbxmlfs"
-
-# User interface configuration
-[params.ui]
-# Enable to show the side bar menu in its compact state.
-sidebar_menu_compact = true
-# Set to true to disable breadcrumb navigation.
-breadcrumb_disable = false
-# Set to true to hide the sidebar search box (the top nav search box will still be displayed if search is enabled)
-sidebar_search_disable = true
-# Set to false if you don't want to display a logo (/assets/icons/logo.svg) in the top nav bar
-navbar_logo = true
-# Set to true to disable the About link in the site footer
-footer_about_enable = true
-
-# Adds a H2 section titled "Feedback" to the bottom of each doc. The responses are sent to Google Analytics as events.
-# This feature depends on [services.googleAnalytics] and will be disabled if "services.googleAnalytics.id" is not set.
-# If you want this feature, but occasionally need to remove the "Feedback" section from a single page,
-# add "hide_feedback: true" to the page's front matter.
-[params.ui.feedback]
-enable = false
-# The responses that the user sees after clicking "yes" (the page was helpful) or "no" (the page was not helpful).
-yes = 'Glad to hear it! Please tell us how we can improve.'
-no = 'Sorry to hear that. Please tell us how we can improve.'
-
-[params.links]
-# End user relevant links. These will show up on left side of footer and in the community page if you have one.
-[[params.links.user]]
- name = "Gitter"
- url = "https://gitter.im/gin-gonic/gin"
- icon = "fab fa-gitter"
- desc = "Discussion and help from your fellow users"
-#[[params.links.user]]
-# name ="Twitter"
-# url = "https://example.org/twitter"
-# icon = "fab fa-twitter"
-# desc = "Follow us on Twitter to get the latest news!"
-#[[params.links.user]]
-# name = "Stack Overflow"
-# url = "https://example.org/stack"
-# icon = "fab fa-stack-overflow"
-# desc = "Practical questions and curated answers"
-# Developer relevant links. These will show up on right side of footer and in the community page if you have one.
-[[params.links.developer]]
- name = "GitHub"
- url = "https://github.com/gin-gonic/gin"
- icon = "fab fa-github"
- desc = "Development takes place here!"
-#[[params.links.developer]]
-# name = "Slack"
-# url = "https://example.org/slack"
-# icon = "fab fa-slack"
-# desc = "Chat with other project developers"
-#[[params.links.developer]]
-# name = "Developer mailing list"
-# url = "https://example.org/mail"
-# icon = "fa fa-envelope"
-# desc = "Discuss development issues around the project"
-
-[module]
- # Uncomment the next line to build and serve using local docsy clone declared in the named Hugo workspace:
- # workspace = "docsy.work"
- [module.hugoVersion]
- extended = true
- min = "0.110.0"
- [[module.mounts]]
- source = "scss"
- targets = "scss"
- [[module.imports]]
- path = "github.com/google/docsy"
- disable = false
diff --git a/layouts/partials/footer.html b/layouts/partials/footer.html
deleted file mode 100644
index 9242b69d6..000000000
--- a/layouts/partials/footer.html
+++ /dev/null
@@ -1,39 +0,0 @@
-{{ $links := .Site.Params.links }}
-
-{{ define "footer-links-block" }}
-
- {{ range . }}
- -
-
-
-
-
- {{ end }}
-
-{{ end }}
diff --git a/package-lock.json b/package-lock.json
deleted file mode 100644
index f11dedf1e..000000000
--- a/package-lock.json
+++ /dev/null
@@ -1,1025 +0,0 @@
-{
- "name": "tech-doc-hugo",
- "version": "0.0.1",
- "lockfileVersion": 3,
- "requires": true,
- "packages": {
- "": {
- "name": "tech-doc-hugo",
- "version": "0.0.1",
- "license": "ISC",
- "dependencies": {
- "postcss": "^7.0.27"
- },
- "devDependencies": {
- "autoprefixer": "^10.4.19",
- "postcss": "^8.4.38",
- "postcss-cli": "^11.0.0"
- }
- },
- "node_modules/@nodelib/fs.scandir": {
- "version": "2.1.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
- "integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "2.0.5",
- "run-parallel": "^1.1.9"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.stat": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
- "integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@nodelib/fs.walk": {
- "version": "1.2.8",
- "resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
- "integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.scandir": "2.1.5",
- "fastq": "^1.6.0"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/@sindresorhus/merge-streams": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-2.3.0.tgz",
- "integrity": "sha512-LtoMMhxAlorcGhmFYI+LhPgbPZCkgP6ra1YL604EeF6U98pLlQ3iWIGMdWSC+vWmPBWBNgmDBAhnAobLROJmwg==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/ansi-regex": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
- "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/ansi-styles": {
- "version": "4.3.0",
- "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
- "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
- "dev": true,
- "dependencies": {
- "color-convert": "^2.0.1"
- },
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/chalk/ansi-styles?sponsor=1"
- }
- },
- "node_modules/anymatch": {
- "version": "3.1.3",
- "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-3.1.3.tgz",
- "integrity": "sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==",
- "dev": true,
- "dependencies": {
- "normalize-path": "^3.0.0",
- "picomatch": "^2.0.4"
- },
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/autoprefixer": {
- "version": "10.4.19",
- "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.19.tgz",
- "integrity": "sha512-BaENR2+zBZ8xXhM4pUaKUxlVdxZ0EZhjvbopwnXmxRUfqDmwSpC2lAi/QXvx7NRdPCo1WKEcEF6mV64si1z4Ew==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/autoprefixer"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "browserslist": "^4.23.0",
- "caniuse-lite": "^1.0.30001599",
- "fraction.js": "^4.3.7",
- "normalize-range": "^0.1.2",
- "picocolors": "^1.0.0",
- "postcss-value-parser": "^4.2.0"
- },
- "bin": {
- "autoprefixer": "bin/autoprefixer"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "node_modules/binary-extensions": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.3.0.tgz",
- "integrity": "sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==",
- "dev": true,
- "engines": {
- "node": ">=8"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/braces": {
- "version": "3.0.2",
- "resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
- "integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
- "dev": true,
- "dependencies": {
- "fill-range": "^7.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/browserslist": {
- "version": "4.23.0",
- "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.23.0.tgz",
- "integrity": "sha512-QW8HiM1shhT2GuzkvklfjcKDiWFXHOeFCIA/huJPwHsslwcydgk7X+z2zXpEijP98UCY7HbubZt5J2Zgvf0CaQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "caniuse-lite": "^1.0.30001587",
- "electron-to-chromium": "^1.4.668",
- "node-releases": "^2.0.14",
- "update-browserslist-db": "^1.0.13"
- },
- "bin": {
- "browserslist": "cli.js"
- },
- "engines": {
- "node": "^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7"
- }
- },
- "node_modules/caniuse-lite": {
- "version": "1.0.30001612",
- "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001612.tgz",
- "integrity": "sha512-lFgnZ07UhaCcsSZgWW0K5j4e69dK1u/ltrL9lTUiFOwNHs12S3UMIEYgBV0Z6C6hRDev7iRnMzzYmKabYdXF9g==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/caniuse-lite"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ]
- },
- "node_modules/chokidar": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz",
- "integrity": "sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==",
- "dev": true,
- "dependencies": {
- "anymatch": "~3.1.2",
- "braces": "~3.0.2",
- "glob-parent": "~5.1.2",
- "is-binary-path": "~2.1.0",
- "is-glob": "~4.0.1",
- "normalize-path": "~3.0.0",
- "readdirp": "~3.6.0"
- },
- "engines": {
- "node": ">= 8.10.0"
- },
- "funding": {
- "url": "https://paulmillr.com/funding/"
- },
- "optionalDependencies": {
- "fsevents": "~2.3.2"
- }
- },
- "node_modules/cliui": {
- "version": "8.0.1",
- "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz",
- "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==",
- "dev": true,
- "dependencies": {
- "string-width": "^4.2.0",
- "strip-ansi": "^6.0.1",
- "wrap-ansi": "^7.0.0"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/color-convert": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
- "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
- "dev": true,
- "dependencies": {
- "color-name": "~1.1.4"
- },
- "engines": {
- "node": ">=7.0.0"
- }
- },
- "node_modules/color-name": {
- "version": "1.1.4",
- "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
- "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
- "dev": true
- },
- "node_modules/dependency-graph": {
- "version": "0.11.0",
- "resolved": "https://registry.npmjs.org/dependency-graph/-/dependency-graph-0.11.0.tgz",
- "integrity": "sha512-JeMq7fEshyepOWDfcfHK06N3MhyPhz++vtqWhMT5O9A3K42rdsEDpfdVqjaqaAhsw6a+ZqeDvQVtD0hFHQWrzg==",
- "dev": true,
- "engines": {
- "node": ">= 0.6.0"
- }
- },
- "node_modules/electron-to-chromium": {
- "version": "1.4.750",
- "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.750.tgz",
- "integrity": "sha512-9ItEpeu15hW5m8jKdriL+BQrgwDTXEL9pn4SkillWFu73ZNNNQ2BKKLS+ZHv2vC9UkNhosAeyfxOf/5OSeTCPA==",
- "dev": true
- },
- "node_modules/emoji-regex": {
- "version": "8.0.0",
- "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
- "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
- "dev": true
- },
- "node_modules/escalade": {
- "version": "3.1.2",
- "resolved": "https://registry.npmjs.org/escalade/-/escalade-3.1.2.tgz",
- "integrity": "sha512-ErCHMCae19vR8vQGe50xIsVomy19rg6gFu3+r3jkEO46suLMWBksvVyoGgQV+jOfl84ZSOSlmv6Gxa89PmTGmA==",
- "dev": true,
- "engines": {
- "node": ">=6"
- }
- },
- "node_modules/fast-glob": {
- "version": "3.3.2",
- "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
- "integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
- "dev": true,
- "dependencies": {
- "@nodelib/fs.stat": "^2.0.2",
- "@nodelib/fs.walk": "^1.2.3",
- "glob-parent": "^5.1.2",
- "merge2": "^1.3.0",
- "micromatch": "^4.0.4"
- },
- "engines": {
- "node": ">=8.6.0"
- }
- },
- "node_modules/fastq": {
- "version": "1.17.1",
- "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
- "integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
- "dev": true,
- "dependencies": {
- "reusify": "^1.0.4"
- }
- },
- "node_modules/fill-range": {
- "version": "7.0.1",
- "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
- "integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
- "dev": true,
- "dependencies": {
- "to-regex-range": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/fraction.js": {
- "version": "4.3.7",
- "resolved": "https://registry.npmjs.org/fraction.js/-/fraction.js-4.3.7.tgz",
- "integrity": "sha512-ZsDfxO51wGAXREY55a7la9LScWpwv9RxIrYABrlvOFBlH/ShPnrtsXeuUIfXKKOVicNxQ+o8JTbJvjS4M89yew==",
- "dev": true,
- "engines": {
- "node": "*"
- },
- "funding": {
- "type": "patreon",
- "url": "https://github.com/sponsors/rawify"
- }
- },
- "node_modules/fs-extra": {
- "version": "11.2.0",
- "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-11.2.0.tgz",
- "integrity": "sha512-PmDi3uwK5nFuXh7XDTlVnS17xJS7vW36is2+w3xcv8SVxiB4NyATf4ctkVY5bkSjX0Y4nbvZCq1/EjtEyr9ktw==",
- "dev": true,
- "dependencies": {
- "graceful-fs": "^4.2.0",
- "jsonfile": "^6.0.1",
- "universalify": "^2.0.0"
- },
- "engines": {
- "node": ">=14.14"
- }
- },
- "node_modules/fsevents": {
- "version": "2.3.3",
- "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
- "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
- "dev": true,
- "hasInstallScript": true,
- "optional": true,
- "os": [
- "darwin"
- ],
- "engines": {
- "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
- }
- },
- "node_modules/get-caller-file": {
- "version": "2.0.5",
- "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
- "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
- "dev": true,
- "engines": {
- "node": "6.* || 8.* || >= 10.*"
- }
- },
- "node_modules/get-stdin": {
- "version": "9.0.0",
- "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-9.0.0.tgz",
- "integrity": "sha512-dVKBjfWisLAicarI2Sf+JuBE/DghV4UzNAVe9yhEJuzeREd3JhOTE9cUaJTeSa77fsbQUK3pcOpJfM59+VKZaA==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/glob-parent": {
- "version": "5.1.2",
- "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
- "integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
- "dev": true,
- "dependencies": {
- "is-glob": "^4.0.1"
- },
- "engines": {
- "node": ">= 6"
- }
- },
- "node_modules/globby": {
- "version": "14.0.1",
- "resolved": "https://registry.npmjs.org/globby/-/globby-14.0.1.tgz",
- "integrity": "sha512-jOMLD2Z7MAhyG8aJpNOpmziMOP4rPLcc95oQPKXBazW82z+CEgPFBQvEpRUa1KeIMUJo4Wsm+q6uzO/Q/4BksQ==",
- "dev": true,
- "dependencies": {
- "@sindresorhus/merge-streams": "^2.1.0",
- "fast-glob": "^3.3.2",
- "ignore": "^5.2.4",
- "path-type": "^5.0.0",
- "slash": "^5.1.0",
- "unicorn-magic": "^0.1.0"
- },
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/graceful-fs": {
- "version": "4.2.11",
- "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz",
- "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==",
- "dev": true
- },
- "node_modules/ignore": {
- "version": "5.3.1",
- "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.1.tgz",
- "integrity": "sha512-5Fytz/IraMjqpwfd34ke28PTVMjZjJG2MPn5t7OE4eUCUNf8BAa7b5WUS9/Qvr6mwOQS7Mk6vdsMno5he+T8Xw==",
- "dev": true,
- "engines": {
- "node": ">= 4"
- }
- },
- "node_modules/is-binary-path": {
- "version": "2.1.0",
- "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-2.1.0.tgz",
- "integrity": "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==",
- "dev": true,
- "dependencies": {
- "binary-extensions": "^2.0.0"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-extglob": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz",
- "integrity": "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-fullwidth-code-point": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
- "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
- "dev": true,
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/is-glob": {
- "version": "4.0.3",
- "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
- "integrity": "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==",
- "dev": true,
- "dependencies": {
- "is-extglob": "^2.1.1"
- },
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/is-number": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
- "integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
- "dev": true,
- "engines": {
- "node": ">=0.12.0"
- }
- },
- "node_modules/jsonfile": {
- "version": "6.1.0",
- "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz",
- "integrity": "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ==",
- "dev": true,
- "dependencies": {
- "universalify": "^2.0.0"
- },
- "optionalDependencies": {
- "graceful-fs": "^4.1.6"
- }
- },
- "node_modules/lilconfig": {
- "version": "3.1.1",
- "resolved": "https://registry.npmjs.org/lilconfig/-/lilconfig-3.1.1.tgz",
- "integrity": "sha512-O18pf7nyvHTckunPWCV1XUNXU1piu01y2b7ATJ0ppkUkk8ocqVWBrYjJBCwHDjD/ZWcfyrA0P4gKhzWGi5EINQ==",
- "dev": true,
- "engines": {
- "node": ">=14"
- },
- "funding": {
- "url": "https://github.com/sponsors/antonk52"
- }
- },
- "node_modules/merge2": {
- "version": "1.4.1",
- "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
- "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
- "dev": true,
- "engines": {
- "node": ">= 8"
- }
- },
- "node_modules/micromatch": {
- "version": "4.0.5",
- "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz",
- "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==",
- "dev": true,
- "dependencies": {
- "braces": "^3.0.2",
- "picomatch": "^2.3.1"
- },
- "engines": {
- "node": ">=8.6"
- }
- },
- "node_modules/nanoid": {
- "version": "3.3.7",
- "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz",
- "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "bin": {
- "nanoid": "bin/nanoid.cjs"
- },
- "engines": {
- "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
- }
- },
- "node_modules/node-releases": {
- "version": "2.0.14",
- "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.14.tgz",
- "integrity": "sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==",
- "dev": true
- },
- "node_modules/normalize-path": {
- "version": "3.0.0",
- "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz",
- "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/normalize-range": {
- "version": "0.1.2",
- "resolved": "https://registry.npmjs.org/normalize-range/-/normalize-range-0.1.2.tgz",
- "integrity": "sha1-LRDAa9/TEuqXd2laTShDlFa3WUI=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/path-type": {
- "version": "5.0.0",
- "resolved": "https://registry.npmjs.org/path-type/-/path-type-5.0.0.tgz",
- "integrity": "sha512-5HviZNaZcfqP95rwpv+1HDgUamezbqdSYTyzjTvwtJSnIH+3vnbmWsItli8OFEndS984VT55M3jduxZbX351gg==",
- "dev": true,
- "engines": {
- "node": ">=12"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/picocolors": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz",
- "integrity": "sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==",
- "dev": true
- },
- "node_modules/picomatch": {
- "version": "2.3.1",
- "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz",
- "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==",
- "dev": true,
- "engines": {
- "node": ">=8.6"
- },
- "funding": {
- "url": "https://github.com/sponsors/jonschlinkert"
- }
- },
- "node_modules/postcss": {
- "version": "8.4.38",
- "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.38.tgz",
- "integrity": "sha512-Wglpdk03BSfXkHoQa3b/oulrotAkwrlLDRSOb9D0bN86FdRyE9lppSp33aHNPgBa0JKCoB+drFLZkQoRRYae5A==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/postcss"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "nanoid": "^3.3.7",
- "picocolors": "^1.0.0",
- "source-map-js": "^1.2.0"
- },
- "engines": {
- "node": "^10 || ^12 || >=14"
- }
- },
- "node_modules/postcss-cli": {
- "version": "11.0.0",
- "resolved": "https://registry.npmjs.org/postcss-cli/-/postcss-cli-11.0.0.tgz",
- "integrity": "sha512-xMITAI7M0u1yolVcXJ9XTZiO9aO49mcoKQy6pCDFdMh9kGqhzLVpWxeD/32M/QBmkhcGypZFFOLNLmIW4Pg4RA==",
- "dev": true,
- "dependencies": {
- "chokidar": "^3.3.0",
- "dependency-graph": "^0.11.0",
- "fs-extra": "^11.0.0",
- "get-stdin": "^9.0.0",
- "globby": "^14.0.0",
- "picocolors": "^1.0.0",
- "postcss-load-config": "^5.0.0",
- "postcss-reporter": "^7.0.0",
- "pretty-hrtime": "^1.0.3",
- "read-cache": "^1.0.0",
- "slash": "^5.0.0",
- "yargs": "^17.0.0"
- },
- "bin": {
- "postcss": "index.js"
- },
- "engines": {
- "node": ">=18"
- },
- "peerDependencies": {
- "postcss": "^8.0.0"
- }
- },
- "node_modules/postcss-load-config": {
- "version": "5.0.3",
- "resolved": "https://registry.npmjs.org/postcss-load-config/-/postcss-load-config-5.0.3.tgz",
- "integrity": "sha512-90pBBI5apUVruIEdCxZic93Wm+i9fTrp7TXbgdUCH+/L+2WnfpITSpq5dFU/IPvbv7aNiMlQISpUkAm3fEcvgQ==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "lilconfig": "^3.0.0",
- "yaml": "^2.3.4"
- },
- "engines": {
- "node": ">= 18"
- },
- "peerDependencies": {
- "jiti": ">=1.21.0",
- "postcss": ">=8.0.9"
- },
- "peerDependenciesMeta": {
- "jiti": {
- "optional": true
- },
- "postcss": {
- "optional": true
- }
- }
- },
- "node_modules/postcss-reporter": {
- "version": "7.1.0",
- "resolved": "https://registry.npmjs.org/postcss-reporter/-/postcss-reporter-7.1.0.tgz",
- "integrity": "sha512-/eoEylGWyy6/DOiMP5lmFRdmDKThqgn7D6hP2dXKJI/0rJSO1ADFNngZfDzxL0YAxFvws+Rtpuji1YIHj4mySA==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/postcss/"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "picocolors": "^1.0.0",
- "thenby": "^1.3.4"
- },
- "engines": {
- "node": ">=10"
- },
- "peerDependencies": {
- "postcss": "^8.1.0"
- }
- },
- "node_modules/postcss-value-parser": {
- "version": "4.2.0",
- "resolved": "https://registry.npmjs.org/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
- "integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
- "dev": true
- },
- "node_modules/pretty-hrtime": {
- "version": "1.0.3",
- "resolved": "https://registry.npmjs.org/pretty-hrtime/-/pretty-hrtime-1.0.3.tgz",
- "integrity": "sha1-t+PqQkNaTJsnWdmeDyAesZWALuE=",
- "dev": true,
- "engines": {
- "node": ">= 0.8"
- }
- },
- "node_modules/queue-microtask": {
- "version": "1.2.3",
- "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
- "integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ]
- },
- "node_modules/read-cache": {
- "version": "1.0.0",
- "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
- "integrity": "sha1-5mTvMRYRZsl1HNvo28+GtftY93Q=",
- "dev": true,
- "dependencies": {
- "pify": "^2.3.0"
- }
- },
- "node_modules/read-cache/node_modules/pify": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz",
- "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/readdirp": {
- "version": "3.6.0",
- "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz",
- "integrity": "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==",
- "dev": true,
- "dependencies": {
- "picomatch": "^2.2.1"
- },
- "engines": {
- "node": ">=8.10.0"
- }
- },
- "node_modules/require-directory": {
- "version": "2.1.1",
- "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz",
- "integrity": "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/reusify": {
- "version": "1.0.4",
- "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
- "integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
- "dev": true,
- "engines": {
- "iojs": ">=1.0.0",
- "node": ">=0.10.0"
- }
- },
- "node_modules/run-parallel": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
- "integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
- "dev": true,
- "funding": [
- {
- "type": "github",
- "url": "https://github.com/sponsors/feross"
- },
- {
- "type": "patreon",
- "url": "https://www.patreon.com/feross"
- },
- {
- "type": "consulting",
- "url": "https://feross.org/support"
- }
- ],
- "dependencies": {
- "queue-microtask": "^1.2.2"
- }
- },
- "node_modules/slash": {
- "version": "5.1.0",
- "resolved": "https://registry.npmjs.org/slash/-/slash-5.1.0.tgz",
- "integrity": "sha512-ZA6oR3T/pEyuqwMgAKT0/hAv8oAXckzbkmR0UkUosQ+Mc4RxGoJkRmwHgHufaenlyAgE1Mxgpdcrf75y6XcnDg==",
- "dev": true,
- "engines": {
- "node": ">=14.16"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/source-map-js": {
- "version": "1.2.0",
- "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.0.tgz",
- "integrity": "sha512-itJW8lvSA0TXEphiRoawsCksnlf8SyvmFzIhltqAHluXd88pkCd+cXJVHTDwdCr0IzwptSm035IHQktUu1QUMg==",
- "dev": true,
- "engines": {
- "node": ">=0.10.0"
- }
- },
- "node_modules/string-width": {
- "version": "4.2.3",
- "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
- "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
- "dev": true,
- "dependencies": {
- "emoji-regex": "^8.0.0",
- "is-fullwidth-code-point": "^3.0.0",
- "strip-ansi": "^6.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/strip-ansi": {
- "version": "6.0.1",
- "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
- "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
- "dev": true,
- "dependencies": {
- "ansi-regex": "^5.0.1"
- },
- "engines": {
- "node": ">=8"
- }
- },
- "node_modules/thenby": {
- "version": "1.3.4",
- "resolved": "https://registry.npmjs.org/thenby/-/thenby-1.3.4.tgz",
- "integrity": "sha512-89Gi5raiWA3QZ4b2ePcEwswC3me9JIg+ToSgtE0JWeCynLnLxNr/f9G+xfo9K+Oj4AFdom8YNJjibIARTJmapQ==",
- "dev": true
- },
- "node_modules/to-regex-range": {
- "version": "5.0.1",
- "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
- "integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
- "dev": true,
- "dependencies": {
- "is-number": "^7.0.0"
- },
- "engines": {
- "node": ">=8.0"
- }
- },
- "node_modules/unicorn-magic": {
- "version": "0.1.0",
- "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.1.0.tgz",
- "integrity": "sha512-lRfVq8fE8gz6QMBuDM6a+LO3IAzTi05H6gCVaUpir2E1Rwpo4ZUog45KpNXKC/Mn3Yb9UDuHumeFTo9iV/D9FQ==",
- "dev": true,
- "engines": {
- "node": ">=18"
- },
- "funding": {
- "url": "https://github.com/sponsors/sindresorhus"
- }
- },
- "node_modules/universalify": {
- "version": "2.0.1",
- "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz",
- "integrity": "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==",
- "dev": true,
- "engines": {
- "node": ">= 10.0.0"
- }
- },
- "node_modules/update-browserslist-db": {
- "version": "1.0.13",
- "resolved": "https://registry.npmjs.org/update-browserslist-db/-/update-browserslist-db-1.0.13.tgz",
- "integrity": "sha512-xebP81SNcPuNpPP3uzeW1NYXxI3rxyJzF3pD6sH4jE7o/IX+WtSpwnVU+qIsDPyk0d3hmFQ7mjqc6AtV604hbg==",
- "dev": true,
- "funding": [
- {
- "type": "opencollective",
- "url": "https://opencollective.com/browserslist"
- },
- {
- "type": "tidelift",
- "url": "https://tidelift.com/funding/github/npm/browserslist"
- },
- {
- "type": "github",
- "url": "https://github.com/sponsors/ai"
- }
- ],
- "dependencies": {
- "escalade": "^3.1.1",
- "picocolors": "^1.0.0"
- },
- "bin": {
- "update-browserslist-db": "cli.js"
- },
- "peerDependencies": {
- "browserslist": ">= 4.21.0"
- }
- },
- "node_modules/wrap-ansi": {
- "version": "7.0.0",
- "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
- "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
- "dev": true,
- "dependencies": {
- "ansi-styles": "^4.0.0",
- "string-width": "^4.1.0",
- "strip-ansi": "^6.0.0"
- },
- "engines": {
- "node": ">=10"
- },
- "funding": {
- "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
- }
- },
- "node_modules/y18n": {
- "version": "5.0.8",
- "resolved": "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz",
- "integrity": "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==",
- "dev": true,
- "engines": {
- "node": ">=10"
- }
- },
- "node_modules/yaml": {
- "version": "2.4.1",
- "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.4.1.tgz",
- "integrity": "sha512-pIXzoImaqmfOrL7teGUBt/T7ZDnyeGBWyXQBvOVhLkWLN37GXv8NMLK406UY6dS51JfcQHsmcW5cJ441bHg6Lg==",
- "dev": true,
- "bin": {
- "yaml": "bin.mjs"
- },
- "engines": {
- "node": ">= 14"
- }
- },
- "node_modules/yargs": {
- "version": "17.7.2",
- "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz",
- "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==",
- "dev": true,
- "dependencies": {
- "cliui": "^8.0.1",
- "escalade": "^3.1.1",
- "get-caller-file": "^2.0.5",
- "require-directory": "^2.1.1",
- "string-width": "^4.2.3",
- "y18n": "^5.0.5",
- "yargs-parser": "^21.1.1"
- },
- "engines": {
- "node": ">=12"
- }
- },
- "node_modules/yargs-parser": {
- "version": "21.1.1",
- "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
- "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
- "dev": true,
- "engines": {
- "node": ">=12"
- }
- }
- }
-}
diff --git a/package.json b/package.json
index 0b8682a43..40b16a76c 100644
--- a/package.json
+++ b/package.json
@@ -1,27 +1,20 @@
{
- "name": "tech-doc-hugo",
+ "name": "",
+ "type": "module",
"version": "0.0.1",
- "description": "Hugo theme for technical documentation.",
- "main": "none.js",
"scripts": {
- "test": "echo \"Error: no test specified\" && exit 1"
+ "dev": "astro dev",
+ "start": "astro dev",
+ "build": "astro check && astro build",
+ "preview": "astro preview",
+ "astro": "astro"
},
- "repository": {
- "type": "git",
- "url": "git+https://github.com/bep/tech-doc-hugo.git"
- },
- "author": "",
- "license": "ISC",
- "bugs": {
- "url": "https://github.com/bep/tech-doc-hugo/issues"
- },
- "homepage": "https://github.com/bep/tech-doc-hugo#readme",
"dependencies": {
- "postcss": "^7.0.27"
- },
- "devDependencies": {
- "autoprefixer": "^10.4.19",
- "postcss": "^8.4.38",
- "postcss-cli": "^11.0.0"
+ "@astrojs/check": "^0.9.3",
+ "@astrojs/starlight": "^0.27.1",
+ "@lorenzo_lewis/starlight-utils": "^0.1.2",
+ "astro": "^4.15.3",
+ "sharp": "^0.32.5",
+ "typescript": "^5.6.2"
}
-}
+}
\ No newline at end of file
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
new file mode 100644
index 000000000..6c437ed4b
--- /dev/null
+++ b/pnpm-lock.yaml
@@ -0,0 +1,5316 @@
+lockfileVersion: '9.0'
+
+settings:
+ autoInstallPeers: true
+ excludeLinksFromLockfile: false
+
+importers:
+
+ .:
+ dependencies:
+ '@astrojs/check':
+ specifier: ^0.9.3
+ version: 0.9.3(typescript@5.6.2)
+ '@astrojs/starlight':
+ specifier: ^0.27.1
+ version: 0.27.1(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ '@lorenzo_lewis/starlight-utils':
+ specifier: ^0.1.2
+ version: 0.1.2(@astrojs/starlight@0.27.1(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2)))(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ astro:
+ specifier: ^4.15.3
+ version: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ sharp:
+ specifier: ^0.32.5
+ version: 0.32.6
+ typescript:
+ specifier: ^5.6.2
+ version: 5.6.2
+
+packages:
+
+ '@ampproject/remapping@2.3.0':
+ resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
+ engines: {node: '>=6.0.0'}
+
+ '@astrojs/check@0.9.3':
+ resolution: {integrity: sha512-I6Dz45bMI5YRbp4yK2LKWsHH3/kkHRGdPGruGkLap6pqxhdcNh7oCgN04Ac+haDfc9ow5BYPGPmEhkwef15GQQ==}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+
+ '@astrojs/compiler@2.10.3':
+ resolution: {integrity: sha512-bL/O7YBxsFt55YHU021oL+xz+B/9HvGNId3F9xURN16aeqDK9juHGktdkCSXz+U4nqFACq6ZFvWomOzhV+zfPw==}
+
+ '@astrojs/internal-helpers@0.4.1':
+ resolution: {integrity: sha512-bMf9jFihO8YP940uD70SI/RDzIhUHJAolWVcO1v5PUivxGKvfLZTLTVVxEYzGYyPsA3ivdLNqMnL5VgmQySa+g==}
+
+ '@astrojs/language-server@2.14.2':
+ resolution: {integrity: sha512-daUJ/+/2pPF3eGG4tVdXKyw0tabUDrJKwLzU8VTuNhEHIn3VZAIES6VT3+mX0lmKcMiKM8/bjZdfY+fPfmnsMA==}
+ hasBin: true
+ peerDependencies:
+ prettier: ^3.0.0
+ prettier-plugin-astro: '>=0.11.0'
+ peerDependenciesMeta:
+ prettier:
+ optional: true
+ prettier-plugin-astro:
+ optional: true
+
+ '@astrojs/markdown-remark@5.2.0':
+ resolution: {integrity: sha512-vWGM24KZXz11jR3JO+oqYU3T2qpuOi4uGivJ9SQLCAI01+vEkHC60YJMRvHPc+hwd60F7euNs1PeOEixIIiNQw==}
+
+ '@astrojs/mdx@3.1.6':
+ resolution: {integrity: sha512-YCEIvNgoQG3oVhe9codH4TX6zjvkl7KGla19yZO5RCnvjv2d9zyrfWqJ98I6/m18PbEY3k8Wjvha0IIf5eZ2sQ==}
+ engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
+ peerDependencies:
+ astro: ^4.8.0
+
+ '@astrojs/prism@3.1.0':
+ resolution: {integrity: sha512-Z9IYjuXSArkAUx3N6xj6+Bnvx8OdUSHA8YoOgyepp3+zJmtVYJIl/I18GozdJVW1p5u/CNpl3Km7/gwTJK85cw==}
+ engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
+
+ '@astrojs/sitemap@3.1.6':
+ resolution: {integrity: sha512-1Qp2NvAzVImqA6y+LubKi1DVhve/hXXgFvB0szxiipzh7BvtuKe4oJJ9dXSqaubaTkt4nMa6dv6RCCAYeB6xaQ==}
+
+ '@astrojs/starlight@0.27.1':
+ resolution: {integrity: sha512-L2hEgN/Tk7tfBDeaqUOgOpey5NcUL78FuQa06iNxyZ6RjyYyuXSniOoFxZYIo5PpY9O1dLdK22PkZyCDpO729g==}
+ peerDependencies:
+ astro: ^4.8.6
+
+ '@astrojs/telemetry@3.1.0':
+ resolution: {integrity: sha512-/ca/+D8MIKEC8/A9cSaPUqQNZm+Es/ZinRv0ZAzvu2ios7POQSsVD+VOj7/hypWNsNM3T7RpfgNq7H2TU1KEHA==}
+ engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0}
+
+ '@astrojs/yaml2ts@0.2.1':
+ resolution: {integrity: sha512-CBaNwDQJz20E5WxzQh4thLVfhB3JEEGz72wRA+oJp6fQR37QLAqXZJU0mHC+yqMOQ6oj0GfRPJrz6hjf+zm6zA==}
+
+ '@babel/code-frame@7.24.7':
+ resolution: {integrity: sha512-BcYH1CVJBO9tvyIZ2jVeXgSIMvGZ2FDRvDdOIVQyuklNKSsx+eppDEBq/g47Ayw+RqNFE+URvOShmf+f/qwAlA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/compat-data@7.25.4':
+ resolution: {integrity: sha512-+LGRog6RAsCJrrrg/IO6LGmpphNe5DiK30dGjCoxxeGv49B10/3XYGxPsAwrDlMFcFEvdAUavDT8r9k/hSyQqQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/core@7.25.2':
+ resolution: {integrity: sha512-BBt3opiCOxUr9euZ5/ro/Xv8/V7yJ5bjYMqG/C1YAo8MIKAnumZalCN+msbci3Pigy4lIQfPUpfMM27HMGaYEA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/generator@7.25.6':
+ resolution: {integrity: sha512-VPC82gr1seXOpkjAAKoLhP50vx4vGNlF4msF64dSFq1P8RfB+QAuJWGHPXXPc8QyfVWwwB/TNNU4+ayZmHNbZw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-annotate-as-pure@7.24.7':
+ resolution: {integrity: sha512-BaDeOonYvhdKw+JoMVkAixAAJzG2jVPIwWoKBPdYuY9b452e2rPuI9QPYh3KpofZ3pW2akOmwZLOiOsHMiqRAg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-compilation-targets@7.25.2':
+ resolution: {integrity: sha512-U2U5LsSaZ7TAt3cfaymQ8WHh0pxvdHoEk6HVpaexxixjyEquMh0L0YNJNM6CTGKMXV1iksi0iZkGw4AcFkPaaw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-imports@7.24.7':
+ resolution: {integrity: sha512-8AyH3C+74cgCVVXow/myrynrAGv+nTVg5vKu2nZph9x7RcRwzmh0VFallJuFTZ9mx6u4eSdXZfcOzSqTUm0HCA==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-module-transforms@7.25.2':
+ resolution: {integrity: sha512-BjyRAbix6j/wv83ftcVJmBt72QtHI56C7JXZoG2xATiLpmoC7dpd8WnkikExHDVPpi/3qCmO6WY1EaXOluiecQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0
+
+ '@babel/helper-plugin-utils@7.24.8':
+ resolution: {integrity: sha512-FFWx5142D8h2Mgr/iPVGH5G7w6jDn4jUSpZTyDnQO0Yn7Ks2Kuz6Pci8H6MPCoUJegd/UZQ3tAvfLCxQSnWWwg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-simple-access@7.24.7':
+ resolution: {integrity: sha512-zBAIvbCMh5Ts+b86r/CjU+4XGYIs+R1j951gxI3KmmxBMhCg4oQMsv6ZXQ64XOm/cvzfU1FmoCyt6+owc5QMYg==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-string-parser@7.24.8':
+ resolution: {integrity: sha512-pO9KhhRcuUyGnJWwyEgnRJTSIZHiT+vMD0kPeD+so0l7mxkMT19g3pjY9GTnHySck/hDzq+dtW/4VgnMkippsQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-identifier@7.24.7':
+ resolution: {integrity: sha512-rR+PBcQ1SMQDDyF6X0wxtG8QyLCgUB0eRAGguqRLfkCA87l7yAP7ehq8SNj96OOGTO8OBV70KhuFYcIkHXOg0w==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helper-validator-option@7.24.8':
+ resolution: {integrity: sha512-xb8t9tD1MHLungh/AIoWYN+gVHaB9kwlu8gffXGSt3FFEIT7RjS+xWbc2vUD1UTZdIpKj/ab3rdqJ7ufngyi2Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/helpers@7.25.6':
+ resolution: {integrity: sha512-Xg0tn4HcfTijTwfDwYlvVCl43V6h4KyVVX2aEm4qdO/PC6L2YvzLHFdmxhoeSA3eslcE6+ZVXHgWwopXYLNq4Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/highlight@7.24.7':
+ resolution: {integrity: sha512-EStJpq4OuY8xYfhGVXngigBJRWxftKX9ksiGDnmlY3o7B/V7KIAc9X4oiK87uPJSc/vs5L869bem5fhZa8caZw==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/parser@7.25.6':
+ resolution: {integrity: sha512-trGdfBdbD0l1ZPmcJ83eNxB9rbEax4ALFTF7fN386TMYbeCQbyme5cOEXQhbGXKebwGaB/J52w1mrklMcbgy6Q==}
+ engines: {node: '>=6.0.0'}
+ hasBin: true
+
+ '@babel/plugin-syntax-jsx@7.24.7':
+ resolution: {integrity: sha512-6ddciUPe/mpMnOKv/U+RSd2vvVy+Yw/JfBB0ZHYjEZt9NLHmCUylNYlsbqCCS1Bffjlb0fCwC9Vqz+sBz6PsiQ==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/plugin-transform-react-jsx@7.25.2':
+ resolution: {integrity: sha512-KQsqEAVBpU82NM/B/N9j9WOdphom1SZH3R+2V7INrQUH+V9EBFwZsEJl8eBIVeQE62FxJCc70jzEZwqU7RcVqA==}
+ engines: {node: '>=6.9.0'}
+ peerDependencies:
+ '@babel/core': ^7.0.0-0
+
+ '@babel/template@7.25.0':
+ resolution: {integrity: sha512-aOOgh1/5XzKvg1jvVz7AVrx2piJ2XBi227DHmbY6y+bM9H2FlN+IfecYu4Xl0cNiiVejlsCri89LUsbj8vJD9Q==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/traverse@7.25.6':
+ resolution: {integrity: sha512-9Vrcx5ZW6UwK5tvqsj0nGpp/XzqthkT0dqIc9g1AdtygFToNtTF67XzYS//dm+SAK9cp3B9R4ZO/46p63SCjlQ==}
+ engines: {node: '>=6.9.0'}
+
+ '@babel/types@7.25.6':
+ resolution: {integrity: sha512-/l42B1qxpG6RdfYf343Uw1vmDjeNhneUXtzhojE7pDgfpEypmRhI6j1kr17XCVv4Cgl9HdAiQY2x0GwKm7rWCw==}
+ engines: {node: '>=6.9.0'}
+
+ '@ctrl/tinycolor@4.1.0':
+ resolution: {integrity: sha512-WyOx8cJQ+FQus4Mm4uPIZA64gbk3Wxh0so5Lcii0aJifqwoVOlfFtorjLE0Hen4OYyHZMXDWqMmaQemBhgxFRQ==}
+ engines: {node: '>=14'}
+
+ '@emmetio/abbreviation@2.3.3':
+ resolution: {integrity: sha512-mgv58UrU3rh4YgbE/TzgLQwJ3pFsHHhCLqY20aJq+9comytTXUDNGG/SMtSeMJdkpxgXSXunBGLD8Boka3JyVA==}
+
+ '@emmetio/css-abbreviation@2.1.8':
+ resolution: {integrity: sha512-s9yjhJ6saOO/uk1V74eifykk2CBYi01STTK3WlXWGOepyKa23ymJ053+DNQjpFcy1ingpaO7AxCcwLvHFY9tuw==}
+
+ '@emmetio/css-parser@0.4.0':
+ resolution: {integrity: sha512-z7wkxRSZgrQHXVzObGkXG+Vmj3uRlpM11oCZ9pbaz0nFejvCDmAiNDpY75+wgXOcffKpj4rzGtwGaZxfJKsJxw==}
+
+ '@emmetio/html-matcher@1.3.0':
+ resolution: {integrity: sha512-NTbsvppE5eVyBMuyGfVu2CRrLvo7J4YHb6t9sBFLyY03WYhXET37qA4zOYUjBWFCRHO7pS1B9khERtY0f5JXPQ==}
+
+ '@emmetio/scanner@1.0.4':
+ resolution: {integrity: sha512-IqRuJtQff7YHHBk4G8YZ45uB9BaAGcwQeVzgj/zj8/UdOhtQpEIupUhSk8dys6spFIWVZVeK20CzGEnqR5SbqA==}
+
+ '@emmetio/stream-reader-utils@0.1.0':
+ resolution: {integrity: sha512-ZsZ2I9Vzso3Ho/pjZFsmmZ++FWeEd/txqybHTm4OgaZzdS8V9V/YYWQwg5TC38Z7uLWUV1vavpLLbjJtKubR1A==}
+
+ '@emmetio/stream-reader@2.2.0':
+ resolution: {integrity: sha512-fXVXEyFA5Yv3M3n8sUGT7+fvecGrZP4k6FnWWMSZVQf69kAq0LLpaBQLGcPR30m3zMmKYhECP4k/ZkzvhEW5kw==}
+
+ '@emnapi/runtime@1.2.0':
+ resolution: {integrity: sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==}
+
+ '@esbuild/aix-ppc64@0.21.5':
+ resolution: {integrity: sha512-1SDgH6ZSPTlggy1yI6+Dbkiz8xzpHJEVAlF/AM1tHPLsf5STom9rwtjE4hKAF20FfXXNTFqEYXyJNWh1GiZedQ==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [aix]
+
+ '@esbuild/android-arm64@0.21.5':
+ resolution: {integrity: sha512-c0uX9VAUBQ7dTDCjq+wdyGLowMdtR/GoC2U5IYk/7D1H1JYC0qseD7+11iMP2mRLN9RcCMRcjC4YMclCzGwS/A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [android]
+
+ '@esbuild/android-arm@0.21.5':
+ resolution: {integrity: sha512-vCPvzSjpPHEi1siZdlvAlsPxXl7WbOVUBBAowWug4rJHb68Ox8KualB+1ocNvT5fjv6wpkX6o/iEpbDrf68zcg==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [android]
+
+ '@esbuild/android-x64@0.21.5':
+ resolution: {integrity: sha512-D7aPRUUNHRBwHxzxRvp856rjUHRFW1SdQATKXH2hqA0kAZb1hKmi02OpYRacl0TxIGz/ZmXWlbZgjwWYaCakTA==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [android]
+
+ '@esbuild/darwin-arm64@0.21.5':
+ resolution: {integrity: sha512-DwqXqZyuk5AiWWf3UfLiRDJ5EDd49zg6O9wclZ7kUMv2WRFr4HKjXp/5t8JZ11QbQfUS6/cRCKGwYhtNAY88kQ==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@esbuild/darwin-x64@0.21.5':
+ resolution: {integrity: sha512-se/JjF8NlmKVG4kNIuyWMV/22ZaerB+qaSi5MdrXtd6R08kvs2qCN4C09miupktDitvh8jRFflwGFBQcxZRjbw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [darwin]
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ resolution: {integrity: sha512-5JcRxxRDUJLX8JXp/wcBCy3pENnCgBR9bN6JsY4OmhfUtIHe3ZW0mawA7+RDAcMLrMIZaf03NlQiX9DGyB8h4g==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [freebsd]
+
+ '@esbuild/freebsd-x64@0.21.5':
+ resolution: {integrity: sha512-J95kNBj1zkbMXtHVH29bBriQygMXqoVQOQYA+ISs0/2l3T9/kj42ow2mpqerRBxDJnmkUDCaQT/dfNXWX/ZZCQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [freebsd]
+
+ '@esbuild/linux-arm64@0.21.5':
+ resolution: {integrity: sha512-ibKvmyYzKsBeX8d8I7MH/TMfWDXBF3db4qM6sy+7re0YXya+K1cem3on9XgdT2EQGMu4hQyZhan7TeQ8XkGp4Q==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [linux]
+
+ '@esbuild/linux-arm@0.21.5':
+ resolution: {integrity: sha512-bPb5AHZtbeNGjCKVZ9UGqGwo8EUu4cLq68E95A53KlxAPRmUyYv2D6F0uUI65XisGOL1hBP5mTronbgo+0bFcA==}
+ engines: {node: '>=12'}
+ cpu: [arm]
+ os: [linux]
+
+ '@esbuild/linux-ia32@0.21.5':
+ resolution: {integrity: sha512-YvjXDqLRqPDl2dvRODYmmhz4rPeVKYvppfGYKSNGdyZkA01046pLWyRKKI3ax8fbJoK5QbxblURkwK/MWY18Tg==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [linux]
+
+ '@esbuild/linux-loong64@0.21.5':
+ resolution: {integrity: sha512-uHf1BmMG8qEvzdrzAqg2SIG/02+4/DHB6a9Kbya0XDvwDEKCoC8ZRWI5JJvNdUjtciBGFQ5PuBlpEOXQj+JQSg==}
+ engines: {node: '>=12'}
+ cpu: [loong64]
+ os: [linux]
+
+ '@esbuild/linux-mips64el@0.21.5':
+ resolution: {integrity: sha512-IajOmO+KJK23bj52dFSNCMsz1QP1DqM6cwLUv3W1QwyxkyIWecfafnI555fvSGqEKwjMXVLokcV5ygHW5b3Jbg==}
+ engines: {node: '>=12'}
+ cpu: [mips64el]
+ os: [linux]
+
+ '@esbuild/linux-ppc64@0.21.5':
+ resolution: {integrity: sha512-1hHV/Z4OEfMwpLO8rp7CvlhBDnjsC3CttJXIhBi+5Aj5r+MBvy4egg7wCbe//hSsT+RvDAG7s81tAvpL2XAE4w==}
+ engines: {node: '>=12'}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@esbuild/linux-riscv64@0.21.5':
+ resolution: {integrity: sha512-2HdXDMd9GMgTGrPWnJzP2ALSokE/0O5HhTUvWIbD3YdjME8JwvSCnNGBnTThKGEB91OZhzrJ4qIIxk/SBmyDDA==}
+ engines: {node: '>=12'}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@esbuild/linux-s390x@0.21.5':
+ resolution: {integrity: sha512-zus5sxzqBJD3eXxwvjN1yQkRepANgxE9lgOW2qLnmr8ikMTphkjgXu1HR01K4FJg8h1kEEDAqDcZQtbrRnB41A==}
+ engines: {node: '>=12'}
+ cpu: [s390x]
+ os: [linux]
+
+ '@esbuild/linux-x64@0.21.5':
+ resolution: {integrity: sha512-1rYdTpyv03iycF1+BhzrzQJCdOuAOtaqHTWJZCWvijKD2N5Xu0TtVC8/+1faWqcP9iBCWOmjmhoH94dH82BxPQ==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [linux]
+
+ '@esbuild/netbsd-x64@0.21.5':
+ resolution: {integrity: sha512-Woi2MXzXjMULccIwMnLciyZH4nCIMpWQAs049KEeMvOcNADVxo0UBIQPfSmxB3CWKedngg7sWZdLvLczpe0tLg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [netbsd]
+
+ '@esbuild/openbsd-x64@0.21.5':
+ resolution: {integrity: sha512-HLNNw99xsvx12lFBUwoT8EVCsSvRNDVxNpjZ7bPn947b8gJPzeHWyNVhFsaerc0n3TsbOINvRP2byTZ5LKezow==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [openbsd]
+
+ '@esbuild/sunos-x64@0.21.5':
+ resolution: {integrity: sha512-6+gjmFpfy0BHU5Tpptkuh8+uw3mnrvgs+dSPQXQOv3ekbordwnzTVEb4qnIvQcYXq6gzkyTnoZ9dZG+D4garKg==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [sunos]
+
+ '@esbuild/win32-arm64@0.21.5':
+ resolution: {integrity: sha512-Z0gOTd75VvXqyq7nsl93zwahcTROgqvuAcYDUr+vOv8uHhNSKROyU961kgtCD1e95IqPKSQKH7tBTslnS3tA8A==}
+ engines: {node: '>=12'}
+ cpu: [arm64]
+ os: [win32]
+
+ '@esbuild/win32-ia32@0.21.5':
+ resolution: {integrity: sha512-SWXFF1CL2RVNMaVs+BBClwtfZSvDgtL//G/smwAc5oVK/UPu2Gu9tIaRgFmYFFKrmg3SyAjSrElf0TiJ1v8fYA==}
+ engines: {node: '>=12'}
+ cpu: [ia32]
+ os: [win32]
+
+ '@esbuild/win32-x64@0.21.5':
+ resolution: {integrity: sha512-tQd/1efJuzPC6rCFwEvLtci/xNFcTZknmXs98FYDfGE4wP9ClFV98nyKrzJKVPMhdDnjzLhdUyMX4PsQAPjwIw==}
+ engines: {node: '>=12'}
+ cpu: [x64]
+ os: [win32]
+
+ '@expressive-code/core@0.35.6':
+ resolution: {integrity: sha512-xGqCkmfkgT7lr/rvmfnYdDSeTdCSp1otAHgoFS6wNEeO7wGDPpxdosVqYiIcQ8CfWUABh/pGqWG90q+MV3824A==}
+
+ '@expressive-code/plugin-frames@0.35.6':
+ resolution: {integrity: sha512-CqjSWjDJ3wabMJZfL9ZAzH5UAGKg7KWsf1TBzr4xvUbZvWoBtLA/TboBML0U1Ls8h/4TRCIvR4VEb8dv5+QG3w==}
+
+ '@expressive-code/plugin-shiki@0.35.6':
+ resolution: {integrity: sha512-xm+hzi9BsmhkDUGuyAWIydOAWer7Cs9cj8FM0t4HXaQ+qCubprT6wJZSKUxuvFJIUsIOqk1xXFaJzGJGnWtKMg==}
+
+ '@expressive-code/plugin-text-markers@0.35.6':
+ resolution: {integrity: sha512-/k9eWVZSCs+uEKHR++22Uu6eIbHWEciVHbIuD8frT8DlqTtHYaaiwHPncO6KFWnGDz5i/gL7oyl6XmOi/E6GVg==}
+
+ '@img/sharp-darwin-arm64@0.33.5':
+ resolution: {integrity: sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-darwin-x64@0.33.5':
+ resolution: {integrity: sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-arm64@1.0.4':
+ resolution: {integrity: sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@img/sharp-libvips-darwin-x64@1.0.4':
+ resolution: {integrity: sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@img/sharp-libvips-linux-arm64@1.0.4':
+ resolution: {integrity: sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-arm@1.0.5':
+ resolution: {integrity: sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-s390x@1.0.4':
+ resolution: {integrity: sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-libvips-linux-x64@1.0.4':
+ resolution: {integrity: sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
+ resolution: {integrity: sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.4':
+ resolution: {integrity: sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linux-arm64@0.33.5':
+ resolution: {integrity: sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linux-arm@0.33.5':
+ resolution: {integrity: sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm]
+ os: [linux]
+
+ '@img/sharp-linux-s390x@0.33.5':
+ resolution: {integrity: sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [s390x]
+ os: [linux]
+
+ '@img/sharp-linux-x64@0.33.5':
+ resolution: {integrity: sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-arm64@0.33.5':
+ resolution: {integrity: sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [arm64]
+ os: [linux]
+
+ '@img/sharp-linuxmusl-x64@0.33.5':
+ resolution: {integrity: sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [linux]
+
+ '@img/sharp-wasm32@0.33.5':
+ resolution: {integrity: sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [wasm32]
+
+ '@img/sharp-win32-ia32@0.33.5':
+ resolution: {integrity: sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [ia32]
+ os: [win32]
+
+ '@img/sharp-win32-x64@0.33.5':
+ resolution: {integrity: sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+ cpu: [x64]
+ os: [win32]
+
+ '@jridgewell/gen-mapping@0.3.5':
+ resolution: {integrity: sha512-IzL8ZoEDIBRWEzlCcRhOaCupYyN5gdIK+Q6fbFdPDg6HqX6jpkItn7DFIpW9LQzXG6Df9sA7+OKnq0qlz/GaQg==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/resolve-uri@3.1.2':
+ resolution: {integrity: sha512-bRISgCIjP20/tbWSPWMEi54QVPRZExkuD9lJL+UIxUKtwVJA8wW1Trb1jMs1RFXo1CBTNZ/5hpC9QvmKWdopKw==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/set-array@1.2.1':
+ resolution: {integrity: sha512-R8gLRTZeyp03ymzP/6Lil/28tGeGEzhx1q2k703KGWRAI1VdvPIXdG70VJc2pAMw3NA6JKL5hhFu1sJX0Mnn/A==}
+ engines: {node: '>=6.0.0'}
+
+ '@jridgewell/sourcemap-codec@1.5.0':
+ resolution: {integrity: sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ resolution: {integrity: sha512-vNk6aEwybGtawWmy/PzwnGDOjCkLWSD2wqvjGGAgOAwCGWySYXfYoxt00IJkTF+8Lb57DwOb3Aa0o9CApepiYQ==}
+
+ '@lorenzo_lewis/starlight-utils@0.1.2':
+ resolution: {integrity: sha512-qj7pXh+L0dzt3rryVt6WxqTILqhmUVAwepwJN5C65fk1YaB7dx6SrPk65h3E7Q2An+2GWnnADQX7Fnb56Msx9Q==}
+ peerDependencies:
+ '@astrojs/starlight': '>=0.16.0'
+ astro: '>=4.0.0'
+
+ '@mdx-js/mdx@3.0.1':
+ resolution: {integrity: sha512-eIQ4QTrOWyL3LWEe/bu6Taqzq2HQvHcyTMaOrI95P2/LmJE7AsfPfgJGuFLPVqBUE1BC1rik3VIhU+s9u72arA==}
+
+ '@nodelib/fs.scandir@2.1.5':
+ resolution: {integrity: sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.stat@2.0.5':
+ resolution: {integrity: sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==}
+ engines: {node: '>= 8'}
+
+ '@nodelib/fs.walk@1.2.8':
+ resolution: {integrity: sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==}
+ engines: {node: '>= 8'}
+
+ '@oslojs/encoding@0.4.1':
+ resolution: {integrity: sha512-hkjo6MuIK/kQR5CrGNdAPZhS01ZCXuWDRJ187zh6qqF2+yMHZpD9fAYpX8q2bOO6Ryhl3XpCT6kUX76N8hhm4Q==}
+
+ '@pagefind/darwin-arm64@1.1.1':
+ resolution: {integrity: sha512-tZ9tysUmQpFs2EqWG2+E1gc+opDAhSyZSsgKmFzhnWfkK02YHZhvL5XJXEZDqYy3s1FAKhwjTg8XDxneuBlDZQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@pagefind/darwin-x64@1.1.1':
+ resolution: {integrity: sha512-ChohLQ39dLwaxQv0jIQB/SavP3TM5K5ENfDTqIdzLkmfs3+JlzSDyQKcJFjTHYcCzQOZVeieeGq8PdqvLJxJxQ==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@pagefind/default-ui@1.1.1':
+ resolution: {integrity: sha512-ZM0zDatWDnac/VGHhQCiM7UgA4ca8jpjA+VfuTJyHJBaxGqZMQnm4WoTz9E0KFcue1Bh9kxpu7uWFZfwpZZk0A==}
+
+ '@pagefind/linux-arm64@1.1.1':
+ resolution: {integrity: sha512-H5P6wDoCoAbdsWp0Zx0DxnLUrwTGWGLu/VI1rcN2CyFdY2EGSvPQsbGBMrseKRNuIrJDFtxHHHyjZ7UbzaM9EA==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@pagefind/linux-x64@1.1.1':
+ resolution: {integrity: sha512-yJs7tTYbL2MI3HT+ngs9E1BfUbY9M4/YzA0yEM5xBo4Xl8Yu8Qg2xZTOQ1/F6gwvMrjCUFo8EoACs6LRDhtMrQ==}
+ cpu: [x64]
+ os: [linux]
+
+ '@pagefind/windows-x64@1.1.1':
+ resolution: {integrity: sha512-b7/qPqgIl+lMzkQ8fJt51SfguB396xbIIR+VZ3YrL2tLuyifDJ1wL5mEm+ddmHxJ2Fki340paPcDan9en5OmAw==}
+ cpu: [x64]
+ os: [win32]
+
+ '@rollup/pluginutils@5.1.0':
+ resolution: {integrity: sha512-XTIWOPPcpvyKI6L1NHo0lFlCyznUEyPmPY1mc3KpPVDYulHSTvyeLNVW00QTLIAFNhR3kYnJTQHeGqU4M3n09g==}
+ engines: {node: '>=14.0.0'}
+ peerDependencies:
+ rollup: ^1.20.0||^2.0.0||^3.0.0||^4.0.0
+ peerDependenciesMeta:
+ rollup:
+ optional: true
+
+ '@rollup/rollup-android-arm-eabi@4.21.3':
+ resolution: {integrity: sha512-MmKSfaB9GX+zXl6E8z4koOr/xU63AMVleLEa64v7R0QF/ZloMs5vcD1sHgM64GXXS1csaJutG+ddtzcueI/BLg==}
+ cpu: [arm]
+ os: [android]
+
+ '@rollup/rollup-android-arm64@4.21.3':
+ resolution: {integrity: sha512-zrt8ecH07PE3sB4jPOggweBjJMzI1JG5xI2DIsUbkA+7K+Gkjys6eV7i9pOenNSDJH3eOr/jLb/PzqtmdwDq5g==}
+ cpu: [arm64]
+ os: [android]
+
+ '@rollup/rollup-darwin-arm64@4.21.3':
+ resolution: {integrity: sha512-P0UxIOrKNBFTQaXTxOH4RxuEBVCgEA5UTNV6Yz7z9QHnUJ7eLX9reOd/NYMO3+XZO2cco19mXTxDMXxit4R/eQ==}
+ cpu: [arm64]
+ os: [darwin]
+
+ '@rollup/rollup-darwin-x64@4.21.3':
+ resolution: {integrity: sha512-L1M0vKGO5ASKntqtsFEjTq/fD91vAqnzeaF6sfNAy55aD+Hi2pBI5DKwCO+UNDQHWsDViJLqshxOahXyLSh3EA==}
+ cpu: [x64]
+ os: [darwin]
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.21.3':
+ resolution: {integrity: sha512-btVgIsCjuYFKUjopPoWiDqmoUXQDiW2A4C3Mtmp5vACm7/GnyuprqIDPNczeyR5W8rTXEbkmrJux7cJmD99D2g==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm-musleabihf@4.21.3':
+ resolution: {integrity: sha512-zmjbSphplZlau6ZTkxd3+NMtE4UKVy7U4aVFMmHcgO5CUbw17ZP6QCgyxhzGaU/wFFdTfiojjbLG3/0p9HhAqA==}
+ cpu: [arm]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-gnu@4.21.3':
+ resolution: {integrity: sha512-nSZfcZtAnQPRZmUkUQwZq2OjQciR6tEoJaZVFvLHsj0MF6QhNMg0fQ6mUOsiCUpTqxTx0/O6gX0V/nYc7LrgPw==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-arm64-musl@4.21.3':
+ resolution: {integrity: sha512-MnvSPGO8KJXIMGlQDYfvYS3IosFN2rKsvxRpPO2l2cum+Z3exiExLwVU+GExL96pn8IP+GdH8Tz70EpBhO0sIQ==}
+ cpu: [arm64]
+ os: [linux]
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.21.3':
+ resolution: {integrity: sha512-+W+p/9QNDr2vE2AXU0qIy0qQE75E8RTwTwgqS2G5CRQ11vzq0tbnfBd6brWhS9bCRjAjepJe2fvvkvS3dno+iw==}
+ cpu: [ppc64]
+ os: [linux]
+
+ '@rollup/rollup-linux-riscv64-gnu@4.21.3':
+ resolution: {integrity: sha512-yXH6K6KfqGXaxHrtr+Uoy+JpNlUlI46BKVyonGiaD74ravdnF9BUNC+vV+SIuB96hUMGShhKV693rF9QDfO6nQ==}
+ cpu: [riscv64]
+ os: [linux]
+
+ '@rollup/rollup-linux-s390x-gnu@4.21.3':
+ resolution: {integrity: sha512-R8cwY9wcnApN/KDYWTH4gV/ypvy9yZUHlbJvfaiXSB48JO3KpwSpjOGqO4jnGkLDSk1hgjYkTbTt6Q7uvPf8eg==}
+ cpu: [s390x]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-gnu@4.21.3':
+ resolution: {integrity: sha512-kZPbX/NOPh0vhS5sI+dR8L1bU2cSO9FgxwM8r7wHzGydzfSjLRCFAT87GR5U9scj2rhzN3JPYVC7NoBbl4FZ0g==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-linux-x64-musl@4.21.3':
+ resolution: {integrity: sha512-S0Yq+xA1VEH66uiMNhijsWAafffydd2X5b77eLHfRmfLsRSpbiAWiRHV6DEpz6aOToPsgid7TI9rGd6zB1rhbg==}
+ cpu: [x64]
+ os: [linux]
+
+ '@rollup/rollup-win32-arm64-msvc@4.21.3':
+ resolution: {integrity: sha512-9isNzeL34yquCPyerog+IMCNxKR8XYmGd0tHSV+OVx0TmE0aJOo9uw4fZfUuk2qxobP5sug6vNdZR6u7Mw7Q+Q==}
+ cpu: [arm64]
+ os: [win32]
+
+ '@rollup/rollup-win32-ia32-msvc@4.21.3':
+ resolution: {integrity: sha512-nMIdKnfZfzn1Vsk+RuOvl43ONTZXoAPUUxgcU0tXooqg4YrAqzfKzVenqqk2g5efWh46/D28cKFrOzDSW28gTA==}
+ cpu: [ia32]
+ os: [win32]
+
+ '@rollup/rollup-win32-x64-msvc@4.21.3':
+ resolution: {integrity: sha512-fOvu7PCQjAj4eWDEuD8Xz5gpzFqXzGlxHZozHP4b9Jxv9APtdxL6STqztDzMLuRXEc4UpXGGhx029Xgm91QBeA==}
+ cpu: [x64]
+ os: [win32]
+
+ '@shikijs/core@1.17.6':
+ resolution: {integrity: sha512-9ztslig6/YmCg/XwESAXbKjAjOhaq6HVced9NY6qcbDz1X5g/S90Wco2vMjBNX/6V71ASkzri76JewSGPa7kiQ==}
+
+ '@shikijs/engine-javascript@1.17.6':
+ resolution: {integrity: sha512-5EEZj8tVcierNxm4V0UMS2PVoflb0UJPalWWV8l9rRg+oOfnr5VivqBJbkyq5grltVPvByIXvVbY8GSM/356jQ==}
+
+ '@shikijs/engine-oniguruma@1.17.6':
+ resolution: {integrity: sha512-NLfWDMXFYe0nDHFbEoyZdz89aIIey3bTfF3zLYSUNTXks5s4uinZVmuPOFf1HfTeGqIn8uErJSBc3VnpJO7Alw==}
+
+ '@shikijs/types@1.17.6':
+ resolution: {integrity: sha512-ndTFa2TJi2w51ddKQDn3Jy8f6K4E5Q2x3dA3Hmsd3+YmxDQ10UWHjcw7VbVbKzv3VcUvYPLy+z9neqytSzUMUg==}
+
+ '@shikijs/vscode-textmate@9.2.2':
+ resolution: {integrity: sha512-TMp15K+GGYrWlZM8+Lnj9EaHEFmOen0WJBrfa17hF7taDOYthuPPV0GWzfd/9iMij0akS/8Yw2ikquH7uVi/fg==}
+
+ '@types/acorn@4.0.6':
+ resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==}
+
+ '@types/babel__core@7.20.5':
+ resolution: {integrity: sha512-qoQprZvz5wQFJwMDqeseRXWv3rqMvhgpbXFfVyWhbx9X47POIA6i/+dXefEmZKoAgOaTdaIgNSMqMIU61yRyzA==}
+
+ '@types/babel__generator@7.6.8':
+ resolution: {integrity: sha512-ASsj+tpEDsEiFr1arWrlN6V3mdfjRMZt6LtK/Vp/kreFLnr5QH5+DhvD5nINYZXzwJvXeGq+05iUXcAzVrqWtw==}
+
+ '@types/babel__template@7.4.4':
+ resolution: {integrity: sha512-h/NUaSyG5EyxBIp8YRxo4RMe2/qQgvyowRwVMzhYhBCONbW8PUsg4lkFMrhgZhUe5z3L3MiLDuvyJ/CaPa2A8A==}
+
+ '@types/babel__traverse@7.20.6':
+ resolution: {integrity: sha512-r1bzfrm0tomOI8g1SzvCaQHo6Lcv6zu0EA+W2kHrt8dyrHQxGzBBL4kdkzIS+jBMV+EYcMAEAqXqYaLJq5rOZg==}
+
+ '@types/cookie@0.6.0':
+ resolution: {integrity: sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==}
+
+ '@types/debug@4.1.12':
+ resolution: {integrity: sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==}
+
+ '@types/estree-jsx@1.0.5':
+ resolution: {integrity: sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==}
+
+ '@types/estree@1.0.5':
+ resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==}
+
+ '@types/hast@3.0.4':
+ resolution: {integrity: sha512-WPs+bbQw5aCj+x6laNGWLH3wviHtoCv/P3+otBhbOhJgG8qtpdAMlTCxLtsTWA7LH1Oh/bFCHsBn0TPS5m30EQ==}
+
+ '@types/mdast@4.0.4':
+ resolution: {integrity: sha512-kGaNbPh1k7AFzgpud/gMdvIm5xuECykRR+JnWKQno9TAXVa6WIVCGTPvYGekIDL4uwCZQSYbUxNBSb1aUo79oA==}
+
+ '@types/mdx@2.0.13':
+ resolution: {integrity: sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==}
+
+ '@types/ms@0.7.34':
+ resolution: {integrity: sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==}
+
+ '@types/nlcst@2.0.3':
+ resolution: {integrity: sha512-vSYNSDe6Ix3q+6Z7ri9lyWqgGhJTmzRjZRqyq15N0Z/1/UnVsno9G/N40NBijoYx2seFDIl0+B2mgAb9mezUCA==}
+
+ '@types/node@17.0.45':
+ resolution: {integrity: sha512-w+tIMs3rq2afQdsPJlODhoUEKzFP1ayaoyl1CcnwtIlsVe7K7bA1NGm4s3PraqTLlXnbIN84zuBlxBWo1u9BLw==}
+
+ '@types/sax@1.2.7':
+ resolution: {integrity: sha512-rO73L89PJxeYM3s3pPPjiPgVVcymqU490g0YO5n5By0k2Erzj6tay/4lr1CHAAU4JyOWd1rpQ8bCf6cZfHU96A==}
+
+ '@types/unist@2.0.11':
+ resolution: {integrity: sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==}
+
+ '@types/unist@3.0.3':
+ resolution: {integrity: sha512-ko/gIFJRv177XgZsZcBwnqJN5x/Gien8qNOn0D5bQU/zAzVf9Zt3BlcUiLqhV9y4ARk0GbT3tnUiPNgnTXzc/Q==}
+
+ '@ungap/structured-clone@1.2.0':
+ resolution: {integrity: sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==}
+
+ '@volar/kit@2.4.4':
+ resolution: {integrity: sha512-6WusqQ4YhtIYbqY3nlLnkSbfBRSakx5HcTKdF+WjGKBj5D74ux9nsLq3uAqQlbpKgVkkt425KEDymQTb4C36Kg==}
+ peerDependencies:
+ typescript: '*'
+
+ '@volar/language-core@2.4.4':
+ resolution: {integrity: sha512-kO9k4kTLfxpg+6lq7/KAIv3m2d62IHuCL6GbVgYZTpfKvIGoAIlDxK7pFcB/eczN2+ydg/vnyaeZ6SGyZrJw2w==}
+
+ '@volar/language-server@2.4.4':
+ resolution: {integrity: sha512-rBzTgRw4/msZSFRSJURFU53qcDfBNm40NtYoMwOyaZuPcLzdgDAZ3hzVE80Rj0pk82LQJ0AfH13Y+EYFvUWkfQ==}
+
+ '@volar/language-service@2.4.4':
+ resolution: {integrity: sha512-QXfZV3IpJdcNQcdWFEG+iXOIb3NiC6/cNIQeH2QAOMx2vpkshuMcWD7AzrhVavobircOXJNiGmRGwqf2okYE3A==}
+
+ '@volar/source-map@2.4.4':
+ resolution: {integrity: sha512-xG3PZqOP2haG8XG4Pg3PD1UGDAdqZg24Ru8c/qYjYAnmcj6GBR64mstx+bZux5QOyRaJK+/lNM/RnpvBD3489g==}
+
+ '@volar/typescript@2.4.4':
+ resolution: {integrity: sha512-QQMQRVj0fVHJ3XdRKiS1LclhG0VBXdFYlyuHRQF/xLk2PuJuHNWP26MDZNvEVCvnyUQuUQhIAfylwY5TGPgc6w==}
+
+ '@vscode/emmet-helper@2.9.3':
+ resolution: {integrity: sha512-rB39LHWWPQYYlYfpv9qCoZOVioPCftKXXqrsyqN1mTWZM6dTnONT63Db+03vgrBbHzJN45IrgS/AGxw9iiqfEw==}
+
+ '@vscode/l10n@0.0.18':
+ resolution: {integrity: sha512-KYSIHVmslkaCDyw013pphY+d7x1qV8IZupYfeIfzNA+nsaWHbn5uPuQRvdRFsa9zFzGeudPuoGoZ1Op4jrJXIQ==}
+
+ acorn-jsx@5.3.2:
+ resolution: {integrity: sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==}
+ peerDependencies:
+ acorn: ^6.0.0 || ^7.0.0 || ^8.0.0
+
+ acorn@8.12.1:
+ resolution: {integrity: sha512-tcpGyI9zbizT9JbV6oYE477V6mTlXvvi0T0G3SNIYE2apm/G5huBa1+K89VGeovbg+jycCrfhl3ADxErOuO6Jg==}
+ engines: {node: '>=0.4.0'}
+ hasBin: true
+
+ ajv@8.17.1:
+ resolution: {integrity: sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==}
+
+ ansi-align@3.0.1:
+ resolution: {integrity: sha512-IOfwwBF5iczOjp/WeY4YxyjqAFMQoZufdQWDd19SEExbVLNXqvpzSJ/M7Za4/sCPmQ0+GRquoA7bGcINcxew6w==}
+
+ ansi-regex@5.0.1:
+ resolution: {integrity: sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==}
+ engines: {node: '>=8'}
+
+ ansi-regex@6.1.0:
+ resolution: {integrity: sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==}
+ engines: {node: '>=12'}
+
+ ansi-styles@3.2.1:
+ resolution: {integrity: sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==}
+ engines: {node: '>=4'}
+
+ ansi-styles@4.3.0:
+ resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==}
+ engines: {node: '>=8'}
+
+ ansi-styles@6.2.1:
+ resolution: {integrity: sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==}
+ engines: {node: '>=12'}
+
+ anymatch@3.1.3:
+ resolution: {integrity: sha512-KMReFUr0B4t+D+OBkjR3KYqvocp2XaSzO55UcB6mgQMd3KbcE+mWTyvVV7D/zsdEbNnV6acZUutkiHQXvTr1Rw==}
+ engines: {node: '>= 8'}
+
+ arg@5.0.2:
+ resolution: {integrity: sha512-PYjyFOLKQ9y57JvQ6QLo8dAgNqswh8M1RMJYdQduT6xbWSgK36P/Z/v+p888pM69jMMfS8Xd8F6I1kQ/I9HUGg==}
+
+ argparse@1.0.10:
+ resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==}
+
+ argparse@2.0.1:
+ resolution: {integrity: sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==}
+
+ aria-query@5.3.1:
+ resolution: {integrity: sha512-Z/ZeOgVl7bcSYZ/u/rh0fOpvEpq//LZmdbkXyc7syVzjPAhfOa9ebsdTSjEBDU4vs5nC98Kfduj1uFo0qyET3g==}
+ engines: {node: '>= 0.4'}
+
+ array-iterate@2.0.1:
+ resolution: {integrity: sha512-I1jXZMjAgCMmxT4qxXfPXa6SthSoE8h6gkSI9BGGNv8mP8G/v0blc+qFnZu6K42vTOiuME596QaLO0TP3Lk0xg==}
+
+ ast-types@0.16.1:
+ resolution: {integrity: sha512-6t10qk83GOG8p0vKmaCr8eiilZwO171AvbROMtvvNiwrTly62t+7XkA8RdIIVbpMhCASAsxgAzdRSwh6nw/5Dg==}
+ engines: {node: '>=4'}
+
+ astring@1.9.0:
+ resolution: {integrity: sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==}
+ hasBin: true
+
+ astro-expressive-code@0.35.6:
+ resolution: {integrity: sha512-1U4KrvFuodaCV3z4I1bIR16SdhQlPkolGsYTtiANxPZUVv/KitGSCTjzksrkPonn1XuwVqvnwmUUVzTLWngnBA==}
+ peerDependencies:
+ astro: ^4.0.0-beta || ^3.3.0
+
+ astro-integration-kit@0.14.0:
+ resolution: {integrity: sha512-Tg85rlRRKEkTK2a02XJByvNOuzGN1eDIfAJxwHPUTOn/iE7yFxL9RaLqSdO8X8PxnbL4e1H6OkK6AVFnHZob9A==}
+ peerDependencies:
+ '@astrojs/db': ^0.9 || ^0.10 || ^0.11
+ astro: ^4.4.1
+ peerDependenciesMeta:
+ '@astrojs/db':
+ optional: true
+
+ astro@4.15.5:
+ resolution: {integrity: sha512-zcHXpRav0dtYpddxoGMDN7A7SKrGL9wsu5IxLjqCcZhylfZ/5mfLfoGYnSg7aFwuAleUXP66lyfY+GDbFTbF2w==}
+ engines: {node: ^18.17.1 || ^20.3.0 || >=21.0.0, npm: '>=9.6.5', pnpm: '>=7.1.0'}
+ hasBin: true
+
+ axobject-query@4.1.0:
+ resolution: {integrity: sha512-qIj0G9wZbMGNLjLmg1PT6v2mE9AH2zlnADJD/2tC6E00hgmhUOfEB6greHPAfLRSufHqROIUTkw6E+M3lH0PTQ==}
+ engines: {node: '>= 0.4'}
+
+ b4a@1.6.6:
+ resolution: {integrity: sha512-5Tk1HLk6b6ctmjIkAcU/Ujv/1WqiDl0F0JdRCR80VsOcUlHcu7pWeWRlOqQLHfDEsVx9YH/aif5AG4ehoCtTmg==}
+
+ bail@2.0.2:
+ resolution: {integrity: sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==}
+
+ bare-events@2.4.2:
+ resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==}
+
+ bare-fs@2.3.5:
+ resolution: {integrity: sha512-SlE9eTxifPDJrT6YgemQ1WGFleevzwY+XAP1Xqgl56HtcrisC2CHCZ2tq6dBpcH2TnNxwUEUGhweo+lrQtYuiw==}
+
+ bare-os@2.4.4:
+ resolution: {integrity: sha512-z3UiI2yi1mK0sXeRdc4O1Kk8aOa/e+FNWZcTiPB/dfTWyLypuE99LibgRaQki914Jq//yAWylcAt+mknKdixRQ==}
+
+ bare-path@2.1.3:
+ resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==}
+
+ bare-stream@2.3.0:
+ resolution: {integrity: sha512-pVRWciewGUeCyKEuRxwv06M079r+fRjAQjBEK2P6OYGrO43O+Z0LrPZZEjlc4mB6C2RpZ9AxJ1s7NLEtOHO6eA==}
+
+ base-64@1.0.0:
+ resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==}
+
+ base64-js@1.5.1:
+ resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==}
+
+ bcp-47-match@2.0.3:
+ resolution: {integrity: sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==}
+
+ bcp-47@2.1.0:
+ resolution: {integrity: sha512-9IIS3UPrvIa1Ej+lVDdDwO7zLehjqsaByECw0bu2RRGP73jALm6FYbzI5gWbgHLvNdkvfXB5YrSbocZdOS0c0w==}
+
+ binary-extensions@2.3.0:
+ resolution: {integrity: sha512-Ceh+7ox5qe7LJuLHoY0feh3pHuUDHAcRUeyL2VYghZwfpkNIy/+8Ocg0a3UuSoYzavmylwuLWQOf3hl0jjMMIw==}
+ engines: {node: '>=8'}
+
+ bl@4.1.0:
+ resolution: {integrity: sha512-1W07cM9gS6DcLperZfFSj+bWLtaPGSOHWhPiGzXmvVJbRLdG82sH/Kn8EtW1VqWVA54AKf2h5k5BbnIbwF3h6w==}
+
+ boolbase@1.0.0:
+ resolution: {integrity: sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==}
+
+ boxen@7.1.1:
+ resolution: {integrity: sha512-2hCgjEmP8YLWQ130n2FerGv7rYpfBmnmp9Uy2Le1vge6X3gZIfSmEzP5QTDElFxcvVcXlEn8Aq6MU/PZygIOog==}
+ engines: {node: '>=14.16'}
+
+ braces@3.0.3:
+ resolution: {integrity: sha512-yQbXgO/OSZVD2IsiLlro+7Hf6Q18EJrKSEsdoMzKePKXct3gvD8oLcOQdIzGupr5Fj+EDe8gO/lxc1BzfMpxvA==}
+ engines: {node: '>=8'}
+
+ browserslist@4.23.3:
+ resolution: {integrity: sha512-btwCFJVjI4YWDNfau8RhZ+B1Q/VLoUITrm3RlP6y1tYGWIOa+InuYiRGXUBXo8nA1qKmHMyLB/iVQg5TT4eFoA==}
+ engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7}
+ hasBin: true
+
+ buffer@5.7.1:
+ resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==}
+
+ camelcase@7.0.1:
+ resolution: {integrity: sha512-xlx1yCK2Oc1APsPXDL2LdlNP6+uu8OCDdhOBSVT279M/S+y75O30C2VuD8T2ogdePBBl7PfPF4504tnLgX3zfw==}
+ engines: {node: '>=14.16'}
+
+ caniuse-lite@1.0.30001660:
+ resolution: {integrity: sha512-GacvNTTuATm26qC74pt+ad1fW15mlQ/zuTzzY1ZoIzECTP8HURDfF43kNxPgf7H1jmelCBQTTbBNxdSXOA7Bqg==}
+
+ ccount@2.0.1:
+ resolution: {integrity: sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==}
+
+ chalk@2.4.2:
+ resolution: {integrity: sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==}
+ engines: {node: '>=4'}
+
+ chalk@5.3.0:
+ resolution: {integrity: sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==}
+ engines: {node: ^12.17.0 || ^14.13 || >=16.0.0}
+
+ character-entities-html4@2.1.0:
+ resolution: {integrity: sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==}
+
+ character-entities-legacy@3.0.0:
+ resolution: {integrity: sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==}
+
+ character-entities@2.0.2:
+ resolution: {integrity: sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==}
+
+ character-reference-invalid@2.0.1:
+ resolution: {integrity: sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==}
+
+ chokidar@3.6.0:
+ resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==}
+ engines: {node: '>= 8.10.0'}
+
+ chownr@1.1.4:
+ resolution: {integrity: sha512-jJ0bqzaylmJtVnNgzTeSOs8DPavpbYgEr/b0YL8/2GO3xJEhInFmhKMUnEJQjZumK7KXGFhUy89PrsJWlakBVg==}
+
+ ci-info@4.0.0:
+ resolution: {integrity: sha512-TdHqgGf9odd8SXNuxtUBVx8Nv+qZOejE6qyqiy5NtbYYQOeFa6zmHkxlPzmaLxWWHsU6nJmB7AETdVPi+2NBUg==}
+ engines: {node: '>=8'}
+
+ cli-boxes@3.0.0:
+ resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
+ engines: {node: '>=10'}
+
+ cli-cursor@5.0.0:
+ resolution: {integrity: sha512-aCj4O5wKyszjMmDT4tZj93kxyydN/K5zPWSCe6/0AV/AA1pqe5ZBIw0a2ZfPQV7lL5/yb5HsUreJ6UFAF1tEQw==}
+ engines: {node: '>=18'}
+
+ cli-spinners@2.9.2:
+ resolution: {integrity: sha512-ywqV+5MmyL4E7ybXgKys4DugZbX0FC6LnwrhjuykIjnK9k8OQacQ7axGKnjDXWNhns0xot3bZI5h55H8yo9cJg==}
+ engines: {node: '>=6'}
+
+ cliui@8.0.1:
+ resolution: {integrity: sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==}
+ engines: {node: '>=12'}
+
+ clsx@2.1.1:
+ resolution: {integrity: sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==}
+ engines: {node: '>=6'}
+
+ collapse-white-space@2.1.0:
+ resolution: {integrity: sha512-loKTxY1zCOuG4j9f6EPnuyyYkf58RnhhWTvRoZEokgB+WbdXehfjFviyOVYkqzEWz1Q5kRiZdBYS5SwxbQYwzw==}
+
+ color-convert@1.9.3:
+ resolution: {integrity: sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==}
+
+ color-convert@2.0.1:
+ resolution: {integrity: sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==}
+ engines: {node: '>=7.0.0'}
+
+ color-name@1.1.3:
+ resolution: {integrity: sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==}
+
+ color-name@1.1.4:
+ resolution: {integrity: sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==}
+
+ color-string@1.9.1:
+ resolution: {integrity: sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==}
+
+ color@4.2.3:
+ resolution: {integrity: sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==}
+ engines: {node: '>=12.5.0'}
+
+ comma-separated-tokens@2.0.3:
+ resolution: {integrity: sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==}
+
+ common-ancestor-path@1.0.1:
+ resolution: {integrity: sha512-L3sHRo1pXXEqX8VU28kfgUY+YGsk09hPqZiZmLacNib6XNTCM8ubYeT7ryXQw8asB1sKgcU5lkB7ONug08aB8w==}
+
+ convert-source-map@2.0.0:
+ resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
+
+ cookie@0.6.0:
+ resolution: {integrity: sha512-U71cyTamuh1CRNCfpGY6to28lxvNwPG4Guz/EVjgf3Jmzv0vlDp1atT9eS5dDjMYHucpHbWns6Lwf3BKz6svdw==}
+ engines: {node: '>= 0.6'}
+
+ css-selector-parser@3.0.5:
+ resolution: {integrity: sha512-3itoDFbKUNx1eKmVpYMFyqKX04Ww9osZ+dLgrk6GEv6KMVeXUhUnp4I5X+evw+u3ZxVU6RFXSSRxlTeMh8bA+g==}
+
+ cssesc@3.0.0:
+ resolution: {integrity: sha512-/Tb/JcjK111nNScGob5MNtsntNM1aCNUDipB/TkwZFhyDrrE47SOx/18wF2bbjgc3ZzCSKW1T5nt5EbFoAz/Vg==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ debug@4.3.7:
+ resolution: {integrity: sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ==}
+ engines: {node: '>=6.0'}
+ peerDependencies:
+ supports-color: '*'
+ peerDependenciesMeta:
+ supports-color:
+ optional: true
+
+ decode-named-character-reference@1.0.2:
+ resolution: {integrity: sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==}
+
+ decompress-response@6.0.0:
+ resolution: {integrity: sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==}
+ engines: {node: '>=10'}
+
+ deep-extend@0.6.0:
+ resolution: {integrity: sha512-LOHxIOaPYdHlJRtCQfDIVZtfw/ufM8+rVj649RIHzcm/vGwQRXFt6OPqIFWsm2XEMrNIEtWR64sY1LEKD2vAOA==}
+ engines: {node: '>=4.0.0'}
+
+ dequal@2.0.3:
+ resolution: {integrity: sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==}
+ engines: {node: '>=6'}
+
+ detect-libc@2.0.3:
+ resolution: {integrity: sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==}
+ engines: {node: '>=8'}
+
+ deterministic-object-hash@2.0.2:
+ resolution: {integrity: sha512-KxektNH63SrbfUyDiwXqRb1rLwKt33AmMv+5Nhsw1kqZ13SJBRTgZHtGbE+hH3a1mVW1cz+4pqSWVPAtLVXTzQ==}
+ engines: {node: '>=18'}
+
+ devalue@5.0.0:
+ resolution: {integrity: sha512-gO+/OMXF7488D+u3ue+G7Y4AA3ZmUnB3eHJXmBTgNHvr4ZNzl36A0ZtG+XCRNYCkYx/bFmw4qtkoFLa+wSrwAA==}
+
+ devlop@1.1.0:
+ resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==}
+
+ diff@5.2.0:
+ resolution: {integrity: sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==}
+ engines: {node: '>=0.3.1'}
+
+ direction@2.0.1:
+ resolution: {integrity: sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==}
+ hasBin: true
+
+ dlv@1.1.3:
+ resolution: {integrity: sha512-+HlytyjlPKnIG8XuRG8WvmBP8xs8P71y+SKKS6ZXWoEgLuePxtDoUEiH7WkdePWrQ5JBpE6aoVqfZfJUQkjXwA==}
+
+ dset@3.1.4:
+ resolution: {integrity: sha512-2QF/g9/zTaPDc3BjNcVTGoBbXBgYfMTTceLaYcFJ/W9kggFUkhxD/hMEeuLKbugyef9SqAx8cpgwlIP/jinUTA==}
+ engines: {node: '>=4'}
+
+ eastasianwidth@0.2.0:
+ resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==}
+
+ electron-to-chromium@1.5.22:
+ resolution: {integrity: sha512-tKYm5YHPU1djz0O+CGJ+oJIvimtsCcwR2Z9w7Skh08lUdyzXY5djods3q+z2JkWdb7tCcmM//eVavSRAiaPRNg==}
+
+ emmet@2.4.7:
+ resolution: {integrity: sha512-O5O5QNqtdlnQM2bmKHtJgyChcrFMgQuulI+WdiOw2NArzprUqqxUW6bgYtKvzKgrsYpuLWalOkdhNP+1jluhCA==}
+
+ emoji-regex@10.4.0:
+ resolution: {integrity: sha512-EC+0oUMY1Rqm4O6LLrgjtYDvcVYTy7chDnM4Q7030tP4Kwj3u/pR6gP9ygnp2CJMK5Gq+9Q2oqmrFJAz01DXjw==}
+
+ emoji-regex@8.0.0:
+ resolution: {integrity: sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==}
+
+ emoji-regex@9.2.2:
+ resolution: {integrity: sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==}
+
+ end-of-stream@1.4.4:
+ resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==}
+
+ entities@4.5.0:
+ resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==}
+ engines: {node: '>=0.12'}
+
+ es-module-lexer@1.5.4:
+ resolution: {integrity: sha512-MVNK56NiMrOwitFB7cqDwq0CQutbw+0BvLshJSse0MUNU+y1FC3bUS/AQg7oUng+/wKrrki7JfmwtVHkVfPLlw==}
+
+ esbuild@0.21.5:
+ resolution: {integrity: sha512-mg3OPMV4hXywwpoDxu3Qda5xCKQi+vCTZq8S9J/EpkhB2HzKXq4SNFZE3+NK93JYxc8VMSep+lOUSC/RVKaBqw==}
+ engines: {node: '>=12'}
+ hasBin: true
+
+ escalade@3.2.0:
+ resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
+ engines: {node: '>=6'}
+
+ escape-string-regexp@1.0.5:
+ resolution: {integrity: sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==}
+ engines: {node: '>=0.8.0'}
+
+ escape-string-regexp@5.0.0:
+ resolution: {integrity: sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==}
+ engines: {node: '>=12'}
+
+ esprima@4.0.1:
+ resolution: {integrity: sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ estree-util-attach-comments@3.0.0:
+ resolution: {integrity: sha512-cKUwm/HUcTDsYh/9FgnuFqpfquUbwIqwKM26BVCGDPVgvaCl/nDCCjUfiLlx6lsEZ3Z4RFxNbOQ60pkaEwFxGw==}
+
+ estree-util-build-jsx@3.0.1:
+ resolution: {integrity: sha512-8U5eiL6BTrPxp/CHbs2yMgP8ftMhR5ww1eIKoWRMlqvltHF8fZn5LRDvTKuxD3DUn+shRbLGqXemcP51oFCsGQ==}
+
+ estree-util-is-identifier-name@3.0.0:
+ resolution: {integrity: sha512-hFtqIDZTIUZ9BXLb8y4pYGyk6+wekIivNVTcmvk8NoOh+VeRn5y6cEHzbURrWbfp1fIqdVipilzj+lfaadNZmg==}
+
+ estree-util-to-js@2.0.0:
+ resolution: {integrity: sha512-WDF+xj5rRWmD5tj6bIqRi6CkLIXbbNQUcxQHzGysQzvHmdYG2G7p/Tf0J0gpxGgkeMZNTIjT/AoSvC9Xehcgdg==}
+
+ estree-util-visit@2.0.0:
+ resolution: {integrity: sha512-m5KgiH85xAhhW8Wta0vShLcUvOsh3LLPI2YVwcbio1l7E09NTLL1EyMZFM1OyWowoH0skScNbhOPl4kcBgzTww==}
+
+ estree-walker@2.0.2:
+ resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==}
+
+ estree-walker@3.0.3:
+ resolution: {integrity: sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==}
+
+ eventemitter3@5.0.1:
+ resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==}
+
+ expand-template@2.0.3:
+ resolution: {integrity: sha512-XYfuKMvj4O35f/pOXLObndIRvyQ+/+6AhODh+OKWj9S9498pHHn/IMszH+gt0fBCRWMNfk1ZSp5x3AifmnI2vg==}
+ engines: {node: '>=6'}
+
+ expressive-code@0.35.6:
+ resolution: {integrity: sha512-+mx+TPTbMqgo0mL92Xh9QgjW0kSQIsEivMgEcOnaqKqL7qCw8Vkqc5Rg/di7ZYw4aMUSr74VTc+w8GQWu05j1g==}
+
+ extend-shallow@2.0.1:
+ resolution: {integrity: sha512-zCnTtlxNoAiDc3gqY2aYAWFx7XWWiasuF2K8Me5WbN8otHKTUKBwjPtNpRs/rbUZm7KxWAaNj7P1a/p52GbVug==}
+ engines: {node: '>=0.10.0'}
+
+ extend@3.0.2:
+ resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==}
+
+ fast-deep-equal@3.1.3:
+ resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==}
+
+ fast-fifo@1.3.2:
+ resolution: {integrity: sha512-/d9sfos4yxzpwkDkuN7k2SqFKtYNmCTzgfEpz82x34IM9/zc8KGxQoXg1liNC/izpRM/MBdt44Nmx41ZWqk+FQ==}
+
+ fast-glob@3.3.2:
+ resolution: {integrity: sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==}
+ engines: {node: '>=8.6.0'}
+
+ fast-uri@3.0.1:
+ resolution: {integrity: sha512-MWipKbbYiYI0UC7cl8m/i/IWTqfC8YXsqjzybjddLsFjStroQzsHXkc73JutMvBiXmOvapk+axIl79ig5t55Bw==}
+
+ fastq@1.17.1:
+ resolution: {integrity: sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==}
+
+ fill-range@7.1.1:
+ resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==}
+ engines: {node: '>=8'}
+
+ find-up-simple@1.0.0:
+ resolution: {integrity: sha512-q7Us7kcjj2VMePAa02hDAF6d+MzsdsAWEwYyOpwUtlerRBkOEPBCRZrAV4XfcSN8fHAgaD0hP7miwoay6DCprw==}
+ engines: {node: '>=18'}
+
+ find-up@4.1.0:
+ resolution: {integrity: sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==}
+ engines: {node: '>=8'}
+
+ find-yarn-workspace-root2@1.2.16:
+ resolution: {integrity: sha512-hr6hb1w8ePMpPVUK39S4RlwJzi+xPLuVuG8XlwXU3KD5Yn3qgBWVfy3AzNlDhWvE1EORCE65/Qm26rFQt3VLVA==}
+
+ flattie@1.1.1:
+ resolution: {integrity: sha512-9UbaD6XdAL97+k/n+N7JwX46K/M6Zc6KcFYskrYL8wbBV/Uyk0CTAMY0VT+qiK5PM7AIc9aTWYtq65U7T+aCNQ==}
+ engines: {node: '>=8'}
+
+ fs-constants@1.0.0:
+ resolution: {integrity: sha512-y6OAwoSIf7FyjMIv94u+b5rdheZEjzR63GTyZJm5qh4Bi+2YgwLCcI/fPFZkL5PSixOt6ZNKm+w+Hfp/Bciwow==}
+
+ fsevents@2.3.3:
+ resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==}
+ engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0}
+ os: [darwin]
+
+ gensync@1.0.0-beta.2:
+ resolution: {integrity: sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==}
+ engines: {node: '>=6.9.0'}
+
+ get-caller-file@2.0.5:
+ resolution: {integrity: sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==}
+ engines: {node: 6.* || 8.* || >= 10.*}
+
+ get-east-asian-width@1.2.0:
+ resolution: {integrity: sha512-2nk+7SIVb14QrgXFHcm84tD4bKQz0RxPuMT8Ag5KPOq7J5fEmAg0UbXdTOSHqNuHSU28k55qnceesxXRZGzKWA==}
+ engines: {node: '>=18'}
+
+ github-from-package@0.0.0:
+ resolution: {integrity: sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==}
+
+ github-slugger@2.0.0:
+ resolution: {integrity: sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==}
+
+ glob-parent@5.1.2:
+ resolution: {integrity: sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==}
+ engines: {node: '>= 6'}
+
+ globals@11.12.0:
+ resolution: {integrity: sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==}
+ engines: {node: '>=4'}
+
+ graceful-fs@4.2.11:
+ resolution: {integrity: sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==}
+
+ gray-matter@4.0.3:
+ resolution: {integrity: sha512-5v6yZd4JK3eMI3FqqCouswVqwugaA9r4dNZB1wwcmrD02QkV5H0y7XBQW8QwQqEaZY1pM9aqORSORhJRdNK44Q==}
+ engines: {node: '>=6.0'}
+
+ has-flag@3.0.0:
+ resolution: {integrity: sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==}
+ engines: {node: '>=4'}
+
+ hast-util-embedded@3.0.0:
+ resolution: {integrity: sha512-naH8sld4Pe2ep03qqULEtvYr7EjrLK2QHY8KJR6RJkTUjPGObe1vnx585uzem2hGra+s1q08DZZpfgDVYRbaXA==}
+
+ hast-util-from-html@2.0.2:
+ resolution: {integrity: sha512-HwOHwxdt2zC5KQ/CNoybBntRook2zJvfZE/u5/Ap7aLPe22bDqen7KwGkOqOyzL5zIqKwiYX/OTtE0FWgr6XXA==}
+
+ hast-util-from-parse5@8.0.1:
+ resolution: {integrity: sha512-Er/Iixbc7IEa7r/XLtuG52zoqn/b3Xng/w6aZQ0xGVxzhw5xUFxcRqdPzP6yFi/4HBYRaifaI5fQ1RH8n0ZeOQ==}
+
+ hast-util-has-property@3.0.0:
+ resolution: {integrity: sha512-MNilsvEKLFpV604hwfhVStK0usFY/QmM5zX16bo7EjnAEGofr5YyI37kzopBlZJkHD4t887i+q/C8/tr5Q94cA==}
+
+ hast-util-is-body-ok-link@3.0.0:
+ resolution: {integrity: sha512-VFHY5bo2nY8HiV6nir2ynmEB1XkxzuUffhEGeVx7orbu/B1KaGyeGgMZldvMVx5xWrDlLLG/kQ6YkJAMkBEx0w==}
+
+ hast-util-is-element@3.0.0:
+ resolution: {integrity: sha512-Val9mnv2IWpLbNPqc/pUem+a7Ipj2aHacCwgNfTiK0vJKl0LF+4Ba4+v1oPHFpf3bLYmreq0/l3Gud9S5OH42g==}
+
+ hast-util-parse-selector@4.0.0:
+ resolution: {integrity: sha512-wkQCkSYoOGCRKERFWcxMVMOcYE2K1AaNLU8DXS9arxnLOUEWbOXKXiJUNzEpqZ3JOKpnha3jkFrumEjVliDe7A==}
+
+ hast-util-phrasing@3.0.1:
+ resolution: {integrity: sha512-6h60VfI3uBQUxHqTyMymMZnEbNl1XmEGtOxxKYL7stY2o601COo62AWAYBQR9lZbYXYSBoxag8UpPRXK+9fqSQ==}
+
+ hast-util-raw@9.0.4:
+ resolution: {integrity: sha512-LHE65TD2YiNsHD3YuXcKPHXPLuYh/gjp12mOfU8jxSrm1f/yJpsb0F/KKljS6U9LJoP0Ux+tCe8iJ2AsPzTdgA==}
+
+ hast-util-select@6.0.2:
+ resolution: {integrity: sha512-hT/SD/d/Meu+iobvgkffo1QecV8WeKWxwsNMzcTJsKw1cKTQKSR/7ArJeURLNJF9HDjp9nVoORyNNJxrvBye8Q==}
+
+ hast-util-to-estree@3.1.0:
+ resolution: {integrity: sha512-lfX5g6hqVh9kjS/B9E2gSkvHH4SZNiQFiqWS0x9fENzEl+8W12RqdRxX6d/Cwxi30tPQs3bIO+aolQJNp1bIyw==}
+
+ hast-util-to-html@9.0.2:
+ resolution: {integrity: sha512-RP5wNpj5nm1Z8cloDv4Sl4RS8jH5HYa0v93YB6Wb4poEzgMo/dAAL0KcT4974dCjcNG5pkLqTImeFHHCwwfY3g==}
+
+ hast-util-to-jsx-runtime@2.3.0:
+ resolution: {integrity: sha512-H/y0+IWPdsLLS738P8tDnrQ8Z+dj12zQQ6WC11TIM21C8WFVoIxcqWXf2H3hiTVZjF1AWqoimGwrTWecWrnmRQ==}
+
+ hast-util-to-parse5@8.0.0:
+ resolution: {integrity: sha512-3KKrV5ZVI8if87DVSi1vDeByYrkGzg4mEfeu4alwgmmIeARiBLKCZS2uw5Gb6nU9x9Yufyj3iudm6i7nl52PFw==}
+
+ hast-util-to-string@3.0.0:
+ resolution: {integrity: sha512-OGkAxX1Ua3cbcW6EJ5pT/tslVb90uViVkcJ4ZZIMW/R33DX/AkcJcRrPebPwJkHYwlDHXz4aIwvAAaAdtrACFA==}
+
+ hast-util-to-text@4.0.2:
+ resolution: {integrity: sha512-KK6y/BN8lbaq654j7JgBydev7wuNMcID54lkRav1P0CaE1e47P72AWWPiGKXTJU271ooYzcvTAn/Zt0REnvc7A==}
+
+ hast-util-whitespace@3.0.0:
+ resolution: {integrity: sha512-88JUN06ipLwsnv+dVn+OIYOvAuvBMy/Qoi6O7mQHxdPXpjy+Cd6xRkWwux7DKO+4sYILtLBRIKgsdpS2gQc7qw==}
+
+ hastscript@8.0.0:
+ resolution: {integrity: sha512-dMOtzCEd3ABUeSIISmrETiKuyydk1w0pa+gE/uormcTpSYuaNJPbX1NU3JLyscSLjwAQM8bWMhhIlnCqnRvDTw==}
+
+ hastscript@9.0.0:
+ resolution: {integrity: sha512-jzaLBGavEDKHrc5EfFImKN7nZKKBdSLIdGvCwDZ9TfzbF2ffXiov8CKE445L2Z1Ek2t/m4SKQ2j6Ipv7NyUolw==}
+
+ html-escaper@3.0.3:
+ resolution: {integrity: sha512-RuMffC89BOWQoY0WKGpIhn5gX3iI54O6nRA0yC124NYVtzjmFWBIiFd8M0x+ZdX0P9R4lADg1mgP8C7PxGOWuQ==}
+
+ html-void-elements@3.0.0:
+ resolution: {integrity: sha512-bEqo66MRXsUGxWHV5IP0PUiAWwoEjba4VCzg0LjFJBpchPaTfyfCKTG6bc5F8ucKec3q5y6qOdGyYTSBEvhCrg==}
+
+ html-whitespace-sensitive-tag-names@3.0.0:
+ resolution: {integrity: sha512-KlClZ3/Qy5UgvpvVvDomGhnQhNWH5INE8GwvSIQ9CWt1K0zbbXrl7eN5bWaafOZgtmO3jMPwUqmrmEwinhPq1w==}
+
+ http-cache-semantics@4.1.1:
+ resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==}
+
+ ieee754@1.2.1:
+ resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==}
+
+ import-meta-resolve@4.1.0:
+ resolution: {integrity: sha512-I6fiaX09Xivtk+THaMfAwnA3MVA5Big1WHF1Dfx9hFuvNIWpXnorlkzhcQf6ehrqQiiZECRt1poOAkPmer3ruw==}
+
+ inherits@2.0.4:
+ resolution: {integrity: sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==}
+
+ ini@1.3.8:
+ resolution: {integrity: sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==}
+
+ inline-style-parser@0.1.1:
+ resolution: {integrity: sha512-7NXolsK4CAS5+xvdj5OMMbI962hU/wvwoxk+LWR9Ek9bVtyuuYScDN6eS0rUm6TxApFpw7CX1o4uJzcd4AyD3Q==}
+
+ inline-style-parser@0.2.4:
+ resolution: {integrity: sha512-0aO8FkhNZlj/ZIbNi7Lxxr12obT7cL1moPfE4tg1LkX7LlLfC6DeX4l2ZEud1ukP9jNQyNnfzQVqwbwmAATY4Q==}
+
+ is-alphabetical@2.0.1:
+ resolution: {integrity: sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==}
+
+ is-alphanumerical@2.0.1:
+ resolution: {integrity: sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==}
+
+ is-arrayish@0.3.2:
+ resolution: {integrity: sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==}
+
+ is-binary-path@2.1.0:
+ resolution: {integrity: sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw==}
+ engines: {node: '>=8'}
+
+ is-decimal@2.0.1:
+ resolution: {integrity: sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==}
+
+ is-docker@3.0.0:
+ resolution: {integrity: sha512-eljcgEDlEns/7AXFosB5K/2nCM4P7FQPkGc/DWLy5rmFEWvZayGrik1d9/QIY5nJ4f9YsVvBkA6kJpHn9rISdQ==}
+ engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0}
+ hasBin: true
+
+ is-extendable@0.1.1:
+ resolution: {integrity: sha512-5BMULNob1vgFX6EjQw5izWDxrecWK9AM72rugNr0TFldMOi0fj6Jk+zeKIt0xGj4cEfQIJth4w3OKWOJ4f+AFw==}
+ engines: {node: '>=0.10.0'}
+
+ is-extglob@2.1.1:
+ resolution: {integrity: sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ==}
+ engines: {node: '>=0.10.0'}
+
+ is-fullwidth-code-point@3.0.0:
+ resolution: {integrity: sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==}
+ engines: {node: '>=8'}
+
+ is-glob@4.0.3:
+ resolution: {integrity: sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg==}
+ engines: {node: '>=0.10.0'}
+
+ is-hexadecimal@2.0.1:
+ resolution: {integrity: sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==}
+
+ is-inside-container@1.0.0:
+ resolution: {integrity: sha512-KIYLCCJghfHZxqjYBE7rEy0OBuTd5xCHS7tHVgvCLkx7StIoaxwNW3hCALgEUjFfeRk+MG/Qxmp/vtETEF3tRA==}
+ engines: {node: '>=14.16'}
+ hasBin: true
+
+ is-interactive@2.0.0:
+ resolution: {integrity: sha512-qP1vozQRI+BMOPcjFzrjXuQvdak2pHNUMZoeG2eRbiSqyvbEf/wQtEOTOX1guk6E3t36RkaqiSt8A/6YElNxLQ==}
+ engines: {node: '>=12'}
+
+ is-number@7.0.0:
+ resolution: {integrity: sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==}
+ engines: {node: '>=0.12.0'}
+
+ is-plain-obj@4.1.0:
+ resolution: {integrity: sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==}
+ engines: {node: '>=12'}
+
+ is-reference@3.0.2:
+ resolution: {integrity: sha512-v3rht/LgVcsdZa3O2Nqs+NMowLOxeOm7Ay9+/ARQ2F+qEoANRcqrjAZKGN0v8ymUetZGgkp26LTnGT7H0Qo9Pg==}
+
+ is-unicode-supported@1.3.0:
+ resolution: {integrity: sha512-43r2mRvz+8JRIKnWJ+3j8JtjRKZ6GmjzfaE/qiBJnikNnYv/6bagRJ1kUhNk8R5EX/GkobD+r+sfxCPJsiKBLQ==}
+ engines: {node: '>=12'}
+
+ is-unicode-supported@2.1.0:
+ resolution: {integrity: sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==}
+ engines: {node: '>=18'}
+
+ is-wsl@3.1.0:
+ resolution: {integrity: sha512-UcVfVfaK4Sc4m7X3dUSoHoozQGBEFeDC+zVo06t98xe8CzHSZZBekNXH+tu0NalHolcJ/QAGqS46Hef7QXBIMw==}
+ engines: {node: '>=16'}
+
+ js-tokens@4.0.0:
+ resolution: {integrity: sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==}
+
+ js-yaml@3.14.1:
+ resolution: {integrity: sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==}
+ hasBin: true
+
+ js-yaml@4.1.0:
+ resolution: {integrity: sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==}
+ hasBin: true
+
+ jsesc@2.5.2:
+ resolution: {integrity: sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==}
+ engines: {node: '>=4'}
+ hasBin: true
+
+ json-schema-traverse@1.0.0:
+ resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==}
+
+ json5@2.2.3:
+ resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==}
+ engines: {node: '>=6'}
+ hasBin: true
+
+ jsonc-parser@2.3.1:
+ resolution: {integrity: sha512-H8jvkz1O50L3dMZCsLqiuB2tA7muqbSg1AtGEkN0leAqGjsUzDJir3Zwr02BhqdcITPg3ei3mZ+HjMocAknhhg==}
+
+ jsonc-parser@3.3.1:
+ resolution: {integrity: sha512-HUgH65KyejrUFPvHFPbqOY0rsFip3Bo5wb4ngvdi1EpCYWUQDC5V+Y7mZws+DLkr4M//zQJoanu1SP+87Dv1oQ==}
+
+ kind-of@6.0.3:
+ resolution: {integrity: sha512-dcS1ul+9tmeD95T+x28/ehLgd9mENa3LsvDTtzm3vyBEO7RPptvAD+t44WVXaUjTBRcrpFeFlC8WCruUR456hw==}
+ engines: {node: '>=0.10.0'}
+
+ kleur@3.0.3:
+ resolution: {integrity: sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w==}
+ engines: {node: '>=6'}
+
+ kleur@4.1.5:
+ resolution: {integrity: sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==}
+ engines: {node: '>=6'}
+
+ load-yaml-file@0.2.0:
+ resolution: {integrity: sha512-OfCBkGEw4nN6JLtgRidPX6QxjBQGQf72q3si2uvqyFEMbycSFFHwAZeXx6cJgFM9wmLrf9zBwCP3Ivqa+LLZPw==}
+ engines: {node: '>=6'}
+
+ locate-path@5.0.0:
+ resolution: {integrity: sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==}
+ engines: {node: '>=8'}
+
+ lodash@4.17.21:
+ resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==}
+
+ log-symbols@6.0.0:
+ resolution: {integrity: sha512-i24m8rpwhmPIS4zscNzK6MSEhk0DUWa/8iYQWxhffV8jkI4Phvs3F+quL5xvS0gdQR0FyTCMMH33Y78dDTzzIw==}
+ engines: {node: '>=18'}
+
+ longest-streak@3.1.0:
+ resolution: {integrity: sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==}
+
+ lru-cache@5.1.1:
+ resolution: {integrity: sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==}
+
+ magic-string@0.30.11:
+ resolution: {integrity: sha512-+Wri9p0QHMy+545hKww7YAu5NyzF8iomPL/RQazugQ9+Ez4Ic3mERMd8ZTX5rfK944j+560ZJi8iAwgak1Ac7A==}
+
+ magicast@0.3.5:
+ resolution: {integrity: sha512-L0WhttDl+2BOsybvEOLK7fW3UA0OQ0IQ2d6Zl2x/a6vVRs3bAY0ECOSHHeL5jD+SbOpOCUEi0y1DgHEn9Qn1AQ==}
+
+ markdown-extensions@2.0.0:
+ resolution: {integrity: sha512-o5vL7aDWatOTX8LzaS1WMoaoxIiLRQJuIKKe2wAw6IeULDHaqbiqiggmx+pKvZDb1Sj+pE46Sn1T7lCqfFtg1Q==}
+ engines: {node: '>=16'}
+
+ markdown-table@3.0.3:
+ resolution: {integrity: sha512-Z1NL3Tb1M9wH4XESsCDEksWoKTdlUafKc4pt0GRwjUyXaCFZ+dc3g2erqB6zm3szA2IUSi7VnPI+o/9jnxh9hw==}
+
+ mdast-util-definitions@6.0.0:
+ resolution: {integrity: sha512-scTllyX6pnYNZH/AIp/0ePz6s4cZtARxImwoPJ7kS42n+MnVsI4XbnG6d4ibehRIldYMWM2LD7ImQblVhUejVQ==}
+
+ mdast-util-directive@3.0.0:
+ resolution: {integrity: sha512-JUpYOqKI4mM3sZcNxmF/ox04XYFFkNwr0CFlrQIkCwbvH0xzMCqkMqAde9wRd80VAhaUrwFwKm2nxretdT1h7Q==}
+
+ mdast-util-find-and-replace@3.0.1:
+ resolution: {integrity: sha512-SG21kZHGC3XRTSUhtofZkBzZTJNM5ecCi0SK2IMKmSXR8vO3peL+kb1O0z7Zl83jKtutG4k5Wv/W7V3/YHvzPA==}
+
+ mdast-util-from-markdown@2.0.1:
+ resolution: {integrity: sha512-aJEUyzZ6TzlsX2s5B4Of7lN7EQtAxvtradMMglCQDyaTFgse6CmtmdJ15ElnVRlCg1vpNyVtbem0PWzlNieZsA==}
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ resolution: {integrity: sha512-5HVP2MKaP6L+G6YaxPNjuL0BPrq9orG3TsrZ9YXbA3vDw/ACI4MEsnoDpn6ZNm7GnZgtAcONJyPhOP8tNJQavQ==}
+
+ mdast-util-gfm-footnote@2.0.0:
+ resolution: {integrity: sha512-5jOT2boTSVkMnQ7LTrd6n/18kqwjmuYqo7JUPe+tRCY6O7dAuTFMtTPauYYrMPpox9hlN0uOx/FL8XvEfG9/mQ==}
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ resolution: {integrity: sha512-mKKb915TF+OC5ptj5bJ7WFRPdYtuHv0yTRxK2tJvi+BDqbkiG7h7u/9SI89nRAYcmap2xHQL9D+QG/6wSrTtXg==}
+
+ mdast-util-gfm-table@2.0.0:
+ resolution: {integrity: sha512-78UEvebzz/rJIxLvE7ZtDd/vIQ0RHv+3Mh5DR96p7cS7HsBhYIICDBCu8csTNWNO6tBWfqXPWekRuj2FNOGOZg==}
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ resolution: {integrity: sha512-IrtvNvjxC1o06taBAVJznEnkiHxLFTzgonUdy8hzFVeDun0uTjxxrRGVaNFqkU1wJR3RBPEfsxmU6jDWPofrTQ==}
+
+ mdast-util-gfm@3.0.0:
+ resolution: {integrity: sha512-dgQEX5Amaq+DuUqf26jJqSK9qgixgd6rYDHAv4aTBuA92cTknZlKpPfa86Z/s8Dj8xsAQpFfBmPUHWJBWqS4Bw==}
+
+ mdast-util-mdx-expression@2.0.1:
+ resolution: {integrity: sha512-J6f+9hUp+ldTZqKRSg7Vw5V6MqjATc+3E4gf3CFNcuZNWD8XdyI6zQ8GqH7f8169MM6P7hMBRDVGnn7oHB9kXQ==}
+
+ mdast-util-mdx-jsx@3.1.3:
+ resolution: {integrity: sha512-bfOjvNt+1AcbPLTFMFWY149nJz0OjmewJs3LQQ5pIyVGxP4CdOqNVJL6kTaM5c68p8q82Xv3nCyFfUnuEcH3UQ==}
+
+ mdast-util-mdx@3.0.0:
+ resolution: {integrity: sha512-JfbYLAW7XnYTTbUsmpu0kdBUVe+yKVJZBItEjwyYJiDJuZ9w4eeaqks4HQO+R7objWgS2ymV60GYpI14Ug554w==}
+
+ mdast-util-mdxjs-esm@2.0.1:
+ resolution: {integrity: sha512-EcmOpxsZ96CvlP03NghtH1EsLtr0n9Tm4lPUJUBccV9RwUOneqSycg19n5HGzCf+10LozMRSObtVr3ee1WoHtg==}
+
+ mdast-util-phrasing@4.1.0:
+ resolution: {integrity: sha512-TqICwyvJJpBwvGAMZjj4J2n0X8QWp21b9l0o7eXyVJ25YNWYbJDVIyD1bZXE6WtV6RmKJVYmQAKWa0zWOABz2w==}
+
+ mdast-util-to-hast@13.2.0:
+ resolution: {integrity: sha512-QGYKEuUsYT9ykKBCMOEDLsU5JRObWQusAolFMeko/tYPufNkRffBAQjIE+99jbA87xv6FgmjLtwjh9wBWajwAA==}
+
+ mdast-util-to-markdown@2.1.0:
+ resolution: {integrity: sha512-SR2VnIEdVNCJbP6y7kVTJgPLifdr8WEU440fQec7qHoHOUz/oJ2jmNRqdDQ3rbiStOXb2mCDGTuwsK5OPUgYlQ==}
+
+ mdast-util-to-string@4.0.0:
+ resolution: {integrity: sha512-0H44vDimn51F0YwvxSJSm0eCDOJTRlmN0R1yBh4HLj9wiV1Dn0QoXGbvFAWj2hSItVTlCmBF1hqKlIyUBVFLPg==}
+
+ merge2@1.4.1:
+ resolution: {integrity: sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==}
+ engines: {node: '>= 8'}
+
+ micromark-core-commonmark@2.0.1:
+ resolution: {integrity: sha512-CUQyKr1e///ZODyD1U3xit6zXwy1a8q2a1S1HKtIlmgvurrEpaw/Y9y6KSIbF8P59cn/NjzHyO+Q2fAyYLQrAA==}
+
+ micromark-extension-directive@3.0.1:
+ resolution: {integrity: sha512-VGV2uxUzhEZmaP7NSFo2vtq7M2nUD+WfmYQD+d8i/1nHbzE+rMy9uzTvUybBbNiVbrhOZibg3gbyoARGqgDWyg==}
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ resolution: {integrity: sha512-oOg7knzhicgQ3t4QCjCWgTmfNhvQbDDnJeVu9v81r7NltNCVmhPy1fJRX27pISafdjL+SVc4d3l48Gb6pbRypw==}
+
+ micromark-extension-gfm-footnote@2.1.0:
+ resolution: {integrity: sha512-/yPhxI1ntnDNsiHtzLKYnE3vf9JZ6cAisqVDauhp4CEHxlb4uoOTxOCJ+9s51bIB8U1N1FJ1RXOKTIlD5B/gqw==}
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ resolution: {integrity: sha512-ADVjpOOkjz1hhkZLlBiYA9cR2Anf8F4HqZUO6e5eDcPQd0Txw5fxLzzxnEkSkfnD0wziSGiv7sYhk/ktvbf1uw==}
+
+ micromark-extension-gfm-table@2.1.0:
+ resolution: {integrity: sha512-Ub2ncQv+fwD70/l4ou27b4YzfNaCJOvyX4HxXU15m7mpYY+rjuWzsLIPZHJL253Z643RpbcP1oeIJlQ/SKW67g==}
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ resolution: {integrity: sha512-xHlTOmuCSotIA8TW1mDIM6X2O1SiX5P9IuDtqGonFhEK0qgRI4yeC6vMxEV2dgyr2TiD+2PQ10o+cOhdVAcwfg==}
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ resolution: {integrity: sha512-qIBZhqxqI6fjLDYFTBIa4eivDMnP+OZqsNwmQ3xNLE4Cxwc+zfQEfbs6tzAo2Hjq+bh6q5F+Z8/cksrLFYWQQw==}
+
+ micromark-extension-gfm@3.0.0:
+ resolution: {integrity: sha512-vsKArQsicm7t0z2GugkCKtZehqUm31oeGBV/KVSorWSy8ZlNAv7ytjFhvaryUiCUJYqs+NoE6AFhpQvBTM6Q4w==}
+
+ micromark-extension-mdx-expression@3.0.0:
+ resolution: {integrity: sha512-sI0nwhUDz97xyzqJAbHQhp5TfaxEvZZZ2JDqUo+7NvyIYG6BZ5CPPqj2ogUoPJlmXHBnyZUzISg9+oUmU6tUjQ==}
+
+ micromark-extension-mdx-jsx@3.0.1:
+ resolution: {integrity: sha512-vNuFb9czP8QCtAQcEJn0UJQJZA8Dk6DXKBqx+bg/w0WGuSxDxNr7hErW89tHUY31dUW4NqEOWwmEUNhjTFmHkg==}
+
+ micromark-extension-mdx-md@2.0.0:
+ resolution: {integrity: sha512-EpAiszsB3blw4Rpba7xTOUptcFeBFi+6PY8VnJ2hhimH+vCQDirWgsMpz7w1XcZE7LVrSAUGb9VJpG9ghlYvYQ==}
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ resolution: {integrity: sha512-DJFl4ZqkErRpq/dAPyeWp15tGrcrrJho1hKK5uBS70BCtfrIFg81sqcTVu3Ta+KD1Tk5vAtBNElWxtAa+m8K9A==}
+
+ micromark-extension-mdxjs@3.0.0:
+ resolution: {integrity: sha512-A873fJfhnJ2siZyUrJ31l34Uqwy4xIFmvPY1oj+Ean5PHcPBYzEsvqvWGaWcfEIr11O5Dlw3p2y0tZWpKHDejQ==}
+
+ micromark-factory-destination@2.0.0:
+ resolution: {integrity: sha512-j9DGrQLm/Uhl2tCzcbLhy5kXsgkHUrjJHg4fFAeoMRwJmJerT9aw4FEhIbZStWN8A3qMwOp1uzHr4UL8AInxtA==}
+
+ micromark-factory-label@2.0.0:
+ resolution: {integrity: sha512-RR3i96ohZGde//4WSe/dJsxOX6vxIg9TimLAS3i4EhBAFx8Sm5SmqVfR8E87DPSR31nEAjZfbt91OMZWcNgdZw==}
+
+ micromark-factory-mdx-expression@2.0.2:
+ resolution: {integrity: sha512-5E5I2pFzJyg2CtemqAbcyCktpHXuJbABnsb32wX2U8IQKhhVFBqkcZR5LRm1WVoFqa4kTueZK4abep7wdo9nrw==}
+
+ micromark-factory-space@2.0.0:
+ resolution: {integrity: sha512-TKr+LIDX2pkBJXFLzpyPyljzYK3MtmllMUMODTQJIUfDGncESaqB90db9IAUcz4AZAJFdd8U9zOp9ty1458rxg==}
+
+ micromark-factory-title@2.0.0:
+ resolution: {integrity: sha512-jY8CSxmpWLOxS+t8W+FG3Xigc0RDQA9bKMY/EwILvsesiRniiVMejYTE4wumNc2f4UbAa4WsHqe3J1QS1sli+A==}
+
+ micromark-factory-whitespace@2.0.0:
+ resolution: {integrity: sha512-28kbwaBjc5yAI1XadbdPYHX/eDnqaUFVikLwrO7FDnKG7lpgxnvk/XGRhX/PN0mOZ+dBSZ+LgunHS+6tYQAzhA==}
+
+ micromark-util-character@2.1.0:
+ resolution: {integrity: sha512-KvOVV+X1yLBfs9dCBSopq/+G1PcgT3lAK07mC4BzXi5E7ahzMAF8oIupDDJ6mievI6F+lAATkbQQlQixJfT3aQ==}
+
+ micromark-util-chunked@2.0.0:
+ resolution: {integrity: sha512-anK8SWmNphkXdaKgz5hJvGa7l00qmcaUQoMYsBwDlSKFKjc6gjGXPDw3FNL3Nbwq5L8gE+RCbGqTw49FK5Qyvg==}
+
+ micromark-util-classify-character@2.0.0:
+ resolution: {integrity: sha512-S0ze2R9GH+fu41FA7pbSqNWObo/kzwf8rN/+IGlW/4tC6oACOs8B++bh+i9bVyNnwCcuksbFwsBme5OCKXCwIw==}
+
+ micromark-util-combine-extensions@2.0.0:
+ resolution: {integrity: sha512-vZZio48k7ON0fVS3CUgFatWHoKbbLTK/rT7pzpJ4Bjp5JjkZeasRfrS9wsBdDJK2cJLHMckXZdzPSSr1B8a4oQ==}
+
+ micromark-util-decode-numeric-character-reference@2.0.1:
+ resolution: {integrity: sha512-bmkNc7z8Wn6kgjZmVHOX3SowGmVdhYS7yBpMnuMnPzDq/6xwVA604DuOXMZTO1lvq01g+Adfa0pE2UKGlxL1XQ==}
+
+ micromark-util-decode-string@2.0.0:
+ resolution: {integrity: sha512-r4Sc6leeUTn3P6gk20aFMj2ntPwn6qpDZqWvYmAG6NgvFTIlj4WtrAudLi65qYoaGdXYViXYw2pkmn7QnIFasA==}
+
+ micromark-util-encode@2.0.0:
+ resolution: {integrity: sha512-pS+ROfCXAGLWCOc8egcBvT0kf27GoWMqtdarNfDcjb6YLuV5cM3ioG45Ys2qOVqeqSbjaKg72vU+Wby3eddPsA==}
+
+ micromark-util-events-to-acorn@2.0.2:
+ resolution: {integrity: sha512-Fk+xmBrOv9QZnEDguL9OI9/NQQp6Hz4FuQ4YmCb/5V7+9eAh1s6AYSvL20kHkD67YIg7EpE54TiSlcsf3vyZgA==}
+
+ micromark-util-html-tag-name@2.0.0:
+ resolution: {integrity: sha512-xNn4Pqkj2puRhKdKTm8t1YHC/BAjx6CEwRFXntTaRf/x16aqka6ouVoutm+QdkISTlT7e2zU7U4ZdlDLJd2Mcw==}
+
+ micromark-util-normalize-identifier@2.0.0:
+ resolution: {integrity: sha512-2xhYT0sfo85FMrUPtHcPo2rrp1lwbDEEzpx7jiH2xXJLqBuy4H0GgXk5ToU8IEwoROtXuL8ND0ttVa4rNqYK3w==}
+
+ micromark-util-resolve-all@2.0.0:
+ resolution: {integrity: sha512-6KU6qO7DZ7GJkaCgwBNtplXCvGkJToU86ybBAUdavvgsCiG8lSSvYxr9MhwmQ+udpzywHsl4RpGJsYWG1pDOcA==}
+
+ micromark-util-sanitize-uri@2.0.0:
+ resolution: {integrity: sha512-WhYv5UEcZrbAtlsnPuChHUAsu/iBPOVaEVsntLBIdpibO0ddy8OzavZz3iL2xVvBZOpolujSliP65Kq0/7KIYw==}
+
+ micromark-util-subtokenize@2.0.1:
+ resolution: {integrity: sha512-jZNtiFl/1aY73yS3UGQkutD0UbhTt68qnRpw2Pifmz5wV9h8gOVsN70v+Lq/f1rKaU/W8pxRe8y8Q9FX1AOe1Q==}
+
+ micromark-util-symbol@2.0.0:
+ resolution: {integrity: sha512-8JZt9ElZ5kyTnO94muPxIGS8oyElRJaiJO8EzV6ZSyGQ1Is8xwl4Q45qU5UOg+bGH4AikWziz0iN4sFLWs8PGw==}
+
+ micromark-util-types@2.0.0:
+ resolution: {integrity: sha512-oNh6S2WMHWRZrmutsRmDDfkzKtxF+bc2VxLC9dvtrDIRFln627VsFP6fLMgTryGDljgLPjkrzQSDcPrjPyDJ5w==}
+
+ micromark@4.0.0:
+ resolution: {integrity: sha512-o/sd0nMof8kYff+TqcDx3VSrgBTcZpSvYcAHIfHhv5VAuNmisCxjhx6YmxS8PFEpb9z5WKWKPdzf0jM23ro3RQ==}
+
+ micromatch@4.0.8:
+ resolution: {integrity: sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA==}
+ engines: {node: '>=8.6'}
+
+ mimic-function@5.0.1:
+ resolution: {integrity: sha512-VP79XUPxV2CigYP3jWwAUFSku2aKqBH7uTAapFWCBqutsbmDo96KY5o8uh6U+/YSIn5OxJnXp73beVkpqMIGhA==}
+ engines: {node: '>=18'}
+
+ mimic-response@3.1.0:
+ resolution: {integrity: sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==}
+ engines: {node: '>=10'}
+
+ minimist@1.2.8:
+ resolution: {integrity: sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==}
+
+ mkdirp-classic@0.5.3:
+ resolution: {integrity: sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==}
+
+ mrmime@2.0.0:
+ resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
+ engines: {node: '>=10'}
+
+ ms@2.1.3:
+ resolution: {integrity: sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==}
+
+ muggle-string@0.4.1:
+ resolution: {integrity: sha512-VNTrAak/KhO2i8dqqnqnAHOa3cYBwXEZe9h+D5h/1ZqFSTEFHdM65lR7RoIqq3tBBYavsOXV84NoHXZ0AkPyqQ==}
+
+ nanoid@3.3.7:
+ resolution: {integrity: sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==}
+ engines: {node: ^10 || ^12 || ^13.7 || ^14 || >=15.0.1}
+ hasBin: true
+
+ napi-build-utils@1.0.2:
+ resolution: {integrity: sha512-ONmRUqK7zj7DWX0D9ADe03wbwOBZxNAfF20PlGfCWQcD3+/MakShIHrMqx9YwPTfxDdF1zLeL+RGZiR9kGMLdg==}
+
+ neotraverse@0.6.18:
+ resolution: {integrity: sha512-Z4SmBUweYa09+o6pG+eASabEpP6QkQ70yHj351pQoEXIs8uHbaU2DWVmzBANKgflPa47A50PtB2+NgRpQvr7vA==}
+ engines: {node: '>= 10'}
+
+ nlcst-to-string@4.0.0:
+ resolution: {integrity: sha512-YKLBCcUYKAg0FNlOBT6aI91qFmSiFKiluk655WzPF+DDMA02qIyy8uiRqI8QXtcFpEvll12LpL5MXqEmAZ+dcA==}
+
+ node-abi@3.67.0:
+ resolution: {integrity: sha512-bLn/fU/ALVBE9wj+p4Y21ZJWYFjUXLXPi/IewyLZkx3ApxKDNBWCKdReeKOtD8dWpOdDCeMyLh6ZewzcLsG2Nw==}
+ engines: {node: '>=10'}
+
+ node-addon-api@6.1.0:
+ resolution: {integrity: sha512-+eawOlIgy680F0kBzPUNFhMZGtJ1YmqM6l4+Crf4IkImjYrO/mqPwRMh352g23uIaQKFItcQ64I7KMaJxHgAVA==}
+
+ node-releases@2.0.18:
+ resolution: {integrity: sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==}
+
+ normalize-path@3.0.0:
+ resolution: {integrity: sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==}
+ engines: {node: '>=0.10.0'}
+
+ not@0.1.0:
+ resolution: {integrity: sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==}
+
+ nth-check@2.1.1:
+ resolution: {integrity: sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==}
+
+ once@1.4.0:
+ resolution: {integrity: sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==}
+
+ onetime@7.0.0:
+ resolution: {integrity: sha512-VXJjc87FScF88uafS3JllDgvAm+c/Slfz06lorj2uAY34rlUu0Nt+v8wreiImcrgAjjIHp1rXpTDlLOGw29WwQ==}
+ engines: {node: '>=18'}
+
+ oniguruma-to-js@0.4.3:
+ resolution: {integrity: sha512-X0jWUcAlxORhOqqBREgPMgnshB7ZGYszBNspP+tS9hPD3l13CdaXcHbgImoHUHlrvGx/7AvFEkTRhAGYh+jzjQ==}
+
+ ora@8.1.0:
+ resolution: {integrity: sha512-GQEkNkH/GHOhPFXcqZs3IDahXEQcQxsSjEkK4KvEEST4t7eNzoMjxTzef+EZ+JluDEV+Raoi3WQ2CflnRdSVnQ==}
+ engines: {node: '>=18'}
+
+ p-limit@2.3.0:
+ resolution: {integrity: sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==}
+ engines: {node: '>=6'}
+
+ p-limit@6.1.0:
+ resolution: {integrity: sha512-H0jc0q1vOzlEk0TqAKXKZxdl7kX3OFUzCnNVUnq5Pc3DGo0kpeaMuPqxQn235HibwBEb0/pm9dgKTjXy66fBkg==}
+ engines: {node: '>=18'}
+
+ p-locate@4.1.0:
+ resolution: {integrity: sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==}
+ engines: {node: '>=8'}
+
+ p-queue@8.0.1:
+ resolution: {integrity: sha512-NXzu9aQJTAzbBqOt2hwsR63ea7yvxJc0PwN/zobNAudYfb1B7R08SzB4TsLeSbUCuG467NhnoT0oO6w1qRO+BA==}
+ engines: {node: '>=18'}
+
+ p-timeout@6.1.2:
+ resolution: {integrity: sha512-UbD77BuZ9Bc9aABo74gfXhNvzC9Tx7SxtHSh1fxvx3jTLLYvmVhiQZZrJzqqU0jKbN32kb5VOKiLEQI/3bIjgQ==}
+ engines: {node: '>=14.16'}
+
+ p-try@2.2.0:
+ resolution: {integrity: sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==}
+ engines: {node: '>=6'}
+
+ pagefind@1.1.1:
+ resolution: {integrity: sha512-U2YR0dQN5B2fbIXrLtt/UXNS0yWSSYfePaad1KcBPTi0p+zRtsVjwmoPaMQgTks5DnHNbmDxyJUL5TGaLljK3A==}
+ hasBin: true
+
+ parse-entities@4.0.1:
+ resolution: {integrity: sha512-SWzvYcSJh4d/SGLIOQfZ/CoNv6BTlI6YEQ7Nj82oDVnRpwe/Z/F1EMx42x3JAOwGBlCjeCH0BRJQbQ/opHL17w==}
+
+ parse-latin@7.0.0:
+ resolution: {integrity: sha512-mhHgobPPua5kZ98EF4HWiH167JWBfl4pvAIXXdbaVohtK7a6YBOy56kvhCqduqyo/f3yrHFWmqmiMg/BkBkYYQ==}
+
+ parse5@7.1.2:
+ resolution: {integrity: sha512-Czj1WaSVpaoj0wbhMzLmWD69anp2WH7FXMB9n1Sy8/ZFF9jolSQVMu1Ij5WIyGmcBmhk7EOndpO4mIpihVqAXw==}
+
+ path-browserify@1.0.1:
+ resolution: {integrity: sha512-b7uo2UCUOYZcnF/3ID0lulOJi/bafxa1xPe7ZPsammBSpjSWQkjNxlt635YGS2MiR9GjvuXCtz2emr3jbsz98g==}
+
+ path-exists@4.0.0:
+ resolution: {integrity: sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==}
+ engines: {node: '>=8'}
+
+ pathe@1.1.2:
+ resolution: {integrity: sha512-whLdWMYL2TwI08hn8/ZqAbrVemu0LNaNNJZX73O6qaIdCTfXutsLhMkjdENX0qhsQ9uIimo4/aQOmXkoon2nDQ==}
+
+ periscopic@3.1.0:
+ resolution: {integrity: sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==}
+
+ picocolors@1.1.0:
+ resolution: {integrity: sha512-TQ92mBOW0l3LeMeyLV6mzy/kWr8lkd/hp3mTg7wYK7zJhuBStmGMBG0BdeDZS/dZx1IukaX6Bk11zcln25o1Aw==}
+
+ picomatch@2.3.1:
+ resolution: {integrity: sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==}
+ engines: {node: '>=8.6'}
+
+ pify@4.0.1:
+ resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==}
+ engines: {node: '>=6'}
+
+ pkg-dir@4.2.0:
+ resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==}
+ engines: {node: '>=8'}
+
+ postcss-nested@6.2.0:
+ resolution: {integrity: sha512-HQbt28KulC5AJzG+cZtj9kvKB93CFCdLvog1WFLf1D+xmMvPGlBstkpTEZfK5+AN9hfJocyBFCNiqyS48bpgzQ==}
+ engines: {node: '>=12.0'}
+ peerDependencies:
+ postcss: ^8.2.14
+
+ postcss-selector-parser@6.1.2:
+ resolution: {integrity: sha512-Q8qQfPiZ+THO/3ZrOrO0cJJKfpYCagtMUkXbnEfmgUjwXg6z/WBeOyS9APBBPCTSiDV+s4SwQGu8yFsiMRIudg==}
+ engines: {node: '>=4'}
+
+ postcss@8.4.45:
+ resolution: {integrity: sha512-7KTLTdzdZZYscUc65XmjFiB73vBhBfbPztCYdUNvlaso9PrzjzcmjqBPR0lNGkcVlcO4BjiO5rK/qNz+XAen1Q==}
+ engines: {node: ^10 || ^12 || >=14}
+
+ prebuild-install@7.1.2:
+ resolution: {integrity: sha512-UnNke3IQb6sgarcZIDU3gbMeTp/9SSU1DAIkil7PrqG1vZlBtY5msYccSKSHDqa3hNg436IXK+SNImReuA1wEQ==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ preferred-pm@4.0.0:
+ resolution: {integrity: sha512-gYBeFTZLu055D8Vv3cSPox/0iTPtkzxpLroSYYA7WXgRi31WCJ51Uyl8ZiPeUUjyvs2MBzK+S8v9JVUgHU/Sqw==}
+ engines: {node: '>=18.12'}
+
+ prettier@2.8.7:
+ resolution: {integrity: sha512-yPngTo3aXUUmyuTjeTUT75txrf+aMh9FiD7q9ZE/i6r0bPb22g4FsE6Y338PQX1bmfy08i9QQCB7/rcUAVntfw==}
+ engines: {node: '>=10.13.0'}
+ hasBin: true
+
+ prismjs@1.29.0:
+ resolution: {integrity: sha512-Kx/1w86q/epKcmte75LNrEoT+lX8pBpavuAbvJWRXar7Hz8jrtF+e3vY751p0R8H9HdArwaCTNDDzHg/ScJK1Q==}
+ engines: {node: '>=6'}
+
+ prompts@2.4.2:
+ resolution: {integrity: sha512-NxNv/kLguCA7p3jE8oL2aEBsrJWgAakBpgmgK6lpPWV+WuOmY6r2/zbAVnP+T8bQlA0nzHXSJSJW0Hq7ylaD2Q==}
+ engines: {node: '>= 6'}
+
+ property-information@6.5.0:
+ resolution: {integrity: sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==}
+
+ pump@3.0.2:
+ resolution: {integrity: sha512-tUPXtzlGM8FE3P0ZL6DVs/3P58k9nk8/jZeQCurTJylQA8qFYzHFfhBJkuqyE0FifOsQ0uKWekiZ5g8wtr28cw==}
+
+ queue-microtask@1.2.3:
+ resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==}
+
+ queue-tick@1.0.1:
+ resolution: {integrity: sha512-kJt5qhMxoszgU/62PLP1CJytzd2NKetjSRnyuj31fDd3Rlcz3fzlFdFLD1SItunPwyqEOkca6GbV612BWfaBag==}
+
+ rc@1.2.8:
+ resolution: {integrity: sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==}
+ hasBin: true
+
+ readable-stream@3.6.2:
+ resolution: {integrity: sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==}
+ engines: {node: '>= 6'}
+
+ readdirp@3.6.0:
+ resolution: {integrity: sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA==}
+ engines: {node: '>=8.10.0'}
+
+ recast@0.23.9:
+ resolution: {integrity: sha512-Hx/BGIbwj+Des3+xy5uAtAbdCyqK9y9wbBcDFDYanLS9JnMqf7OeF87HQwUimE87OEc72mr6tkKUKMBBL+hF9Q==}
+ engines: {node: '>= 4'}
+
+ regex@4.3.2:
+ resolution: {integrity: sha512-kK/AA3A9K6q2js89+VMymcboLOlF5lZRCYJv3gzszXFHBr6kO6qLGzbm+UIugBEV8SMMKCTR59txoY6ctRHYVw==}
+
+ rehype-expressive-code@0.35.6:
+ resolution: {integrity: sha512-pPdE+pRcRw01kxMOwHQjuRxgwlblZt5+wAc3w2aPGgmcnn57wYjn07iKO7zaznDxYVxMYVvYlnL+R3vWFQS4Gw==}
+
+ rehype-format@5.0.0:
+ resolution: {integrity: sha512-kM4II8krCHmUhxrlvzFSptvaWh280Fr7UGNJU5DCMuvmAwGCNmGfi9CvFAQK6JDjsNoRMWQStglK3zKJH685Wg==}
+
+ rehype-minify-whitespace@6.0.0:
+ resolution: {integrity: sha512-i9It4YHR0Sf3GsnlR5jFUKXRr9oayvEk9GKQUkwZv6hs70OH9q3OCZrq9PpLvIGKt3W+JxBOxCidNVpH/6rWdA==}
+
+ rehype-parse@9.0.0:
+ resolution: {integrity: sha512-WG7nfvmWWkCR++KEkZevZb/uw41E8TsH4DsY9UxsTbIXCVGbAs4S+r8FrQ+OtH5EEQAs+5UxKC42VinkmpA1Yw==}
+
+ rehype-raw@7.0.0:
+ resolution: {integrity: sha512-/aE8hCfKlQeA8LmyeyQvQF3eBiLRGNlfBJEvWH7ivp9sBqs7TNqBL5X3v157rM4IFETqDnIOO+z5M/biZbo9Ww==}
+
+ rehype-stringify@10.0.0:
+ resolution: {integrity: sha512-1TX1i048LooI9QoecrXy7nGFFbFSufxVRAfc6Y9YMRAi56l+oB0zP51mLSV312uRuvVLPV1opSlJmslozR1XHQ==}
+
+ rehype@13.0.1:
+ resolution: {integrity: sha512-AcSLS2mItY+0fYu9xKxOu1LhUZeBZZBx8//5HKzF+0XP+eP8+6a5MXn2+DW2kfXR6Dtp1FEXMVrjyKAcvcU8vg==}
+
+ remark-directive@3.0.0:
+ resolution: {integrity: sha512-l1UyWJ6Eg1VPU7Hm/9tt0zKtReJQNOA4+iDMAxTyZNWnJnFlbS/7zhiel/rogTLQ2vMYwDzSJa4BiVNqGlqIMA==}
+
+ remark-gfm@4.0.0:
+ resolution: {integrity: sha512-U92vJgBPkbw4Zfu/IiW2oTZLSL3Zpv+uI7My2eq8JxKgqraFdU8YUGicEJCEgSbeaG+QDFqIcwwfMTOEelPxuA==}
+
+ remark-mdx@3.0.1:
+ resolution: {integrity: sha512-3Pz3yPQ5Rht2pM5R+0J2MrGoBSrzf+tJG94N+t/ilfdh8YLyyKYtidAYwTveB20BoHAcwIopOUqhcmh2F7hGYA==}
+
+ remark-parse@11.0.0:
+ resolution: {integrity: sha512-FCxlKLNGknS5ba/1lmpYijMUzX2esxW5xQqjWxw2eHFfS2MSdaHVINFmhjo+qN1WhZhNimq0dZATN9pH0IDrpA==}
+
+ remark-rehype@11.1.0:
+ resolution: {integrity: sha512-z3tJrAs2kIs1AqIIy6pzHmAHlF1hWQ+OdY4/hv+Wxe35EhyLKcajL33iUEn3ScxtFox9nUvRufR/Zre8Q08H/g==}
+
+ remark-smartypants@3.0.2:
+ resolution: {integrity: sha512-ILTWeOriIluwEvPjv67v7Blgrcx+LZOkAUVtKI3putuhlZm84FnqDORNXPPm+HY3NdZOMhyDwZ1E+eZB/Df5dA==}
+ engines: {node: '>=16.0.0'}
+
+ remark-stringify@11.0.0:
+ resolution: {integrity: sha512-1OSmLd3awB/t8qdoEOMazZkNsfVTeY4fTsgzcQFdXNq8ToTN4ZGwrMnlda4K6smTFKD+GRV6O48i6Z4iKgPPpw==}
+
+ request-light@0.5.8:
+ resolution: {integrity: sha512-3Zjgh+8b5fhRJBQZoy+zbVKpAQGLyka0MPgW3zruTF4dFFJ8Fqcfu9YsAvi/rvdcaTeWG3MkbZv4WKxAn/84Lg==}
+
+ request-light@0.7.0:
+ resolution: {integrity: sha512-lMbBMrDoxgsyO+yB3sDcrDuX85yYt7sS8BfQd11jtbW/z5ZWgLZRcEGLsLoYw7I0WSUGQBs8CC8ScIxkTX1+6Q==}
+
+ require-directory@2.1.1:
+ resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==}
+ engines: {node: '>=0.10.0'}
+
+ require-from-string@2.0.2:
+ resolution: {integrity: sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==}
+ engines: {node: '>=0.10.0'}
+
+ restore-cursor@5.1.0:
+ resolution: {integrity: sha512-oMA2dcrw6u0YfxJQXm342bFKX/E4sG9rbTzO9ptUcR/e8A33cHuvStiYOwH7fszkZlZ1z/ta9AAoPk2F4qIOHA==}
+ engines: {node: '>=18'}
+
+ retext-latin@4.0.0:
+ resolution: {integrity: sha512-hv9woG7Fy0M9IlRQloq/N6atV82NxLGveq+3H2WOi79dtIYWN8OaxogDm77f8YnVXJL2VD3bbqowu5E3EMhBYA==}
+
+ retext-smartypants@6.1.1:
+ resolution: {integrity: sha512-onsHf34i/GzgElJgtT1K2V+31yEhWs7NJboKNxXJcmVMMPxLpgxZ9iADoMdydd6j/bHic5F/aNq0CGqElEtu2g==}
+
+ retext-stringify@4.0.0:
+ resolution: {integrity: sha512-rtfN/0o8kL1e+78+uxPTqu1Klt0yPzKuQ2BfWwwfgIUSayyzxpM1PJzkKt4V8803uB9qSy32MvI7Xep9khTpiA==}
+
+ retext@9.0.0:
+ resolution: {integrity: sha512-sbMDcpHCNjvlheSgMfEcVrZko3cDzdbe1x/e7G66dFp0Ff7Mldvi2uv6JkJQzdRcvLYE8CA8Oe8siQx8ZOgTcA==}
+
+ reusify@1.0.4:
+ resolution: {integrity: sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==}
+ engines: {iojs: '>=1.0.0', node: '>=0.10.0'}
+
+ rollup@4.21.3:
+ resolution: {integrity: sha512-7sqRtBNnEbcBtMeRVc6VRsJMmpI+JU1z9VTvW8D4gXIYQFz0aLcsE6rRkyghZkLfEgUZgVvOG7A5CVz/VW5GIA==}
+ engines: {node: '>=18.0.0', npm: '>=8.0.0'}
+ hasBin: true
+
+ run-parallel@1.2.0:
+ resolution: {integrity: sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==}
+
+ safe-buffer@5.2.1:
+ resolution: {integrity: sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==}
+
+ sax@1.4.1:
+ resolution: {integrity: sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==}
+
+ section-matter@1.0.0:
+ resolution: {integrity: sha512-vfD3pmTzGpufjScBh50YHKzEu2lxBWhVEHsNGoEXmCmn2hKGfeNLYMzCJpe8cD7gqX7TJluOVpBkAequ6dgMmA==}
+ engines: {node: '>=4'}
+
+ semver@6.3.1:
+ resolution: {integrity: sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==}
+ hasBin: true
+
+ semver@7.6.3:
+ resolution: {integrity: sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==}
+ engines: {node: '>=10'}
+ hasBin: true
+
+ sharp@0.32.6:
+ resolution: {integrity: sha512-KyLTWwgcR9Oe4d9HwCwNM2l7+J0dUQwn/yf7S0EnTtb0eVS4RxO0eUSvxPtzT4F3SY+C4K6fqdv/DO27sJ/v/w==}
+ engines: {node: '>=14.15.0'}
+
+ sharp@0.33.5:
+ resolution: {integrity: sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==}
+ engines: {node: ^18.17.0 || ^20.3.0 || >=21.0.0}
+
+ shiki@1.17.6:
+ resolution: {integrity: sha512-RejGugKpDM75vh6YtF9R771acxHRDikC/01kxsUGW+Pnaz3pTY+c8aZB5CnD7p0vuFPs1HaoAIU/4E+NCfS+mQ==}
+
+ signal-exit@4.1.0:
+ resolution: {integrity: sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==}
+ engines: {node: '>=14'}
+
+ simple-concat@1.0.1:
+ resolution: {integrity: sha512-cSFtAPtRhljv69IK0hTVZQ+OfE9nePi/rtJmw5UjHeVyVroEqJXP1sFztKUy1qU+xvz3u/sfYJLa947b7nAN2Q==}
+
+ simple-get@4.0.1:
+ resolution: {integrity: sha512-brv7p5WgH0jmQJr1ZDDfKDOSeWWg+OVypG99A/5vYGPqJ6pxiaHLy8nxtFjBA7oMa01ebA9gfh1uMCFqOuXxvA==}
+
+ simple-swizzle@0.2.2:
+ resolution: {integrity: sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==}
+
+ sisteransi@1.0.5:
+ resolution: {integrity: sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==}
+
+ sitemap@7.1.2:
+ resolution: {integrity: sha512-ARCqzHJ0p4gWt+j7NlU5eDlIO9+Rkr/JhPFZKKQ1l5GCus7rJH4UdrlVAh0xC/gDS/Qir2UMxqYNHtsKr2rpCw==}
+ engines: {node: '>=12.0.0', npm: '>=5.6.0'}
+ hasBin: true
+
+ source-map-js@1.2.1:
+ resolution: {integrity: sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.6.1:
+ resolution: {integrity: sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==}
+ engines: {node: '>=0.10.0'}
+
+ source-map@0.7.4:
+ resolution: {integrity: sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==}
+ engines: {node: '>= 8'}
+
+ space-separated-tokens@2.0.2:
+ resolution: {integrity: sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==}
+
+ sprintf-js@1.0.3:
+ resolution: {integrity: sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==}
+
+ stdin-discarder@0.2.2:
+ resolution: {integrity: sha512-UhDfHmA92YAlNnCfhmq0VeNL5bDbiZGg7sZ2IvPsXubGkiNa9EC+tUTsjBRsYUAz87btI6/1wf4XoVvQ3uRnmQ==}
+ engines: {node: '>=18'}
+
+ stream-replace-string@2.0.0:
+ resolution: {integrity: sha512-TlnjJ1C0QrmxRNrON00JvaFFlNh5TTG00APw23j74ET7gkQpTASi6/L2fuiav8pzK715HXtUeClpBTw2NPSn6w==}
+
+ streamx@2.20.1:
+ resolution: {integrity: sha512-uTa0mU6WUC65iUvzKH4X9hEdvSW7rbPxPtwfWiLMSj3qTdQbAiUboZTxauKfpFuGIGa1C2BYijZ7wgdUXICJhA==}
+
+ string-width@4.2.3:
+ resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==}
+ engines: {node: '>=8'}
+
+ string-width@5.1.2:
+ resolution: {integrity: sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==}
+ engines: {node: '>=12'}
+
+ string-width@7.2.0:
+ resolution: {integrity: sha512-tsaTIkKW9b4N+AEj+SVA+WhJzV7/zMhcSu78mLKWSk7cXMOSHsBKFWUs0fWwq8QyK3MgJBQRX6Gbi4kYbdvGkQ==}
+ engines: {node: '>=18'}
+
+ string_decoder@1.3.0:
+ resolution: {integrity: sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA==}
+
+ stringify-entities@4.0.4:
+ resolution: {integrity: sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==}
+
+ strip-ansi@6.0.1:
+ resolution: {integrity: sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==}
+ engines: {node: '>=8'}
+
+ strip-ansi@7.1.0:
+ resolution: {integrity: sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==}
+ engines: {node: '>=12'}
+
+ strip-bom-string@1.0.0:
+ resolution: {integrity: sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g==}
+ engines: {node: '>=0.10.0'}
+
+ strip-bom@3.0.0:
+ resolution: {integrity: sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==}
+ engines: {node: '>=4'}
+
+ strip-json-comments@2.0.1:
+ resolution: {integrity: sha512-4gB8na07fecVVkOI6Rs4e7T6NOTki5EmL7TUduTs6bu3EdnSycntVJ4re8kgZA+wx9IueI2Y11bfbgwtzuE0KQ==}
+ engines: {node: '>=0.10.0'}
+
+ style-to-object@0.4.4:
+ resolution: {integrity: sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==}
+
+ style-to-object@1.0.8:
+ resolution: {integrity: sha512-xT47I/Eo0rwJmaXC4oilDGDWLohVhR6o/xAQcPQN8q6QBuZVL8qMYL85kLmST5cPjAorwvqIA4qXTRQoYHaL6g==}
+
+ supports-color@5.5.0:
+ resolution: {integrity: sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==}
+ engines: {node: '>=4'}
+
+ tar-fs@2.1.1:
+ resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==}
+
+ tar-fs@3.0.6:
+ resolution: {integrity: sha512-iokBDQQkUyeXhgPYaZxmczGPhnhXZ0CmrqI+MOb/WFGS9DW5wnfrLgtjUJBvz50vQ3qfRwJ62QVoCFu8mPVu5w==}
+
+ tar-stream@2.2.0:
+ resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==}
+ engines: {node: '>=6'}
+
+ tar-stream@3.1.7:
+ resolution: {integrity: sha512-qJj60CXt7IU1Ffyc3NJMjh6EkuCFej46zUqJ4J7pqYlThyd9bO0XBTmcOIhSzZJVWfsLks0+nle/j538YAW9RQ==}
+
+ text-decoder@1.2.0:
+ resolution: {integrity: sha512-n1yg1mOj9DNpk3NeZOx7T6jchTbyJS3i3cucbNN6FcdPriMZx7NsgrGpWWdWZZGxD7ES1XB+3uoqHMgOKaN+fg==}
+
+ tiny-invariant@1.3.3:
+ resolution: {integrity: sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg==}
+
+ tinyexec@0.3.0:
+ resolution: {integrity: sha512-tVGE0mVJPGb0chKhqmsoosjsS+qUnJVGJpZgsHYQcGoPlG3B51R3PouqTgEGH2Dc9jjFyOqOpix6ZHNMXp1FZg==}
+
+ to-fast-properties@2.0.0:
+ resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==}
+ engines: {node: '>=4'}
+
+ to-regex-range@5.0.1:
+ resolution: {integrity: sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==}
+ engines: {node: '>=8.0'}
+
+ trim-lines@3.0.1:
+ resolution: {integrity: sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==}
+
+ trough@2.2.0:
+ resolution: {integrity: sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==}
+
+ tsconfck@3.1.3:
+ resolution: {integrity: sha512-ulNZP1SVpRDesxeMLON/LtWM8HIgAJEIVpVVhBM6gsmvQ8+Rh+ZG7FWGvHh7Ah3pRABwVJWklWCr/BTZSv0xnQ==}
+ engines: {node: ^18 || >=20}
+ hasBin: true
+ peerDependencies:
+ typescript: ^5.0.0
+ peerDependenciesMeta:
+ typescript:
+ optional: true
+
+ tslib@2.7.0:
+ resolution: {integrity: sha512-gLXCKdN1/j47AiHiOkJN69hJmcbGTHI0ImLmbYLHykhgeN0jVGola9yVjFgzCUklsZQMW55o+dW7IXv3RCXDzA==}
+
+ tunnel-agent@0.6.0:
+ resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==}
+
+ type-fest@2.19.0:
+ resolution: {integrity: sha512-RAH822pAdBgcNMAfWnCBU3CFZcfZ/i1eZjwFU/dsLKumyuuP3niueg2UAukXYF0E2AAoc82ZSSf9J0WQBinzHA==}
+ engines: {node: '>=12.20'}
+
+ typesafe-path@0.2.2:
+ resolution: {integrity: sha512-OJabfkAg1WLZSqJAJ0Z6Sdt3utnbzr/jh+NAHoyWHJe8CMSy79Gm085094M9nvTPy22KzTVn5Zq5mbapCI/hPA==}
+
+ typescript-auto-import-cache@0.3.3:
+ resolution: {integrity: sha512-ojEC7+Ci1ij9eE6hp8Jl9VUNnsEKzztktP5gtYNRMrTmfXVwA1PITYYAkpxCvvupdSYa/Re51B6KMcv1CTZEUA==}
+
+ typescript@5.6.2:
+ resolution: {integrity: sha512-NW8ByodCSNCwZeghjN3o+JX5OFH0Ojg6sadjEKY4huZ52TqbJTJnDo5+Tw98lSy63NZvi4n+ez5m2u5d4PkZyw==}
+ engines: {node: '>=14.17'}
+ hasBin: true
+
+ unified@11.0.5:
+ resolution: {integrity: sha512-xKvGhPWw3k84Qjh8bI3ZeJjqnyadK+GEFtazSfZv/rKeTkTjOJho6mFqh2SM96iIcZokxiOpg78GazTSg8+KHA==}
+
+ unist-util-find-after@5.0.0:
+ resolution: {integrity: sha512-amQa0Ep2m6hE2g72AugUItjbuM8X8cGQnFoHk0pGfrFeT9GZhzN5SW8nRsiGKK7Aif4CrACPENkA6P/Lw6fHGQ==}
+
+ unist-util-is@6.0.0:
+ resolution: {integrity: sha512-2qCTHimwdxLfz+YzdGfkqNlH0tLi9xjTnHddPmJwtIG9MGsdbutfTc4P+haPD7l7Cjxf/WZj+we5qfVPvvxfYw==}
+
+ unist-util-modify-children@4.0.0:
+ resolution: {integrity: sha512-+tdN5fGNddvsQdIzUF3Xx82CU9sMM+fA0dLgR9vOmT0oPT2jH+P1nd5lSqfCfXAw+93NhcXNY2qqvTUtE4cQkw==}
+
+ unist-util-position-from-estree@2.0.0:
+ resolution: {integrity: sha512-KaFVRjoqLyF6YXCbVLNad/eS4+OfPQQn2yOd7zF/h5T/CSL2v8NpN6a5TPvtbXthAGw5nG+PuTtq+DdIZr+cRQ==}
+
+ unist-util-position@5.0.0:
+ resolution: {integrity: sha512-fucsC7HjXvkB5R3kTCO7kUjRdrS0BJt3M/FPxmHMBOm8JQi2BsHAHFsy27E0EolP8rp0NzXsJ+jNPyDWvOJZPA==}
+
+ unist-util-remove-position@5.0.0:
+ resolution: {integrity: sha512-Hp5Kh3wLxv0PHj9m2yZhhLt58KzPtEYKQQ4yxfYFEO7EvHwzyDYnduhHnY1mDxoqr7VUwVuHXk9RXKIiYS1N8Q==}
+
+ unist-util-stringify-position@4.0.0:
+ resolution: {integrity: sha512-0ASV06AAoKCDkS2+xw5RXJywruurpbC4JZSm7nr7MOt1ojAzvyyaO+UxZf18j8FCF6kmzCZKcAgN/yu2gm2XgQ==}
+
+ unist-util-visit-children@3.0.0:
+ resolution: {integrity: sha512-RgmdTfSBOg04sdPcpTSD1jzoNBjt9a80/ZCzp5cI9n1qPzLZWF9YdvWGN2zmTumP1HWhXKdUWexjy/Wy/lJ7tA==}
+
+ unist-util-visit-parents@6.0.1:
+ resolution: {integrity: sha512-L/PqWzfTP9lzzEa6CKs0k2nARxTdZduw3zyh8d2NVBnsyvHjSX4TWse388YrrQKbvI8w20fGjGlhgT96WwKykw==}
+
+ unist-util-visit@5.0.0:
+ resolution: {integrity: sha512-MR04uvD+07cwl/yhVuVWAtw+3GOR/knlL55Nd/wAdblk27GCVt3lqpTivy/tkJcZoNPzTwS1Y+KMojlLDhoTzg==}
+
+ update-browserslist-db@1.1.0:
+ resolution: {integrity: sha512-EdRAaAyk2cUE1wOf2DkEhzxqOQvFOoRJFNS6NeyJ01Gp2beMRpBAINjM2iDXE3KCuKhwnvHIQCJm6ThL2Z+HzQ==}
+ hasBin: true
+ peerDependencies:
+ browserslist: '>= 4.21.0'
+
+ util-deprecate@1.0.2:
+ resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==}
+
+ vfile-location@5.0.3:
+ resolution: {integrity: sha512-5yXvWDEgqeiYiBe1lbxYF7UMAIm/IcopxMHrMQDq3nvKcjPKIhZklUKL+AE7J7uApI4kwe2snsK+eI6UTj9EHg==}
+
+ vfile-message@4.0.2:
+ resolution: {integrity: sha512-jRDZ1IMLttGj41KcZvlrYAaI3CfqpLpfpf+Mfig13viT6NKvRzWZ+lXz0Y5D60w6uJIBAOGq9mSHf0gktF0duw==}
+
+ vfile@6.0.3:
+ resolution: {integrity: sha512-KzIbH/9tXat2u30jf+smMwFCsno4wHVdNmzFyL+T/L3UGqqk6JKfVqOFOZEpZSHADH1k40ab6NUIXZq422ov3Q==}
+
+ vite@5.4.5:
+ resolution: {integrity: sha512-pXqR0qtb2bTwLkev4SE3r4abCNioP3GkjvIDLlzziPpXtHgiJIjuKl+1GN6ESOT3wMjG3JTeARopj2SwYaHTOA==}
+ engines: {node: ^18.0.0 || >=20.0.0}
+ hasBin: true
+ peerDependencies:
+ '@types/node': ^18.0.0 || >=20.0.0
+ less: '*'
+ lightningcss: ^1.21.0
+ sass: '*'
+ sass-embedded: '*'
+ stylus: '*'
+ sugarss: '*'
+ terser: ^5.4.0
+ peerDependenciesMeta:
+ '@types/node':
+ optional: true
+ less:
+ optional: true
+ lightningcss:
+ optional: true
+ sass:
+ optional: true
+ sass-embedded:
+ optional: true
+ stylus:
+ optional: true
+ sugarss:
+ optional: true
+ terser:
+ optional: true
+
+ vitefu@1.0.2:
+ resolution: {integrity: sha512-0/iAvbXyM3RiPPJ4lyD4w6Mjgtf4ejTK6TPvTNG3H32PLwuT0N/ZjJLiXug7ETE/LWtTeHw9WRv7uX/tIKYyKg==}
+ peerDependencies:
+ vite: ^3.0.0 || ^4.0.0 || ^5.0.0
+ peerDependenciesMeta:
+ vite:
+ optional: true
+
+ volar-service-css@0.0.61:
+ resolution: {integrity: sha512-Ct9L/w+IB1JU8F4jofcNCGoHy6TF83aiapfZq9A0qYYpq+Kk5dH+ONS+rVZSsuhsunq8UvAuF8Gk6B8IFLfniw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-emmet@0.0.61:
+ resolution: {integrity: sha512-iiYqBxjjcekqrRruw4COQHZME6EZYWVbkHjHDbULpml3g8HGJHzpAMkj9tXNCPxf36A+f1oUYjsvZt36qPg4cg==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-html@0.0.61:
+ resolution: {integrity: sha512-yFE+YmmgqIL5HI4ORqP++IYb1QaGcv+xBboI0WkCxJJ/M35HZj7f5rbT3eQ24ECLXFbFCFanckwyWJVz5KmN3Q==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-prettier@0.0.61:
+ resolution: {integrity: sha512-F612nql5I0IS8HxXemCGvOR2Uxd4XooIwqYVUvk7WSBxP/+xu1jYvE3QJ7EVpl8Ty3S4SxPXYiYTsG3bi+gzIQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ prettier: ^2.2 || ^3.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+ prettier:
+ optional: true
+
+ volar-service-typescript-twoslash-queries@0.0.61:
+ resolution: {integrity: sha512-99FICGrEF0r1E2tV+SvprHPw9Knyg7BdW2fUch0tf59kG+KG+Tj4tL6tUg+cy8f23O/VXlmsWFMIE+bx1dXPnQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-typescript@0.0.61:
+ resolution: {integrity: sha512-4kRHxVbW7wFBHZWRU6yWxTgiKETBDIJNwmJUAWeP0mHaKpnDGj/astdRFKqGFRYVeEYl45lcUPhdJyrzanjsdQ==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ volar-service-yaml@0.0.61:
+ resolution: {integrity: sha512-L+gbDiLDQQ1rZUbJ3mf3doDsoQUa8OZM/xdpk/unMg1Vz24Zmi2Ign8GrZyBD7bRoIQDwOH9gdktGDKzRPpUNw==}
+ peerDependencies:
+ '@volar/language-service': ~2.4.0
+ peerDependenciesMeta:
+ '@volar/language-service':
+ optional: true
+
+ vscode-css-languageservice@6.3.1:
+ resolution: {integrity: sha512-1BzTBuJfwMc3A0uX4JBdJgoxp74cjj4q2mDJdp49yD/GuAq4X0k5WtK6fNcMYr+FfJ9nqgR6lpfCSZDkARJ5qQ==}
+
+ vscode-html-languageservice@5.3.1:
+ resolution: {integrity: sha512-ysUh4hFeW/WOWz/TO9gm08xigiSsV/FOAZ+DolgJfeLftna54YdmZ4A+lIn46RbdO3/Qv5QHTn1ZGqmrXQhZyA==}
+
+ vscode-json-languageservice@4.1.8:
+ resolution: {integrity: sha512-0vSpg6Xd9hfV+eZAaYN63xVVMOTmJ4GgHxXnkLCh+9RsQBkWKIghzLhW2B9ebfG+LQQg8uLtsQ2aUKjTgE+QOg==}
+ engines: {npm: '>=7.0.0'}
+
+ vscode-jsonrpc@6.0.0:
+ resolution: {integrity: sha512-wnJA4BnEjOSyFMvjZdpiOwhSq9uDoK8e/kpRJDTaMYzwlkrhG1fwDIZI94CLsLzlCK5cIbMMtFlJlfR57Lavmg==}
+ engines: {node: '>=8.0.0 || >=10.0.0'}
+
+ vscode-jsonrpc@8.2.0:
+ resolution: {integrity: sha512-C+r0eKJUIfiDIfwJhria30+TYWPtuHJXHtI7J0YlOmKAo7ogxP20T0zxB7HZQIFhIyvoBPwWskjxrvAtfjyZfA==}
+ engines: {node: '>=14.0.0'}
+
+ vscode-languageserver-protocol@3.16.0:
+ resolution: {integrity: sha512-sdeUoAawceQdgIfTI+sdcwkiK2KU+2cbEYA0agzM2uqaUy2UpnnGHtWTHVEtS0ES4zHU0eMFRGN+oQgDxlD66A==}
+
+ vscode-languageserver-protocol@3.17.5:
+ resolution: {integrity: sha512-mb1bvRJN8SVznADSGWM9u/b07H7Ecg0I3OgXDuLdn307rl/J3A9YD6/eYOssqhecL27hK1IPZAsaqh00i/Jljg==}
+
+ vscode-languageserver-textdocument@1.0.12:
+ resolution: {integrity: sha512-cxWNPesCnQCcMPeenjKKsOCKQZ/L6Tv19DTRIGuLWe32lyzWhihGVJ/rcckZXJxfdKCFvRLS3fpBIsV/ZGX4zA==}
+
+ vscode-languageserver-types@3.16.0:
+ resolution: {integrity: sha512-k8luDIWJWyenLc5ToFQQMaSrqCHiLwyKPHKPQZ5zz21vM+vIVUSvsRpcbiECH4WR88K2XZqc4ScRcZ7nk/jbeA==}
+
+ vscode-languageserver-types@3.17.5:
+ resolution: {integrity: sha512-Ld1VelNuX9pdF39h2Hgaeb5hEZM2Z3jUrrMgWQAu82jMtZp7p3vJT3BzToKtZI7NgQssZje5o0zryOrhQvzQAg==}
+
+ vscode-languageserver@7.0.0:
+ resolution: {integrity: sha512-60HTx5ID+fLRcgdHfmz0LDZAXYEV68fzwG0JWwEPBode9NuMYTIxuYXPg4ngO8i8+Ou0lM7y6GzaYWbiDL0drw==}
+ hasBin: true
+
+ vscode-languageserver@9.0.1:
+ resolution: {integrity: sha512-woByF3PDpkHFUreUa7Hos7+pUWdeWMXRd26+ZX2A8cFx6v/JPTtd4/uN0/jB6XQHYaOlHbio03NTHCqrgG5n7g==}
+ hasBin: true
+
+ vscode-nls@5.2.0:
+ resolution: {integrity: sha512-RAaHx7B14ZU04EU31pT+rKz2/zSl7xMsfIZuo8pd+KZO6PXtQmpevpq3vxvWNcrGbdmhM/rr5Uw5Mz+NBfhVng==}
+
+ vscode-uri@2.1.2:
+ resolution: {integrity: sha512-8TEXQxlldWAuIODdukIb+TR5s+9Ds40eSJrw+1iDDA9IFORPjMELarNQE3myz5XIkWWpdprmJjm1/SxMlWOC8A==}
+
+ vscode-uri@3.0.8:
+ resolution: {integrity: sha512-AyFQ0EVmsOZOlAnxoFOGOq1SQDWAB7C6aqMGS23svWAllfOaxbuFvcT8D1i8z3Gyn8fraVeZNNmN6e9bxxXkKw==}
+
+ web-namespaces@2.0.1:
+ resolution: {integrity: sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==}
+
+ which-pm-runs@1.1.0:
+ resolution: {integrity: sha512-n1brCuqClxfFfq/Rb0ICg9giSZqCS+pLtccdag6C2HyufBrh3fBOiy9nb6ggRMvWOVH5GrdJskj5iGTZNxd7SA==}
+ engines: {node: '>=4'}
+
+ which-pm@3.0.0:
+ resolution: {integrity: sha512-ysVYmw6+ZBhx3+ZkcPwRuJi38ZOTLJJ33PSHaitLxSKUMsh0LkKd0nC69zZCwt5D+AYUcMK2hhw4yWny20vSGg==}
+ engines: {node: '>=18.12'}
+
+ widest-line@4.0.1:
+ resolution: {integrity: sha512-o0cyEG0e8GPzT4iGHphIOh0cJOV8fivsXxddQasHPHfoZf1ZexrfeA21w2NaEN1RHE+fXlfISmOE8R9N3u3Qig==}
+ engines: {node: '>=12'}
+
+ wrap-ansi@7.0.0:
+ resolution: {integrity: sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==}
+ engines: {node: '>=10'}
+
+ wrap-ansi@8.1.0:
+ resolution: {integrity: sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==}
+ engines: {node: '>=12'}
+
+ wrappy@1.0.2:
+ resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==}
+
+ xxhash-wasm@1.0.2:
+ resolution: {integrity: sha512-ibF0Or+FivM9lNrg+HGJfVX8WJqgo+kCLDc4vx6xMeTce7Aj+DLttKbxxRR/gNLSAelRc1omAPlJ77N/Jem07A==}
+
+ y18n@5.0.8:
+ resolution: {integrity: sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA==}
+ engines: {node: '>=10'}
+
+ yallist@3.1.1:
+ resolution: {integrity: sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==}
+
+ yaml-language-server@1.15.0:
+ resolution: {integrity: sha512-N47AqBDCMQmh6mBLmI6oqxryHRzi33aPFPsJhYy3VTUGCdLHYjGh4FZzpUjRlphaADBBkDmnkM/++KNIOHi5Rw==}
+ hasBin: true
+
+ yaml@2.2.2:
+ resolution: {integrity: sha512-CBKFWExMn46Foo4cldiChEzn7S7SRV+wqiluAb6xmueD/fGyRHIhX8m14vVGgeFWjN540nKCNVj6P21eQjgTuA==}
+ engines: {node: '>= 14'}
+
+ yaml@2.5.1:
+ resolution: {integrity: sha512-bLQOjaX/ADgQ20isPJRvF0iRUHIxVhYvr53Of7wGcWlO2jvtUlH5m87DsmulFVxRpNLOnI4tB6p/oh8D7kpn9Q==}
+ engines: {node: '>= 14'}
+ hasBin: true
+
+ yargs-parser@21.1.1:
+ resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==}
+ engines: {node: '>=12'}
+
+ yargs@17.7.2:
+ resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==}
+ engines: {node: '>=12'}
+
+ yocto-queue@1.1.1:
+ resolution: {integrity: sha512-b4JR1PFR10y1mKjhHY9LaGo6tmrgjit7hxVIeAmyMw3jegXR4dhYqLaQF5zMXZxY7tLpMyJeLjr1C4rLmkVe8g==}
+ engines: {node: '>=12.20'}
+
+ zod-to-json-schema@3.23.3:
+ resolution: {integrity: sha512-TYWChTxKQbRJp5ST22o/Irt9KC5nj7CdBKYB/AosCRdj/wxEMvv4NNaj9XVUHDOIp53ZxArGhnw5HMZziPFjog==}
+ peerDependencies:
+ zod: ^3.23.3
+
+ zod-to-ts@1.2.0:
+ resolution: {integrity: sha512-x30XE43V+InwGpvTySRNz9kB7qFU8DlyEy7BsSTCHPH1R0QasMmHWZDCzYm6bVXtj/9NNJAZF3jW8rzFvH5OFA==}
+ peerDependencies:
+ typescript: ^4.9.4 || ^5.0.2
+ zod: ^3
+
+ zod@3.23.8:
+ resolution: {integrity: sha512-XBx9AXhXktjUqnepgTiE5flcKIYWi/rme0Eaj+5Y0lftuGBq+jyRu/md4WnuxqgP1ubdpNCsYEYPxrzVHD8d6g==}
+
+ zwitch@2.0.4:
+ resolution: {integrity: sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==}
+
+snapshots:
+
+ '@ampproject/remapping@2.3.0':
+ dependencies:
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@astrojs/check@0.9.3(typescript@5.6.2)':
+ dependencies:
+ '@astrojs/language-server': 2.14.2(typescript@5.6.2)
+ chokidar: 3.6.0
+ fast-glob: 3.3.2
+ kleur: 4.1.5
+ typescript: 5.6.2
+ yargs: 17.7.2
+ transitivePeerDependencies:
+ - prettier
+ - prettier-plugin-astro
+
+ '@astrojs/compiler@2.10.3': {}
+
+ '@astrojs/internal-helpers@0.4.1': {}
+
+ '@astrojs/language-server@2.14.2(typescript@5.6.2)':
+ dependencies:
+ '@astrojs/compiler': 2.10.3
+ '@astrojs/yaml2ts': 0.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@volar/kit': 2.4.4(typescript@5.6.2)
+ '@volar/language-core': 2.4.4
+ '@volar/language-server': 2.4.4
+ '@volar/language-service': 2.4.4
+ '@volar/typescript': 2.4.4
+ fast-glob: 3.3.2
+ muggle-string: 0.4.1
+ volar-service-css: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-emmet: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-html: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-prettier: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-typescript: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-typescript-twoslash-queries: 0.0.61(@volar/language-service@2.4.4)
+ volar-service-yaml: 0.0.61(@volar/language-service@2.4.4)
+ vscode-html-languageservice: 5.3.1
+ vscode-uri: 3.0.8
+ transitivePeerDependencies:
+ - typescript
+
+ '@astrojs/markdown-remark@5.2.0':
+ dependencies:
+ '@astrojs/prism': 3.1.0
+ github-slugger: 2.0.0
+ hast-util-from-html: 2.0.2
+ hast-util-to-text: 4.0.2
+ import-meta-resolve: 4.1.0
+ mdast-util-definitions: 6.0.0
+ rehype-raw: 7.0.0
+ rehype-stringify: 10.0.0
+ remark-gfm: 4.0.0
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.0
+ remark-smartypants: 3.0.2
+ shiki: 1.17.6
+ unified: 11.0.5
+ unist-util-remove-position: 5.0.0
+ unist-util-visit: 5.0.0
+ unist-util-visit-parents: 6.0.1
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/mdx@3.1.6(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))':
+ dependencies:
+ '@astrojs/markdown-remark': 5.2.0
+ '@mdx-js/mdx': 3.0.1
+ acorn: 8.12.1
+ astro: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ es-module-lexer: 1.5.4
+ estree-util-visit: 2.0.0
+ gray-matter: 4.0.3
+ hast-util-to-html: 9.0.2
+ kleur: 4.1.5
+ rehype-raw: 7.0.0
+ remark-gfm: 4.0.0
+ remark-smartypants: 3.0.2
+ source-map: 0.7.4
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/prism@3.1.0':
+ dependencies:
+ prismjs: 1.29.0
+
+ '@astrojs/sitemap@3.1.6':
+ dependencies:
+ sitemap: 7.1.2
+ stream-replace-string: 2.0.0
+ zod: 3.23.8
+
+ '@astrojs/starlight@0.27.1(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))':
+ dependencies:
+ '@astrojs/mdx': 3.1.6(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ '@astrojs/sitemap': 3.1.6
+ '@pagefind/default-ui': 1.1.1
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ astro: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ astro-expressive-code: 0.35.6(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ bcp-47: 2.1.0
+ hast-util-from-html: 2.0.2
+ hast-util-select: 6.0.2
+ hast-util-to-string: 3.0.0
+ hastscript: 9.0.0
+ mdast-util-directive: 3.0.0
+ mdast-util-to-markdown: 2.1.0
+ mdast-util-to-string: 4.0.0
+ pagefind: 1.1.1
+ rehype: 13.0.1
+ rehype-format: 5.0.0
+ remark-directive: 3.0.0
+ unified: 11.0.5
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/telemetry@3.1.0':
+ dependencies:
+ ci-info: 4.0.0
+ debug: 4.3.7
+ dlv: 1.1.3
+ dset: 3.1.4
+ is-docker: 3.0.0
+ is-wsl: 3.1.0
+ which-pm-runs: 1.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@astrojs/yaml2ts@0.2.1':
+ dependencies:
+ yaml: 2.5.1
+
+ '@babel/code-frame@7.24.7':
+ dependencies:
+ '@babel/highlight': 7.24.7
+ picocolors: 1.1.0
+
+ '@babel/compat-data@7.25.4': {}
+
+ '@babel/core@7.25.2':
+ dependencies:
+ '@ampproject/remapping': 2.3.0
+ '@babel/code-frame': 7.24.7
+ '@babel/generator': 7.25.6
+ '@babel/helper-compilation-targets': 7.25.2
+ '@babel/helper-module-transforms': 7.25.2(@babel/core@7.25.2)
+ '@babel/helpers': 7.25.6
+ '@babel/parser': 7.25.6
+ '@babel/template': 7.25.0
+ '@babel/traverse': 7.25.6
+ '@babel/types': 7.25.6
+ convert-source-map: 2.0.0
+ debug: 4.3.7
+ gensync: 1.0.0-beta.2
+ json5: 2.2.3
+ semver: 6.3.1
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/generator@7.25.6':
+ dependencies:
+ '@babel/types': 7.25.6
+ '@jridgewell/gen-mapping': 0.3.5
+ '@jridgewell/trace-mapping': 0.3.25
+ jsesc: 2.5.2
+
+ '@babel/helper-annotate-as-pure@7.24.7':
+ dependencies:
+ '@babel/types': 7.25.6
+
+ '@babel/helper-compilation-targets@7.25.2':
+ dependencies:
+ '@babel/compat-data': 7.25.4
+ '@babel/helper-validator-option': 7.24.8
+ browserslist: 4.23.3
+ lru-cache: 5.1.1
+ semver: 6.3.1
+
+ '@babel/helper-module-imports@7.24.7':
+ dependencies:
+ '@babel/traverse': 7.25.6
+ '@babel/types': 7.25.6
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-module-transforms@7.25.2(@babel/core@7.25.2)':
+ dependencies:
+ '@babel/core': 7.25.2
+ '@babel/helper-module-imports': 7.24.7
+ '@babel/helper-simple-access': 7.24.7
+ '@babel/helper-validator-identifier': 7.24.7
+ '@babel/traverse': 7.25.6
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-plugin-utils@7.24.8': {}
+
+ '@babel/helper-simple-access@7.24.7':
+ dependencies:
+ '@babel/traverse': 7.25.6
+ '@babel/types': 7.25.6
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/helper-string-parser@7.24.8': {}
+
+ '@babel/helper-validator-identifier@7.24.7': {}
+
+ '@babel/helper-validator-option@7.24.8': {}
+
+ '@babel/helpers@7.25.6':
+ dependencies:
+ '@babel/template': 7.25.0
+ '@babel/types': 7.25.6
+
+ '@babel/highlight@7.24.7':
+ dependencies:
+ '@babel/helper-validator-identifier': 7.24.7
+ chalk: 2.4.2
+ js-tokens: 4.0.0
+ picocolors: 1.1.0
+
+ '@babel/parser@7.25.6':
+ dependencies:
+ '@babel/types': 7.25.6
+
+ '@babel/plugin-syntax-jsx@7.24.7(@babel/core@7.25.2)':
+ dependencies:
+ '@babel/core': 7.25.2
+ '@babel/helper-plugin-utils': 7.24.8
+
+ '@babel/plugin-transform-react-jsx@7.25.2(@babel/core@7.25.2)':
+ dependencies:
+ '@babel/core': 7.25.2
+ '@babel/helper-annotate-as-pure': 7.24.7
+ '@babel/helper-module-imports': 7.24.7
+ '@babel/helper-plugin-utils': 7.24.8
+ '@babel/plugin-syntax-jsx': 7.24.7(@babel/core@7.25.2)
+ '@babel/types': 7.25.6
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/template@7.25.0':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/parser': 7.25.6
+ '@babel/types': 7.25.6
+
+ '@babel/traverse@7.25.6':
+ dependencies:
+ '@babel/code-frame': 7.24.7
+ '@babel/generator': 7.25.6
+ '@babel/parser': 7.25.6
+ '@babel/template': 7.25.0
+ '@babel/types': 7.25.6
+ debug: 4.3.7
+ globals: 11.12.0
+ transitivePeerDependencies:
+ - supports-color
+
+ '@babel/types@7.25.6':
+ dependencies:
+ '@babel/helper-string-parser': 7.24.8
+ '@babel/helper-validator-identifier': 7.24.7
+ to-fast-properties: 2.0.0
+
+ '@ctrl/tinycolor@4.1.0': {}
+
+ '@emmetio/abbreviation@2.3.3':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-abbreviation@2.1.8':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/css-parser@0.4.0':
+ dependencies:
+ '@emmetio/stream-reader': 2.2.0
+ '@emmetio/stream-reader-utils': 0.1.0
+
+ '@emmetio/html-matcher@1.3.0':
+ dependencies:
+ '@emmetio/scanner': 1.0.4
+
+ '@emmetio/scanner@1.0.4': {}
+
+ '@emmetio/stream-reader-utils@0.1.0': {}
+
+ '@emmetio/stream-reader@2.2.0': {}
+
+ '@emnapi/runtime@1.2.0':
+ dependencies:
+ tslib: 2.7.0
+ optional: true
+
+ '@esbuild/aix-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/android-arm@0.21.5':
+ optional: true
+
+ '@esbuild/android-x64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/darwin-x64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/freebsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-arm@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/linux-loong64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-mips64el@0.21.5':
+ optional: true
+
+ '@esbuild/linux-ppc64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-riscv64@0.21.5':
+ optional: true
+
+ '@esbuild/linux-s390x@0.21.5':
+ optional: true
+
+ '@esbuild/linux-x64@0.21.5':
+ optional: true
+
+ '@esbuild/netbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/openbsd-x64@0.21.5':
+ optional: true
+
+ '@esbuild/sunos-x64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-arm64@0.21.5':
+ optional: true
+
+ '@esbuild/win32-ia32@0.21.5':
+ optional: true
+
+ '@esbuild/win32-x64@0.21.5':
+ optional: true
+
+ '@expressive-code/core@0.35.6':
+ dependencies:
+ '@ctrl/tinycolor': 4.1.0
+ hast-util-select: 6.0.2
+ hast-util-to-html: 9.0.2
+ hast-util-to-text: 4.0.2
+ hastscript: 9.0.0
+ postcss: 8.4.45
+ postcss-nested: 6.2.0(postcss@8.4.45)
+ unist-util-visit: 5.0.0
+ unist-util-visit-parents: 6.0.1
+
+ '@expressive-code/plugin-frames@0.35.6':
+ dependencies:
+ '@expressive-code/core': 0.35.6
+
+ '@expressive-code/plugin-shiki@0.35.6':
+ dependencies:
+ '@expressive-code/core': 0.35.6
+ shiki: 1.17.6
+
+ '@expressive-code/plugin-text-markers@0.35.6':
+ dependencies:
+ '@expressive-code/core': 0.35.6
+
+ '@img/sharp-darwin-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-darwin-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-darwin-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-libvips-darwin-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-darwin-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-arm@1.0.5':
+ optional: true
+
+ '@img/sharp-libvips-linux-s390x@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linux-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-arm64@1.0.4':
+ optional: true
+
+ '@img/sharp-libvips-linuxmusl-x64@1.0.4':
+ optional: true
+
+ '@img/sharp-linux-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-linux-arm@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-arm': 1.0.5
+ optional: true
+
+ '@img/sharp-linux-s390x@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-s390x': 1.0.4
+ optional: true
+
+ '@img/sharp-linux-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linux-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-linuxmusl-arm64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
+ optional: true
+
+ '@img/sharp-linuxmusl-x64@0.33.5':
+ optionalDependencies:
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.4
+ optional: true
+
+ '@img/sharp-wasm32@0.33.5':
+ dependencies:
+ '@emnapi/runtime': 1.2.0
+ optional: true
+
+ '@img/sharp-win32-ia32@0.33.5':
+ optional: true
+
+ '@img/sharp-win32-x64@0.33.5':
+ optional: true
+
+ '@jridgewell/gen-mapping@0.3.5':
+ dependencies:
+ '@jridgewell/set-array': 1.2.1
+ '@jridgewell/sourcemap-codec': 1.5.0
+ '@jridgewell/trace-mapping': 0.3.25
+
+ '@jridgewell/resolve-uri@3.1.2': {}
+
+ '@jridgewell/set-array@1.2.1': {}
+
+ '@jridgewell/sourcemap-codec@1.5.0': {}
+
+ '@jridgewell/trace-mapping@0.3.25':
+ dependencies:
+ '@jridgewell/resolve-uri': 3.1.2
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ '@lorenzo_lewis/starlight-utils@0.1.2(@astrojs/starlight@0.27.1(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2)))(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))':
+ dependencies:
+ '@astrojs/starlight': 0.27.1(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ astro: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ astro-integration-kit: 0.14.0(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2))
+ transitivePeerDependencies:
+ - '@astrojs/db'
+
+ '@mdx-js/mdx@3.0.1':
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdx': 2.0.13
+ collapse-white-space: 2.1.0
+ devlop: 1.1.0
+ estree-util-build-jsx: 3.0.1
+ estree-util-is-identifier-name: 3.0.0
+ estree-util-to-js: 2.0.0
+ estree-walker: 3.0.3
+ hast-util-to-estree: 3.1.0
+ hast-util-to-jsx-runtime: 2.3.0
+ markdown-extensions: 2.0.0
+ periscopic: 3.1.0
+ remark-mdx: 3.0.1
+ remark-parse: 11.0.0
+ remark-rehype: 11.1.0
+ source-map: 0.7.4
+ unified: 11.0.5
+ unist-util-position-from-estree: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ transitivePeerDependencies:
+ - supports-color
+
+ '@nodelib/fs.scandir@2.1.5':
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ run-parallel: 1.2.0
+
+ '@nodelib/fs.stat@2.0.5': {}
+
+ '@nodelib/fs.walk@1.2.8':
+ dependencies:
+ '@nodelib/fs.scandir': 2.1.5
+ fastq: 1.17.1
+
+ '@oslojs/encoding@0.4.1': {}
+
+ '@pagefind/darwin-arm64@1.1.1':
+ optional: true
+
+ '@pagefind/darwin-x64@1.1.1':
+ optional: true
+
+ '@pagefind/default-ui@1.1.1': {}
+
+ '@pagefind/linux-arm64@1.1.1':
+ optional: true
+
+ '@pagefind/linux-x64@1.1.1':
+ optional: true
+
+ '@pagefind/windows-x64@1.1.1':
+ optional: true
+
+ '@rollup/pluginutils@5.1.0(rollup@4.21.3)':
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 2.0.2
+ picomatch: 2.3.1
+ optionalDependencies:
+ rollup: 4.21.3
+
+ '@rollup/rollup-android-arm-eabi@4.21.3':
+ optional: true
+
+ '@rollup/rollup-android-arm64@4.21.3':
+ optional: true
+
+ '@rollup/rollup-darwin-arm64@4.21.3':
+ optional: true
+
+ '@rollup/rollup-darwin-x64@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-gnueabihf@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm-musleabihf@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-gnu@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-arm64-musl@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-powerpc64le-gnu@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-riscv64-gnu@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-s390x-gnu@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-gnu@4.21.3':
+ optional: true
+
+ '@rollup/rollup-linux-x64-musl@4.21.3':
+ optional: true
+
+ '@rollup/rollup-win32-arm64-msvc@4.21.3':
+ optional: true
+
+ '@rollup/rollup-win32-ia32-msvc@4.21.3':
+ optional: true
+
+ '@rollup/rollup-win32-x64-msvc@4.21.3':
+ optional: true
+
+ '@shikijs/core@1.17.6':
+ dependencies:
+ '@shikijs/engine-javascript': 1.17.6
+ '@shikijs/engine-oniguruma': 1.17.6
+ '@shikijs/types': 1.17.6
+ '@shikijs/vscode-textmate': 9.2.2
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.2
+
+ '@shikijs/engine-javascript@1.17.6':
+ dependencies:
+ '@shikijs/types': 1.17.6
+ oniguruma-to-js: 0.4.3
+
+ '@shikijs/engine-oniguruma@1.17.6':
+ dependencies:
+ '@shikijs/types': 1.17.6
+ '@shikijs/vscode-textmate': 9.2.2
+
+ '@shikijs/types@1.17.6':
+ dependencies:
+ '@shikijs/vscode-textmate': 9.2.2
+ '@types/hast': 3.0.4
+
+ '@shikijs/vscode-textmate@9.2.2': {}
+
+ '@types/acorn@4.0.6':
+ dependencies:
+ '@types/estree': 1.0.5
+
+ '@types/babel__core@7.20.5':
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@babel/types': 7.25.6
+ '@types/babel__generator': 7.6.8
+ '@types/babel__template': 7.4.4
+ '@types/babel__traverse': 7.20.6
+
+ '@types/babel__generator@7.6.8':
+ dependencies:
+ '@babel/types': 7.25.6
+
+ '@types/babel__template@7.4.4':
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@babel/types': 7.25.6
+
+ '@types/babel__traverse@7.20.6':
+ dependencies:
+ '@babel/types': 7.25.6
+
+ '@types/cookie@0.6.0': {}
+
+ '@types/debug@4.1.12':
+ dependencies:
+ '@types/ms': 0.7.34
+
+ '@types/estree-jsx@1.0.5':
+ dependencies:
+ '@types/estree': 1.0.5
+
+ '@types/estree@1.0.5': {}
+
+ '@types/hast@3.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdast@4.0.4':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/mdx@2.0.13': {}
+
+ '@types/ms@0.7.34': {}
+
+ '@types/nlcst@2.0.3':
+ dependencies:
+ '@types/unist': 3.0.3
+
+ '@types/node@17.0.45': {}
+
+ '@types/sax@1.2.7':
+ dependencies:
+ '@types/node': 17.0.45
+
+ '@types/unist@2.0.11': {}
+
+ '@types/unist@3.0.3': {}
+
+ '@ungap/structured-clone@1.2.0': {}
+
+ '@volar/kit@2.4.4(typescript@5.6.2)':
+ dependencies:
+ '@volar/language-service': 2.4.4
+ '@volar/typescript': 2.4.4
+ typesafe-path: 0.2.2
+ typescript: 5.6.2
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.0.8
+
+ '@volar/language-core@2.4.4':
+ dependencies:
+ '@volar/source-map': 2.4.4
+
+ '@volar/language-server@2.4.4':
+ dependencies:
+ '@volar/language-core': 2.4.4
+ '@volar/language-service': 2.4.4
+ '@volar/typescript': 2.4.4
+ path-browserify: 1.0.1
+ request-light: 0.7.0
+ vscode-languageserver: 9.0.1
+ vscode-languageserver-protocol: 3.17.5
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.0.8
+
+ '@volar/language-service@2.4.4':
+ dependencies:
+ '@volar/language-core': 2.4.4
+ vscode-languageserver-protocol: 3.17.5
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.0.8
+
+ '@volar/source-map@2.4.4': {}
+
+ '@volar/typescript@2.4.4':
+ dependencies:
+ '@volar/language-core': 2.4.4
+ path-browserify: 1.0.1
+ vscode-uri: 3.0.8
+
+ '@vscode/emmet-helper@2.9.3':
+ dependencies:
+ emmet: 2.4.7
+ jsonc-parser: 2.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 2.1.2
+
+ '@vscode/l10n@0.0.18': {}
+
+ acorn-jsx@5.3.2(acorn@8.12.1):
+ dependencies:
+ acorn: 8.12.1
+
+ acorn@8.12.1: {}
+
+ ajv@8.17.1:
+ dependencies:
+ fast-deep-equal: 3.1.3
+ fast-uri: 3.0.1
+ json-schema-traverse: 1.0.0
+ require-from-string: 2.0.2
+
+ ansi-align@3.0.1:
+ dependencies:
+ string-width: 4.2.3
+
+ ansi-regex@5.0.1: {}
+
+ ansi-regex@6.1.0: {}
+
+ ansi-styles@3.2.1:
+ dependencies:
+ color-convert: 1.9.3
+
+ ansi-styles@4.3.0:
+ dependencies:
+ color-convert: 2.0.1
+
+ ansi-styles@6.2.1: {}
+
+ anymatch@3.1.3:
+ dependencies:
+ normalize-path: 3.0.0
+ picomatch: 2.3.1
+
+ arg@5.0.2: {}
+
+ argparse@1.0.10:
+ dependencies:
+ sprintf-js: 1.0.3
+
+ argparse@2.0.1: {}
+
+ aria-query@5.3.1: {}
+
+ array-iterate@2.0.1: {}
+
+ ast-types@0.16.1:
+ dependencies:
+ tslib: 2.7.0
+
+ astring@1.9.0: {}
+
+ astro-expressive-code@0.35.6(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2)):
+ dependencies:
+ astro: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ rehype-expressive-code: 0.35.6
+
+ astro-integration-kit@0.14.0(astro@4.15.5(rollup@4.21.3)(typescript@5.6.2)):
+ dependencies:
+ astro: 4.15.5(rollup@4.21.3)(typescript@5.6.2)
+ pathe: 1.1.2
+ recast: 0.23.9
+
+ astro@4.15.5(rollup@4.21.3)(typescript@5.6.2):
+ dependencies:
+ '@astrojs/compiler': 2.10.3
+ '@astrojs/internal-helpers': 0.4.1
+ '@astrojs/markdown-remark': 5.2.0
+ '@astrojs/telemetry': 3.1.0
+ '@babel/core': 7.25.2
+ '@babel/plugin-transform-react-jsx': 7.25.2(@babel/core@7.25.2)
+ '@babel/types': 7.25.6
+ '@oslojs/encoding': 0.4.1
+ '@rollup/pluginutils': 5.1.0(rollup@4.21.3)
+ '@types/babel__core': 7.20.5
+ '@types/cookie': 0.6.0
+ acorn: 8.12.1
+ aria-query: 5.3.1
+ axobject-query: 4.1.0
+ boxen: 7.1.1
+ ci-info: 4.0.0
+ clsx: 2.1.1
+ common-ancestor-path: 1.0.1
+ cookie: 0.6.0
+ cssesc: 3.0.0
+ debug: 4.3.7
+ deterministic-object-hash: 2.0.2
+ devalue: 5.0.0
+ diff: 5.2.0
+ dlv: 1.1.3
+ dset: 3.1.4
+ es-module-lexer: 1.5.4
+ esbuild: 0.21.5
+ estree-walker: 3.0.3
+ fast-glob: 3.3.2
+ fastq: 1.17.1
+ flattie: 1.1.1
+ github-slugger: 2.0.0
+ gray-matter: 4.0.3
+ html-escaper: 3.0.3
+ http-cache-semantics: 4.1.1
+ js-yaml: 4.1.0
+ kleur: 4.1.5
+ magic-string: 0.30.11
+ magicast: 0.3.5
+ micromatch: 4.0.8
+ mrmime: 2.0.0
+ neotraverse: 0.6.18
+ ora: 8.1.0
+ p-limit: 6.1.0
+ p-queue: 8.0.1
+ preferred-pm: 4.0.0
+ prompts: 2.4.2
+ rehype: 13.0.1
+ semver: 7.6.3
+ shiki: 1.17.6
+ string-width: 7.2.0
+ strip-ansi: 7.1.0
+ tinyexec: 0.3.0
+ tsconfck: 3.1.3(typescript@5.6.2)
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ vite: 5.4.5
+ vitefu: 1.0.2(vite@5.4.5)
+ which-pm: 3.0.0
+ xxhash-wasm: 1.0.2
+ yargs-parser: 21.1.1
+ zod: 3.23.8
+ zod-to-json-schema: 3.23.3(zod@3.23.8)
+ zod-to-ts: 1.2.0(typescript@5.6.2)(zod@3.23.8)
+ optionalDependencies:
+ sharp: 0.33.5
+ transitivePeerDependencies:
+ - '@types/node'
+ - less
+ - lightningcss
+ - rollup
+ - sass
+ - sass-embedded
+ - stylus
+ - sugarss
+ - supports-color
+ - terser
+ - typescript
+
+ axobject-query@4.1.0: {}
+
+ b4a@1.6.6: {}
+
+ bail@2.0.2: {}
+
+ bare-events@2.4.2:
+ optional: true
+
+ bare-fs@2.3.5:
+ dependencies:
+ bare-events: 2.4.2
+ bare-path: 2.1.3
+ bare-stream: 2.3.0
+ optional: true
+
+ bare-os@2.4.4:
+ optional: true
+
+ bare-path@2.1.3:
+ dependencies:
+ bare-os: 2.4.4
+ optional: true
+
+ bare-stream@2.3.0:
+ dependencies:
+ b4a: 1.6.6
+ streamx: 2.20.1
+ optional: true
+
+ base-64@1.0.0: {}
+
+ base64-js@1.5.1: {}
+
+ bcp-47-match@2.0.3: {}
+
+ bcp-47@2.1.0:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+
+ binary-extensions@2.3.0: {}
+
+ bl@4.1.0:
+ dependencies:
+ buffer: 5.7.1
+ inherits: 2.0.4
+ readable-stream: 3.6.2
+
+ boolbase@1.0.0: {}
+
+ boxen@7.1.1:
+ dependencies:
+ ansi-align: 3.0.1
+ camelcase: 7.0.1
+ chalk: 5.3.0
+ cli-boxes: 3.0.0
+ string-width: 5.1.2
+ type-fest: 2.19.0
+ widest-line: 4.0.1
+ wrap-ansi: 8.1.0
+
+ braces@3.0.3:
+ dependencies:
+ fill-range: 7.1.1
+
+ browserslist@4.23.3:
+ dependencies:
+ caniuse-lite: 1.0.30001660
+ electron-to-chromium: 1.5.22
+ node-releases: 2.0.18
+ update-browserslist-db: 1.1.0(browserslist@4.23.3)
+
+ buffer@5.7.1:
+ dependencies:
+ base64-js: 1.5.1
+ ieee754: 1.2.1
+
+ camelcase@7.0.1: {}
+
+ caniuse-lite@1.0.30001660: {}
+
+ ccount@2.0.1: {}
+
+ chalk@2.4.2:
+ dependencies:
+ ansi-styles: 3.2.1
+ escape-string-regexp: 1.0.5
+ supports-color: 5.5.0
+
+ chalk@5.3.0: {}
+
+ character-entities-html4@2.1.0: {}
+
+ character-entities-legacy@3.0.0: {}
+
+ character-entities@2.0.2: {}
+
+ character-reference-invalid@2.0.1: {}
+
+ chokidar@3.6.0:
+ dependencies:
+ anymatch: 3.1.3
+ braces: 3.0.3
+ glob-parent: 5.1.2
+ is-binary-path: 2.1.0
+ is-glob: 4.0.3
+ normalize-path: 3.0.0
+ readdirp: 3.6.0
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ chownr@1.1.4: {}
+
+ ci-info@4.0.0: {}
+
+ cli-boxes@3.0.0: {}
+
+ cli-cursor@5.0.0:
+ dependencies:
+ restore-cursor: 5.1.0
+
+ cli-spinners@2.9.2: {}
+
+ cliui@8.0.1:
+ dependencies:
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+ wrap-ansi: 7.0.0
+
+ clsx@2.1.1: {}
+
+ collapse-white-space@2.1.0: {}
+
+ color-convert@1.9.3:
+ dependencies:
+ color-name: 1.1.3
+
+ color-convert@2.0.1:
+ dependencies:
+ color-name: 1.1.4
+
+ color-name@1.1.3: {}
+
+ color-name@1.1.4: {}
+
+ color-string@1.9.1:
+ dependencies:
+ color-name: 1.1.4
+ simple-swizzle: 0.2.2
+
+ color@4.2.3:
+ dependencies:
+ color-convert: 2.0.1
+ color-string: 1.9.1
+
+ comma-separated-tokens@2.0.3: {}
+
+ common-ancestor-path@1.0.1: {}
+
+ convert-source-map@2.0.0: {}
+
+ cookie@0.6.0: {}
+
+ css-selector-parser@3.0.5: {}
+
+ cssesc@3.0.0: {}
+
+ debug@4.3.7:
+ dependencies:
+ ms: 2.1.3
+
+ decode-named-character-reference@1.0.2:
+ dependencies:
+ character-entities: 2.0.2
+
+ decompress-response@6.0.0:
+ dependencies:
+ mimic-response: 3.1.0
+
+ deep-extend@0.6.0: {}
+
+ dequal@2.0.3: {}
+
+ detect-libc@2.0.3: {}
+
+ deterministic-object-hash@2.0.2:
+ dependencies:
+ base-64: 1.0.0
+
+ devalue@5.0.0: {}
+
+ devlop@1.1.0:
+ dependencies:
+ dequal: 2.0.3
+
+ diff@5.2.0: {}
+
+ direction@2.0.1: {}
+
+ dlv@1.1.3: {}
+
+ dset@3.1.4: {}
+
+ eastasianwidth@0.2.0: {}
+
+ electron-to-chromium@1.5.22: {}
+
+ emmet@2.4.7:
+ dependencies:
+ '@emmetio/abbreviation': 2.3.3
+ '@emmetio/css-abbreviation': 2.1.8
+
+ emoji-regex@10.4.0: {}
+
+ emoji-regex@8.0.0: {}
+
+ emoji-regex@9.2.2: {}
+
+ end-of-stream@1.4.4:
+ dependencies:
+ once: 1.4.0
+
+ entities@4.5.0: {}
+
+ es-module-lexer@1.5.4: {}
+
+ esbuild@0.21.5:
+ optionalDependencies:
+ '@esbuild/aix-ppc64': 0.21.5
+ '@esbuild/android-arm': 0.21.5
+ '@esbuild/android-arm64': 0.21.5
+ '@esbuild/android-x64': 0.21.5
+ '@esbuild/darwin-arm64': 0.21.5
+ '@esbuild/darwin-x64': 0.21.5
+ '@esbuild/freebsd-arm64': 0.21.5
+ '@esbuild/freebsd-x64': 0.21.5
+ '@esbuild/linux-arm': 0.21.5
+ '@esbuild/linux-arm64': 0.21.5
+ '@esbuild/linux-ia32': 0.21.5
+ '@esbuild/linux-loong64': 0.21.5
+ '@esbuild/linux-mips64el': 0.21.5
+ '@esbuild/linux-ppc64': 0.21.5
+ '@esbuild/linux-riscv64': 0.21.5
+ '@esbuild/linux-s390x': 0.21.5
+ '@esbuild/linux-x64': 0.21.5
+ '@esbuild/netbsd-x64': 0.21.5
+ '@esbuild/openbsd-x64': 0.21.5
+ '@esbuild/sunos-x64': 0.21.5
+ '@esbuild/win32-arm64': 0.21.5
+ '@esbuild/win32-ia32': 0.21.5
+ '@esbuild/win32-x64': 0.21.5
+
+ escalade@3.2.0: {}
+
+ escape-string-regexp@1.0.5: {}
+
+ escape-string-regexp@5.0.0: {}
+
+ esprima@4.0.1: {}
+
+ estree-util-attach-comments@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.5
+
+ estree-util-build-jsx@3.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ estree-walker: 3.0.3
+
+ estree-util-is-identifier-name@3.0.0: {}
+
+ estree-util-to-js@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ astring: 1.9.0
+ source-map: 0.7.4
+
+ estree-util-visit@2.0.0:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/unist': 3.0.3
+
+ estree-walker@2.0.2: {}
+
+ estree-walker@3.0.3:
+ dependencies:
+ '@types/estree': 1.0.5
+
+ eventemitter3@5.0.1: {}
+
+ expand-template@2.0.3: {}
+
+ expressive-code@0.35.6:
+ dependencies:
+ '@expressive-code/core': 0.35.6
+ '@expressive-code/plugin-frames': 0.35.6
+ '@expressive-code/plugin-shiki': 0.35.6
+ '@expressive-code/plugin-text-markers': 0.35.6
+
+ extend-shallow@2.0.1:
+ dependencies:
+ is-extendable: 0.1.1
+
+ extend@3.0.2: {}
+
+ fast-deep-equal@3.1.3: {}
+
+ fast-fifo@1.3.2: {}
+
+ fast-glob@3.3.2:
+ dependencies:
+ '@nodelib/fs.stat': 2.0.5
+ '@nodelib/fs.walk': 1.2.8
+ glob-parent: 5.1.2
+ merge2: 1.4.1
+ micromatch: 4.0.8
+
+ fast-uri@3.0.1: {}
+
+ fastq@1.17.1:
+ dependencies:
+ reusify: 1.0.4
+
+ fill-range@7.1.1:
+ dependencies:
+ to-regex-range: 5.0.1
+
+ find-up-simple@1.0.0: {}
+
+ find-up@4.1.0:
+ dependencies:
+ locate-path: 5.0.0
+ path-exists: 4.0.0
+
+ find-yarn-workspace-root2@1.2.16:
+ dependencies:
+ micromatch: 4.0.8
+ pkg-dir: 4.2.0
+
+ flattie@1.1.1: {}
+
+ fs-constants@1.0.0: {}
+
+ fsevents@2.3.3:
+ optional: true
+
+ gensync@1.0.0-beta.2: {}
+
+ get-caller-file@2.0.5: {}
+
+ get-east-asian-width@1.2.0: {}
+
+ github-from-package@0.0.0: {}
+
+ github-slugger@2.0.0: {}
+
+ glob-parent@5.1.2:
+ dependencies:
+ is-glob: 4.0.3
+
+ globals@11.12.0: {}
+
+ graceful-fs@4.2.11: {}
+
+ gray-matter@4.0.3:
+ dependencies:
+ js-yaml: 3.14.1
+ kind-of: 6.0.3
+ section-matter: 1.0.0
+ strip-bom-string: 1.0.0
+
+ has-flag@3.0.0: {}
+
+ hast-util-embedded@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-is-element: 3.0.0
+
+ hast-util-from-html@2.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ devlop: 1.1.0
+ hast-util-from-parse5: 8.0.1
+ parse5: 7.1.2
+ vfile: 6.0.3
+ vfile-message: 4.0.2
+
+ hast-util-from-parse5@8.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ hastscript: 8.0.0
+ property-information: 6.5.0
+ vfile: 6.0.3
+ vfile-location: 5.0.3
+ web-namespaces: 2.0.1
+
+ hast-util-has-property@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-is-body-ok-link@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-is-element@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-parse-selector@4.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-phrasing@3.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-has-property: 3.0.0
+ hast-util-is-body-ok-link: 3.0.0
+ hast-util-is-element: 3.0.0
+
+ hast-util-raw@9.0.4:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ '@ungap/structured-clone': 1.2.0
+ hast-util-from-parse5: 8.0.1
+ hast-util-to-parse5: 8.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.0
+ parse5: 7.1.2
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-select@6.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ bcp-47-match: 2.0.3
+ comma-separated-tokens: 2.0.3
+ css-selector-parser: 3.0.5
+ devlop: 1.1.0
+ direction: 2.0.1
+ hast-util-has-property: 3.0.0
+ hast-util-to-string: 3.0.0
+ hast-util-whitespace: 3.0.0
+ not: 0.1.0
+ nth-check: 2.1.1
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ unist-util-visit: 5.0.0
+ zwitch: 2.0.4
+
+ hast-util-to-estree@3.1.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-attach-comments: 3.0.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.1.3
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ style-to-object: 0.4.4
+ unist-util-position: 5.0.0
+ zwitch: 2.0.4
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-html@9.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ comma-separated-tokens: 2.0.3
+ hast-util-whitespace: 3.0.0
+ html-void-elements: 3.0.0
+ mdast-util-to-hast: 13.2.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ stringify-entities: 4.0.4
+ zwitch: 2.0.4
+
+ hast-util-to-jsx-runtime@2.3.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ hast-util-whitespace: 3.0.0
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.1.3
+ mdast-util-mdxjs-esm: 2.0.1
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ style-to-object: 1.0.8
+ unist-util-position: 5.0.0
+ vfile-message: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ hast-util-to-parse5@8.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ devlop: 1.1.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+ web-namespaces: 2.0.1
+ zwitch: 2.0.4
+
+ hast-util-to-string@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hast-util-to-text@4.0.2:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/unist': 3.0.3
+ hast-util-is-element: 3.0.0
+ unist-util-find-after: 5.0.0
+
+ hast-util-whitespace@3.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+
+ hastscript@8.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+
+ hastscript@9.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ comma-separated-tokens: 2.0.3
+ hast-util-parse-selector: 4.0.0
+ property-information: 6.5.0
+ space-separated-tokens: 2.0.2
+
+ html-escaper@3.0.3: {}
+
+ html-void-elements@3.0.0: {}
+
+ html-whitespace-sensitive-tag-names@3.0.0: {}
+
+ http-cache-semantics@4.1.1: {}
+
+ ieee754@1.2.1: {}
+
+ import-meta-resolve@4.1.0: {}
+
+ inherits@2.0.4: {}
+
+ ini@1.3.8: {}
+
+ inline-style-parser@0.1.1: {}
+
+ inline-style-parser@0.2.4: {}
+
+ is-alphabetical@2.0.1: {}
+
+ is-alphanumerical@2.0.1:
+ dependencies:
+ is-alphabetical: 2.0.1
+ is-decimal: 2.0.1
+
+ is-arrayish@0.3.2: {}
+
+ is-binary-path@2.1.0:
+ dependencies:
+ binary-extensions: 2.3.0
+
+ is-decimal@2.0.1: {}
+
+ is-docker@3.0.0: {}
+
+ is-extendable@0.1.1: {}
+
+ is-extglob@2.1.1: {}
+
+ is-fullwidth-code-point@3.0.0: {}
+
+ is-glob@4.0.3:
+ dependencies:
+ is-extglob: 2.1.1
+
+ is-hexadecimal@2.0.1: {}
+
+ is-inside-container@1.0.0:
+ dependencies:
+ is-docker: 3.0.0
+
+ is-interactive@2.0.0: {}
+
+ is-number@7.0.0: {}
+
+ is-plain-obj@4.1.0: {}
+
+ is-reference@3.0.2:
+ dependencies:
+ '@types/estree': 1.0.5
+
+ is-unicode-supported@1.3.0: {}
+
+ is-unicode-supported@2.1.0: {}
+
+ is-wsl@3.1.0:
+ dependencies:
+ is-inside-container: 1.0.0
+
+ js-tokens@4.0.0: {}
+
+ js-yaml@3.14.1:
+ dependencies:
+ argparse: 1.0.10
+ esprima: 4.0.1
+
+ js-yaml@4.1.0:
+ dependencies:
+ argparse: 2.0.1
+
+ jsesc@2.5.2: {}
+
+ json-schema-traverse@1.0.0: {}
+
+ json5@2.2.3: {}
+
+ jsonc-parser@2.3.1: {}
+
+ jsonc-parser@3.3.1: {}
+
+ kind-of@6.0.3: {}
+
+ kleur@3.0.3: {}
+
+ kleur@4.1.5: {}
+
+ load-yaml-file@0.2.0:
+ dependencies:
+ graceful-fs: 4.2.11
+ js-yaml: 3.14.1
+ pify: 4.0.1
+ strip-bom: 3.0.0
+
+ locate-path@5.0.0:
+ dependencies:
+ p-locate: 4.1.0
+
+ lodash@4.17.21: {}
+
+ log-symbols@6.0.0:
+ dependencies:
+ chalk: 5.3.0
+ is-unicode-supported: 1.3.0
+
+ longest-streak@3.1.0: {}
+
+ lru-cache@5.1.1:
+ dependencies:
+ yallist: 3.1.1
+
+ magic-string@0.30.11:
+ dependencies:
+ '@jridgewell/sourcemap-codec': 1.5.0
+
+ magicast@0.3.5:
+ dependencies:
+ '@babel/parser': 7.25.6
+ '@babel/types': 7.25.6
+ source-map-js: 1.2.1
+
+ markdown-extensions@2.0.0: {}
+
+ markdown-table@3.0.3: {}
+
+ mdast-util-definitions@6.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.0.0
+
+ mdast-util-directive@3.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ parse-entities: 4.0.1
+ stringify-entities: 4.0.4
+ unist-util-visit-parents: 6.0.1
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-find-and-replace@3.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ escape-string-regexp: 5.0.0
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
+ mdast-util-from-markdown@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ decode-named-character-reference: 1.0.2
+ devlop: 1.1.0
+ mdast-util-to-string: 4.0.0
+ micromark: 4.0.0
+ micromark-util-decode-numeric-character-reference: 2.0.1
+ micromark-util-decode-string: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ unist-util-stringify-position: 4.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-autolink-literal@2.0.1:
+ dependencies:
+ '@types/mdast': 4.0.4
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-find-and-replace: 3.0.1
+ micromark-util-character: 2.1.0
+
+ mdast-util-gfm-footnote@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ micromark-util-normalize-identifier: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-strikethrough@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-table@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ markdown-table: 3.0.3
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm-task-list-item@2.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-gfm@3.0.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-gfm-autolink-literal: 2.0.1
+ mdast-util-gfm-footnote: 2.0.0
+ mdast-util-gfm-strikethrough: 2.0.0
+ mdast-util-gfm-table: 2.0.0
+ mdast-util-gfm-task-list-item: 2.0.0
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-expression@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx-jsx@3.1.3:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ ccount: 2.0.1
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ parse-entities: 4.0.1
+ stringify-entities: 4.0.4
+ unist-util-stringify-position: 4.0.0
+ vfile-message: 4.0.2
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdx@3.0.0:
+ dependencies:
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-mdx-expression: 2.0.1
+ mdast-util-mdx-jsx: 3.1.3
+ mdast-util-mdxjs-esm: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-mdxjs-esm@2.0.1:
+ dependencies:
+ '@types/estree-jsx': 1.0.5
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ devlop: 1.1.0
+ mdast-util-from-markdown: 2.0.1
+ mdast-util-to-markdown: 2.1.0
+ transitivePeerDependencies:
+ - supports-color
+
+ mdast-util-phrasing@4.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ unist-util-is: 6.0.0
+
+ mdast-util-to-hast@13.2.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ '@ungap/structured-clone': 1.2.0
+ devlop: 1.1.0
+ micromark-util-sanitize-uri: 2.0.0
+ trim-lines: 3.0.1
+ unist-util-position: 5.0.0
+ unist-util-visit: 5.0.0
+ vfile: 6.0.3
+
+ mdast-util-to-markdown@2.1.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ '@types/unist': 3.0.3
+ longest-streak: 3.1.0
+ mdast-util-phrasing: 4.1.0
+ mdast-util-to-string: 4.0.0
+ micromark-util-decode-string: 2.0.0
+ unist-util-visit: 5.0.0
+ zwitch: 2.0.4
+
+ mdast-util-to-string@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+
+ merge2@1.4.1: {}
+
+ micromark-core-commonmark@2.0.1:
+ dependencies:
+ decode-named-character-reference: 1.0.2
+ devlop: 1.1.0
+ micromark-factory-destination: 2.0.0
+ micromark-factory-label: 2.0.0
+ micromark-factory-space: 2.0.0
+ micromark-factory-title: 2.0.0
+ micromark-factory-whitespace: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-classify-character: 2.0.0
+ micromark-util-html-tag-name: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-subtokenize: 2.0.1
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-directive@3.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-factory-whitespace: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ parse-entities: 4.0.1
+
+ micromark-extension-gfm-autolink-literal@2.1.0:
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-footnote@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.1
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-strikethrough@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-classify-character: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-table@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-tagfilter@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm-task-list-item@2.1.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-gfm@3.0.0:
+ dependencies:
+ micromark-extension-gfm-autolink-literal: 2.1.0
+ micromark-extension-gfm-footnote: 2.1.0
+ micromark-extension-gfm-strikethrough: 2.1.0
+ micromark-extension-gfm-table: 2.1.0
+ micromark-extension-gfm-tagfilter: 2.0.0
+ micromark-extension-gfm-task-list-item: 2.1.0
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-mdx-expression@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ devlop: 1.1.0
+ micromark-factory-mdx-expression: 2.0.2
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-events-to-acorn: 2.0.2
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-extension-mdx-jsx@3.0.1:
+ dependencies:
+ '@types/acorn': 4.0.6
+ '@types/estree': 1.0.5
+ devlop: 1.1.0
+ estree-util-is-identifier-name: 3.0.0
+ micromark-factory-mdx-expression: 2.0.2
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-events-to-acorn: 2.0.2
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-extension-mdx-md@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.0
+
+ micromark-extension-mdxjs-esm@3.0.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.1
+ micromark-util-character: 2.1.0
+ micromark-util-events-to-acorn: 2.0.2
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-extension-mdxjs@3.0.0:
+ dependencies:
+ acorn: 8.12.1
+ acorn-jsx: 5.3.2(acorn@8.12.1)
+ micromark-extension-mdx-expression: 3.0.0
+ micromark-extension-mdx-jsx: 3.0.1
+ micromark-extension-mdx-md: 2.0.0
+ micromark-extension-mdxjs-esm: 3.0.0
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-destination@2.0.0:
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-label@2.0.0:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-mdx-expression@2.0.2:
+ dependencies:
+ '@types/estree': 1.0.5
+ devlop: 1.1.0
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-events-to-acorn: 2.0.2
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ unist-util-position-from-estree: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-factory-space@2.0.0:
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-title@2.0.0:
+ dependencies:
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-factory-whitespace@2.0.0:
+ dependencies:
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-character@2.1.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-chunked@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-classify-character@2.0.0:
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-combine-extensions@2.0.0:
+ dependencies:
+ micromark-util-chunked: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-decode-numeric-character-reference@2.0.1:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-decode-string@2.0.0:
+ dependencies:
+ decode-named-character-reference: 1.0.2
+ micromark-util-character: 2.1.0
+ micromark-util-decode-numeric-character-reference: 2.0.1
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-encode@2.0.0: {}
+
+ micromark-util-events-to-acorn@2.0.2:
+ dependencies:
+ '@types/acorn': 4.0.6
+ '@types/estree': 1.0.5
+ '@types/unist': 3.0.3
+ devlop: 1.1.0
+ estree-util-visit: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ vfile-message: 4.0.2
+
+ micromark-util-html-tag-name@2.0.0: {}
+
+ micromark-util-normalize-identifier@2.0.0:
+ dependencies:
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-resolve-all@2.0.0:
+ dependencies:
+ micromark-util-types: 2.0.0
+
+ micromark-util-sanitize-uri@2.0.0:
+ dependencies:
+ micromark-util-character: 2.1.0
+ micromark-util-encode: 2.0.0
+ micromark-util-symbol: 2.0.0
+
+ micromark-util-subtokenize@2.0.1:
+ dependencies:
+ devlop: 1.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+
+ micromark-util-symbol@2.0.0: {}
+
+ micromark-util-types@2.0.0: {}
+
+ micromark@4.0.0:
+ dependencies:
+ '@types/debug': 4.1.12
+ debug: 4.3.7
+ decode-named-character-reference: 1.0.2
+ devlop: 1.1.0
+ micromark-core-commonmark: 2.0.1
+ micromark-factory-space: 2.0.0
+ micromark-util-character: 2.1.0
+ micromark-util-chunked: 2.0.0
+ micromark-util-combine-extensions: 2.0.0
+ micromark-util-decode-numeric-character-reference: 2.0.1
+ micromark-util-encode: 2.0.0
+ micromark-util-normalize-identifier: 2.0.0
+ micromark-util-resolve-all: 2.0.0
+ micromark-util-sanitize-uri: 2.0.0
+ micromark-util-subtokenize: 2.0.1
+ micromark-util-symbol: 2.0.0
+ micromark-util-types: 2.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ micromatch@4.0.8:
+ dependencies:
+ braces: 3.0.3
+ picomatch: 2.3.1
+
+ mimic-function@5.0.1: {}
+
+ mimic-response@3.1.0: {}
+
+ minimist@1.2.8: {}
+
+ mkdirp-classic@0.5.3: {}
+
+ mrmime@2.0.0: {}
+
+ ms@2.1.3: {}
+
+ muggle-string@0.4.1: {}
+
+ nanoid@3.3.7: {}
+
+ napi-build-utils@1.0.2: {}
+
+ neotraverse@0.6.18: {}
+
+ nlcst-to-string@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+
+ node-abi@3.67.0:
+ dependencies:
+ semver: 7.6.3
+
+ node-addon-api@6.1.0: {}
+
+ node-releases@2.0.18: {}
+
+ normalize-path@3.0.0: {}
+
+ not@0.1.0: {}
+
+ nth-check@2.1.1:
+ dependencies:
+ boolbase: 1.0.0
+
+ once@1.4.0:
+ dependencies:
+ wrappy: 1.0.2
+
+ onetime@7.0.0:
+ dependencies:
+ mimic-function: 5.0.1
+
+ oniguruma-to-js@0.4.3:
+ dependencies:
+ regex: 4.3.2
+
+ ora@8.1.0:
+ dependencies:
+ chalk: 5.3.0
+ cli-cursor: 5.0.0
+ cli-spinners: 2.9.2
+ is-interactive: 2.0.0
+ is-unicode-supported: 2.1.0
+ log-symbols: 6.0.0
+ stdin-discarder: 0.2.2
+ string-width: 7.2.0
+ strip-ansi: 7.1.0
+
+ p-limit@2.3.0:
+ dependencies:
+ p-try: 2.2.0
+
+ p-limit@6.1.0:
+ dependencies:
+ yocto-queue: 1.1.1
+
+ p-locate@4.1.0:
+ dependencies:
+ p-limit: 2.3.0
+
+ p-queue@8.0.1:
+ dependencies:
+ eventemitter3: 5.0.1
+ p-timeout: 6.1.2
+
+ p-timeout@6.1.2: {}
+
+ p-try@2.2.0: {}
+
+ pagefind@1.1.1:
+ optionalDependencies:
+ '@pagefind/darwin-arm64': 1.1.1
+ '@pagefind/darwin-x64': 1.1.1
+ '@pagefind/linux-arm64': 1.1.1
+ '@pagefind/linux-x64': 1.1.1
+ '@pagefind/windows-x64': 1.1.1
+
+ parse-entities@4.0.1:
+ dependencies:
+ '@types/unist': 2.0.11
+ character-entities: 2.0.2
+ character-entities-legacy: 3.0.0
+ character-reference-invalid: 2.0.1
+ decode-named-character-reference: 1.0.2
+ is-alphanumerical: 2.0.1
+ is-decimal: 2.0.1
+ is-hexadecimal: 2.0.1
+
+ parse-latin@7.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ '@types/unist': 3.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-modify-children: 4.0.0
+ unist-util-visit-children: 3.0.0
+ vfile: 6.0.3
+
+ parse5@7.1.2:
+ dependencies:
+ entities: 4.5.0
+
+ path-browserify@1.0.1: {}
+
+ path-exists@4.0.0: {}
+
+ pathe@1.1.2: {}
+
+ periscopic@3.1.0:
+ dependencies:
+ '@types/estree': 1.0.5
+ estree-walker: 3.0.3
+ is-reference: 3.0.2
+
+ picocolors@1.1.0: {}
+
+ picomatch@2.3.1: {}
+
+ pify@4.0.1: {}
+
+ pkg-dir@4.2.0:
+ dependencies:
+ find-up: 4.1.0
+
+ postcss-nested@6.2.0(postcss@8.4.45):
+ dependencies:
+ postcss: 8.4.45
+ postcss-selector-parser: 6.1.2
+
+ postcss-selector-parser@6.1.2:
+ dependencies:
+ cssesc: 3.0.0
+ util-deprecate: 1.0.2
+
+ postcss@8.4.45:
+ dependencies:
+ nanoid: 3.3.7
+ picocolors: 1.1.0
+ source-map-js: 1.2.1
+
+ prebuild-install@7.1.2:
+ dependencies:
+ detect-libc: 2.0.3
+ expand-template: 2.0.3
+ github-from-package: 0.0.0
+ minimist: 1.2.8
+ mkdirp-classic: 0.5.3
+ napi-build-utils: 1.0.2
+ node-abi: 3.67.0
+ pump: 3.0.2
+ rc: 1.2.8
+ simple-get: 4.0.1
+ tar-fs: 2.1.1
+ tunnel-agent: 0.6.0
+
+ preferred-pm@4.0.0:
+ dependencies:
+ find-up-simple: 1.0.0
+ find-yarn-workspace-root2: 1.2.16
+ which-pm: 3.0.0
+
+ prettier@2.8.7:
+ optional: true
+
+ prismjs@1.29.0: {}
+
+ prompts@2.4.2:
+ dependencies:
+ kleur: 3.0.3
+ sisteransi: 1.0.5
+
+ property-information@6.5.0: {}
+
+ pump@3.0.2:
+ dependencies:
+ end-of-stream: 1.4.4
+ once: 1.4.0
+
+ queue-microtask@1.2.3: {}
+
+ queue-tick@1.0.1: {}
+
+ rc@1.2.8:
+ dependencies:
+ deep-extend: 0.6.0
+ ini: 1.3.8
+ minimist: 1.2.8
+ strip-json-comments: 2.0.1
+
+ readable-stream@3.6.2:
+ dependencies:
+ inherits: 2.0.4
+ string_decoder: 1.3.0
+ util-deprecate: 1.0.2
+
+ readdirp@3.6.0:
+ dependencies:
+ picomatch: 2.3.1
+
+ recast@0.23.9:
+ dependencies:
+ ast-types: 0.16.1
+ esprima: 4.0.1
+ source-map: 0.6.1
+ tiny-invariant: 1.3.3
+ tslib: 2.7.0
+
+ regex@4.3.2: {}
+
+ rehype-expressive-code@0.35.6:
+ dependencies:
+ expressive-code: 0.35.6
+
+ rehype-format@5.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-is-element: 3.0.0
+ hast-util-phrasing: 3.0.1
+ hast-util-whitespace: 3.0.0
+ html-whitespace-sensitive-tag-names: 3.0.0
+ rehype-minify-whitespace: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
+ rehype-minify-whitespace@6.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-embedded: 3.0.0
+ hast-util-is-element: 3.0.0
+ hast-util-whitespace: 3.0.0
+ unist-util-is: 6.0.0
+
+ rehype-parse@9.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-from-html: 2.0.2
+ unified: 11.0.5
+
+ rehype-raw@7.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-raw: 9.0.4
+ vfile: 6.0.3
+
+ rehype-stringify@10.0.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ hast-util-to-html: 9.0.2
+ unified: 11.0.5
+
+ rehype@13.0.1:
+ dependencies:
+ '@types/hast': 3.0.4
+ rehype-parse: 9.0.0
+ rehype-stringify: 10.0.0
+ unified: 11.0.5
+
+ remark-directive@3.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-directive: 3.0.0
+ micromark-extension-directive: 3.0.1
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-gfm@4.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-gfm: 3.0.0
+ micromark-extension-gfm: 3.0.0
+ remark-parse: 11.0.0
+ remark-stringify: 11.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-mdx@3.0.1:
+ dependencies:
+ mdast-util-mdx: 3.0.0
+ micromark-extension-mdxjs: 3.0.0
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-parse@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-from-markdown: 2.0.1
+ micromark-util-types: 2.0.0
+ unified: 11.0.5
+ transitivePeerDependencies:
+ - supports-color
+
+ remark-rehype@11.1.0:
+ dependencies:
+ '@types/hast': 3.0.4
+ '@types/mdast': 4.0.4
+ mdast-util-to-hast: 13.2.0
+ unified: 11.0.5
+ vfile: 6.0.3
+
+ remark-smartypants@3.0.2:
+ dependencies:
+ retext: 9.0.0
+ retext-smartypants: 6.1.1
+ unified: 11.0.5
+ unist-util-visit: 5.0.0
+
+ remark-stringify@11.0.0:
+ dependencies:
+ '@types/mdast': 4.0.4
+ mdast-util-to-markdown: 2.1.0
+ unified: 11.0.5
+
+ request-light@0.5.8: {}
+
+ request-light@0.7.0: {}
+
+ require-directory@2.1.1: {}
+
+ require-from-string@2.0.2: {}
+
+ restore-cursor@5.1.0:
+ dependencies:
+ onetime: 7.0.0
+ signal-exit: 4.1.0
+
+ retext-latin@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ parse-latin: 7.0.0
+ unified: 11.0.5
+
+ retext-smartypants@6.1.1:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unist-util-visit: 5.0.0
+
+ retext-stringify@4.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ nlcst-to-string: 4.0.0
+ unified: 11.0.5
+
+ retext@9.0.0:
+ dependencies:
+ '@types/nlcst': 2.0.3
+ retext-latin: 4.0.0
+ retext-stringify: 4.0.0
+ unified: 11.0.5
+
+ reusify@1.0.4: {}
+
+ rollup@4.21.3:
+ dependencies:
+ '@types/estree': 1.0.5
+ optionalDependencies:
+ '@rollup/rollup-android-arm-eabi': 4.21.3
+ '@rollup/rollup-android-arm64': 4.21.3
+ '@rollup/rollup-darwin-arm64': 4.21.3
+ '@rollup/rollup-darwin-x64': 4.21.3
+ '@rollup/rollup-linux-arm-gnueabihf': 4.21.3
+ '@rollup/rollup-linux-arm-musleabihf': 4.21.3
+ '@rollup/rollup-linux-arm64-gnu': 4.21.3
+ '@rollup/rollup-linux-arm64-musl': 4.21.3
+ '@rollup/rollup-linux-powerpc64le-gnu': 4.21.3
+ '@rollup/rollup-linux-riscv64-gnu': 4.21.3
+ '@rollup/rollup-linux-s390x-gnu': 4.21.3
+ '@rollup/rollup-linux-x64-gnu': 4.21.3
+ '@rollup/rollup-linux-x64-musl': 4.21.3
+ '@rollup/rollup-win32-arm64-msvc': 4.21.3
+ '@rollup/rollup-win32-ia32-msvc': 4.21.3
+ '@rollup/rollup-win32-x64-msvc': 4.21.3
+ fsevents: 2.3.3
+
+ run-parallel@1.2.0:
+ dependencies:
+ queue-microtask: 1.2.3
+
+ safe-buffer@5.2.1: {}
+
+ sax@1.4.1: {}
+
+ section-matter@1.0.0:
+ dependencies:
+ extend-shallow: 2.0.1
+ kind-of: 6.0.3
+
+ semver@6.3.1: {}
+
+ semver@7.6.3: {}
+
+ sharp@0.32.6:
+ dependencies:
+ color: 4.2.3
+ detect-libc: 2.0.3
+ node-addon-api: 6.1.0
+ prebuild-install: 7.1.2
+ semver: 7.6.3
+ simple-get: 4.0.1
+ tar-fs: 3.0.6
+ tunnel-agent: 0.6.0
+
+ sharp@0.33.5:
+ dependencies:
+ color: 4.2.3
+ detect-libc: 2.0.3
+ semver: 7.6.3
+ optionalDependencies:
+ '@img/sharp-darwin-arm64': 0.33.5
+ '@img/sharp-darwin-x64': 0.33.5
+ '@img/sharp-libvips-darwin-arm64': 1.0.4
+ '@img/sharp-libvips-darwin-x64': 1.0.4
+ '@img/sharp-libvips-linux-arm': 1.0.5
+ '@img/sharp-libvips-linux-arm64': 1.0.4
+ '@img/sharp-libvips-linux-s390x': 1.0.4
+ '@img/sharp-libvips-linux-x64': 1.0.4
+ '@img/sharp-libvips-linuxmusl-arm64': 1.0.4
+ '@img/sharp-libvips-linuxmusl-x64': 1.0.4
+ '@img/sharp-linux-arm': 0.33.5
+ '@img/sharp-linux-arm64': 0.33.5
+ '@img/sharp-linux-s390x': 0.33.5
+ '@img/sharp-linux-x64': 0.33.5
+ '@img/sharp-linuxmusl-arm64': 0.33.5
+ '@img/sharp-linuxmusl-x64': 0.33.5
+ '@img/sharp-wasm32': 0.33.5
+ '@img/sharp-win32-ia32': 0.33.5
+ '@img/sharp-win32-x64': 0.33.5
+ optional: true
+
+ shiki@1.17.6:
+ dependencies:
+ '@shikijs/core': 1.17.6
+ '@shikijs/engine-javascript': 1.17.6
+ '@shikijs/engine-oniguruma': 1.17.6
+ '@shikijs/types': 1.17.6
+ '@shikijs/vscode-textmate': 9.2.2
+ '@types/hast': 3.0.4
+
+ signal-exit@4.1.0: {}
+
+ simple-concat@1.0.1: {}
+
+ simple-get@4.0.1:
+ dependencies:
+ decompress-response: 6.0.0
+ once: 1.4.0
+ simple-concat: 1.0.1
+
+ simple-swizzle@0.2.2:
+ dependencies:
+ is-arrayish: 0.3.2
+
+ sisteransi@1.0.5: {}
+
+ sitemap@7.1.2:
+ dependencies:
+ '@types/node': 17.0.45
+ '@types/sax': 1.2.7
+ arg: 5.0.2
+ sax: 1.4.1
+
+ source-map-js@1.2.1: {}
+
+ source-map@0.6.1: {}
+
+ source-map@0.7.4: {}
+
+ space-separated-tokens@2.0.2: {}
+
+ sprintf-js@1.0.3: {}
+
+ stdin-discarder@0.2.2: {}
+
+ stream-replace-string@2.0.0: {}
+
+ streamx@2.20.1:
+ dependencies:
+ fast-fifo: 1.3.2
+ queue-tick: 1.0.1
+ text-decoder: 1.2.0
+ optionalDependencies:
+ bare-events: 2.4.2
+
+ string-width@4.2.3:
+ dependencies:
+ emoji-regex: 8.0.0
+ is-fullwidth-code-point: 3.0.0
+ strip-ansi: 6.0.1
+
+ string-width@5.1.2:
+ dependencies:
+ eastasianwidth: 0.2.0
+ emoji-regex: 9.2.2
+ strip-ansi: 7.1.0
+
+ string-width@7.2.0:
+ dependencies:
+ emoji-regex: 10.4.0
+ get-east-asian-width: 1.2.0
+ strip-ansi: 7.1.0
+
+ string_decoder@1.3.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ stringify-entities@4.0.4:
+ dependencies:
+ character-entities-html4: 2.1.0
+ character-entities-legacy: 3.0.0
+
+ strip-ansi@6.0.1:
+ dependencies:
+ ansi-regex: 5.0.1
+
+ strip-ansi@7.1.0:
+ dependencies:
+ ansi-regex: 6.1.0
+
+ strip-bom-string@1.0.0: {}
+
+ strip-bom@3.0.0: {}
+
+ strip-json-comments@2.0.1: {}
+
+ style-to-object@0.4.4:
+ dependencies:
+ inline-style-parser: 0.1.1
+
+ style-to-object@1.0.8:
+ dependencies:
+ inline-style-parser: 0.2.4
+
+ supports-color@5.5.0:
+ dependencies:
+ has-flag: 3.0.0
+
+ tar-fs@2.1.1:
+ dependencies:
+ chownr: 1.1.4
+ mkdirp-classic: 0.5.3
+ pump: 3.0.2
+ tar-stream: 2.2.0
+
+ tar-fs@3.0.6:
+ dependencies:
+ pump: 3.0.2
+ tar-stream: 3.1.7
+ optionalDependencies:
+ bare-fs: 2.3.5
+ bare-path: 2.1.3
+
+ tar-stream@2.2.0:
+ dependencies:
+ bl: 4.1.0
+ end-of-stream: 1.4.4
+ fs-constants: 1.0.0
+ inherits: 2.0.4
+ readable-stream: 3.6.2
+
+ tar-stream@3.1.7:
+ dependencies:
+ b4a: 1.6.6
+ fast-fifo: 1.3.2
+ streamx: 2.20.1
+
+ text-decoder@1.2.0:
+ dependencies:
+ b4a: 1.6.6
+
+ tiny-invariant@1.3.3: {}
+
+ tinyexec@0.3.0: {}
+
+ to-fast-properties@2.0.0: {}
+
+ to-regex-range@5.0.1:
+ dependencies:
+ is-number: 7.0.0
+
+ trim-lines@3.0.1: {}
+
+ trough@2.2.0: {}
+
+ tsconfck@3.1.3(typescript@5.6.2):
+ optionalDependencies:
+ typescript: 5.6.2
+
+ tslib@2.7.0: {}
+
+ tunnel-agent@0.6.0:
+ dependencies:
+ safe-buffer: 5.2.1
+
+ type-fest@2.19.0: {}
+
+ typesafe-path@0.2.2: {}
+
+ typescript-auto-import-cache@0.3.3:
+ dependencies:
+ semver: 7.6.3
+
+ typescript@5.6.2: {}
+
+ unified@11.0.5:
+ dependencies:
+ '@types/unist': 3.0.3
+ bail: 2.0.2
+ devlop: 1.1.0
+ extend: 3.0.2
+ is-plain-obj: 4.1.0
+ trough: 2.2.0
+ vfile: 6.0.3
+
+ unist-util-find-after@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+
+ unist-util-is@6.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-modify-children@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ array-iterate: 2.0.1
+
+ unist-util-position-from-estree@2.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-remove-position@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-visit: 5.0.0
+
+ unist-util-stringify-position@4.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-children@3.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+
+ unist-util-visit-parents@6.0.1:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+
+ unist-util-visit@5.0.0:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-is: 6.0.0
+ unist-util-visit-parents: 6.0.1
+
+ update-browserslist-db@1.1.0(browserslist@4.23.3):
+ dependencies:
+ browserslist: 4.23.3
+ escalade: 3.2.0
+ picocolors: 1.1.0
+
+ util-deprecate@1.0.2: {}
+
+ vfile-location@5.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile: 6.0.3
+
+ vfile-message@4.0.2:
+ dependencies:
+ '@types/unist': 3.0.3
+ unist-util-stringify-position: 4.0.0
+
+ vfile@6.0.3:
+ dependencies:
+ '@types/unist': 3.0.3
+ vfile-message: 4.0.2
+
+ vite@5.4.5:
+ dependencies:
+ esbuild: 0.21.5
+ postcss: 8.4.45
+ rollup: 4.21.3
+ optionalDependencies:
+ fsevents: 2.3.3
+
+ vitefu@1.0.2(vite@5.4.5):
+ optionalDependencies:
+ vite: 5.4.5
+
+ volar-service-css@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ vscode-css-languageservice: 6.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-emmet@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ '@emmetio/css-parser': 0.4.0
+ '@emmetio/html-matcher': 1.3.0
+ '@vscode/emmet-helper': 2.9.3
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-html@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ vscode-html-languageservice: 5.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-prettier@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-typescript-twoslash-queries@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-typescript@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ path-browserify: 1.0.1
+ semver: 7.6.3
+ typescript-auto-import-cache: 0.3.3
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-nls: 5.2.0
+ vscode-uri: 3.0.8
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ volar-service-yaml@0.0.61(@volar/language-service@2.4.4):
+ dependencies:
+ vscode-uri: 3.0.8
+ yaml-language-server: 1.15.0
+ optionalDependencies:
+ '@volar/language-service': 2.4.4
+
+ vscode-css-languageservice@6.3.1:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.0.8
+
+ vscode-html-languageservice@5.3.1:
+ dependencies:
+ '@vscode/l10n': 0.0.18
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-uri: 3.0.8
+
+ vscode-json-languageservice@4.1.8:
+ dependencies:
+ jsonc-parser: 3.3.1
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-nls: 5.2.0
+ vscode-uri: 3.0.8
+
+ vscode-jsonrpc@6.0.0: {}
+
+ vscode-jsonrpc@8.2.0: {}
+
+ vscode-languageserver-protocol@3.16.0:
+ dependencies:
+ vscode-jsonrpc: 6.0.0
+ vscode-languageserver-types: 3.16.0
+
+ vscode-languageserver-protocol@3.17.5:
+ dependencies:
+ vscode-jsonrpc: 8.2.0
+ vscode-languageserver-types: 3.17.5
+
+ vscode-languageserver-textdocument@1.0.12: {}
+
+ vscode-languageserver-types@3.16.0: {}
+
+ vscode-languageserver-types@3.17.5: {}
+
+ vscode-languageserver@7.0.0:
+ dependencies:
+ vscode-languageserver-protocol: 3.16.0
+
+ vscode-languageserver@9.0.1:
+ dependencies:
+ vscode-languageserver-protocol: 3.17.5
+
+ vscode-nls@5.2.0: {}
+
+ vscode-uri@2.1.2: {}
+
+ vscode-uri@3.0.8: {}
+
+ web-namespaces@2.0.1: {}
+
+ which-pm-runs@1.1.0: {}
+
+ which-pm@3.0.0:
+ dependencies:
+ load-yaml-file: 0.2.0
+
+ widest-line@4.0.1:
+ dependencies:
+ string-width: 5.1.2
+
+ wrap-ansi@7.0.0:
+ dependencies:
+ ansi-styles: 4.3.0
+ string-width: 4.2.3
+ strip-ansi: 6.0.1
+
+ wrap-ansi@8.1.0:
+ dependencies:
+ ansi-styles: 6.2.1
+ string-width: 5.1.2
+ strip-ansi: 7.1.0
+
+ wrappy@1.0.2: {}
+
+ xxhash-wasm@1.0.2: {}
+
+ y18n@5.0.8: {}
+
+ yallist@3.1.1: {}
+
+ yaml-language-server@1.15.0:
+ dependencies:
+ ajv: 8.17.1
+ lodash: 4.17.21
+ request-light: 0.5.8
+ vscode-json-languageservice: 4.1.8
+ vscode-languageserver: 7.0.0
+ vscode-languageserver-textdocument: 1.0.12
+ vscode-languageserver-types: 3.17.5
+ vscode-nls: 5.2.0
+ vscode-uri: 3.0.8
+ yaml: 2.2.2
+ optionalDependencies:
+ prettier: 2.8.7
+
+ yaml@2.2.2: {}
+
+ yaml@2.5.1: {}
+
+ yargs-parser@21.1.1: {}
+
+ yargs@17.7.2:
+ dependencies:
+ cliui: 8.0.1
+ escalade: 3.2.0
+ get-caller-file: 2.0.5
+ require-directory: 2.1.1
+ string-width: 4.2.3
+ y18n: 5.0.8
+ yargs-parser: 21.1.1
+
+ yocto-queue@1.1.1: {}
+
+ zod-to-json-schema@3.23.3(zod@3.23.8):
+ dependencies:
+ zod: 3.23.8
+
+ zod-to-ts@1.2.0(typescript@5.6.2)(zod@3.23.8):
+ dependencies:
+ typescript: 5.6.2
+ zod: 3.23.8
+
+ zod@3.23.8: {}
+
+ zwitch@2.0.4: {}
diff --git a/public/CNAME b/public/CNAME
new file mode 100644
index 000000000..8005f2314
--- /dev/null
+++ b/public/CNAME
@@ -0,0 +1 @@
+gin-gonic.com
\ No newline at end of file
diff --git a/static/comment.js b/public/comment.js
similarity index 100%
rename from static/comment.js
rename to public/comment.js
diff --git a/static/favicons/favicon.ico b/public/favicon.ico
similarity index 100%
rename from static/favicons/favicon.ico
rename to public/favicon.ico
diff --git a/static/favicons/android-chrome-192x192.png b/public/favicons/android-chrome-192x192.png
similarity index 100%
rename from static/favicons/android-chrome-192x192.png
rename to public/favicons/android-chrome-192x192.png
diff --git a/static/favicons/android-chrome-512x512.png b/public/favicons/android-chrome-512x512.png
similarity index 100%
rename from static/favicons/android-chrome-512x512.png
rename to public/favicons/android-chrome-512x512.png
diff --git a/static/favicons/apple-touch-icon.png b/public/favicons/apple-touch-icon.png
similarity index 100%
rename from static/favicons/apple-touch-icon.png
rename to public/favicons/apple-touch-icon.png
diff --git a/static/favicons/browserconfig.xml b/public/favicons/browserconfig.xml
similarity index 100%
rename from static/favicons/browserconfig.xml
rename to public/favicons/browserconfig.xml
diff --git a/static/favicons/favicon-16x16.png b/public/favicons/favicon-16x16.png
similarity index 100%
rename from static/favicons/favicon-16x16.png
rename to public/favicons/favicon-16x16.png
diff --git a/static/favicons/favicon-32x32.png b/public/favicons/favicon-32x32.png
similarity index 100%
rename from static/favicons/favicon-32x32.png
rename to public/favicons/favicon-32x32.png
diff --git a/public/favicons/favicon.ico b/public/favicons/favicon.ico
new file mode 100644
index 000000000..6e8ab1f8f
Binary files /dev/null and b/public/favicons/favicon.ico differ
diff --git a/static/favicons/mstile-150x150.png b/public/favicons/mstile-150x150.png
similarity index 100%
rename from static/favicons/mstile-150x150.png
rename to public/favicons/mstile-150x150.png
diff --git a/static/favicons/safari-pinned-tab.svg b/public/favicons/safari-pinned-tab.svg
similarity index 100%
rename from static/favicons/safari-pinned-tab.svg
rename to public/favicons/safari-pinned-tab.svg
diff --git a/static/favicons/site.webmanifest b/public/favicons/site.webmanifest
similarity index 100%
rename from static/favicons/site.webmanifest
rename to public/favicons/site.webmanifest
diff --git a/public/go.mod b/public/go.mod
new file mode 100644
index 000000000..0e69b2a75
--- /dev/null
+++ b/public/go.mod
@@ -0,0 +1,9 @@
+module github.com/gin-gonic/website
+
+go 1.22.2
+
+require (
+ github.com/google/docsy v0.9.2-0.20240426161215-e9eca0fcb3b5 // indirect
+ github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7 // indirect
+ github.com/twbs/bootstrap v5.3.3+incompatible // indirect
+)
diff --git a/public/go.sum b/public/go.sum
new file mode 100644
index 000000000..9b580b446
--- /dev/null
+++ b/public/go.sum
@@ -0,0 +1,12 @@
+github.com/FortAwesome/Font-Awesome v0.0.0-20240108205627-a1232e345536/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7 h1:2aWEKCRLqQ9nPyXaz4/IYtRrDr3PzEiX0DUSUr2/EDs=
+github.com/FortAwesome/Font-Awesome v0.0.0-20240402185447-c0f460dca7f7/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/FortAwesome/Font-Awesome v4.7.0+incompatible h1:3trjm7NtX5NXlju1AxSWSzedDMq2hsfH78Qtqrc8EgY=
+github.com/FortAwesome/Font-Awesome v4.7.0+incompatible/go.mod h1:IUgezN/MFpCDIlFezw3L8j83oeiIuYoj28Miwr/KUYo=
+github.com/google/docsy v0.9.1 h1:+jqges1YCd+yHeuZ1BUvD8V8mEGVtPxULg5j/vaJ984=
+github.com/google/docsy v0.9.1/go.mod h1:saOqKEUOn07Bc0orM/JdIF3VkOanHta9LU5Y53bwN2U=
+github.com/google/docsy v0.9.2-0.20240426161215-e9eca0fcb3b5 h1:EDs9FRTZ75agHdnMeO3HjfqJV10jKpdsM6XEARy/FsM=
+github.com/google/docsy v0.9.2-0.20240426161215-e9eca0fcb3b5/go.mod h1:c0nIAqmRTOuJ01F85U/wJPQtc3Zj9N58Kea9bOT2AJc=
+github.com/twbs/bootstrap v5.2.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
+github.com/twbs/bootstrap v5.3.3+incompatible h1:goFoqinzdHfkeegpFP7pvhbd0g+A3O2hbU3XCjuNrEQ=
+github.com/twbs/bootstrap v5.3.3+incompatible/go.mod h1:fZTSrkpSf0/HkL0IIJzvVspTt1r9zuf7XlZau8kpcY0=
diff --git a/src/assets/gin.png b/src/assets/gin.png
new file mode 100644
index 000000000..df3999718
Binary files /dev/null and b/src/assets/gin.png differ
diff --git a/src/content/config.ts b/src/content/config.ts
new file mode 100644
index 000000000..45f60b015
--- /dev/null
+++ b/src/content/config.ts
@@ -0,0 +1,6 @@
+import { defineCollection } from 'astro:content';
+import { docsSchema } from '@astrojs/starlight/schema';
+
+export const collections = {
+ docs: defineCollection({ schema: docsSchema() }),
+};
diff --git a/src/content/docs/en/blog/index.md b/src/content/docs/en/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/en/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/en/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/en/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/en/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/en/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/en/blog/releases/release13.md b/src/content/docs/en/blog/releases/release13.md
similarity index 100%
rename from content/en/blog/releases/release13.md
rename to src/content/docs/en/blog/releases/release13.md
diff --git a/content/en/blog/releases/release14.md b/src/content/docs/en/blog/releases/release14.md
similarity index 100%
rename from content/en/blog/releases/release14.md
rename to src/content/docs/en/blog/releases/release14.md
diff --git a/content/en/blog/releases/release15.md b/src/content/docs/en/blog/releases/release15.md
similarity index 100%
rename from content/en/blog/releases/release15.md
rename to src/content/docs/en/blog/releases/release15.md
diff --git a/content/en/blog/releases/release16.md b/src/content/docs/en/blog/releases/release16.md
similarity index 100%
rename from content/en/blog/releases/release16.md
rename to src/content/docs/en/blog/releases/release16.md
diff --git a/src/content/docs/en/docs/benchmarks/index.md b/src/content/docs/en/docs/benchmarks/index.md
new file mode 100644
index 000000000..3f4ae2915
--- /dev/null
+++ b/src/content/docs/en/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "Benchmarks"
+
+sidebar:
+ order: 3
+---
+
+Gin uses a custom version of [HttpRouter](https://github.com/julienschmidt/httprouter)
+
+[See all benchmarks](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): Total Repetitions achieved in constant time, higher means more confident result
+- (2): Single Repetition Duration (ns/op), lower is better
+- (3): Heap Memory (B/op), lower is better
+- (4): Average Allocations per Repetition (allocs/op), lower is better
diff --git a/src/content/docs/en/docs/deployment/index.md b/src/content/docs/en/docs/deployment/index.md
new file mode 100644
index 000000000..334b01805
--- /dev/null
+++ b/src/content/docs/en/docs/deployment/index.md
@@ -0,0 +1,32 @@
+---
+title: "Deployment"
+
+sidebar:
+ order: 6
+---
+
+Gin projects can be deployed easily on any cloud provider.
+
+## [Koyeb](https://www.koyeb.com)
+
+Koyeb is a developer-friendly serverless platform to deploy apps globally with git-based deployment, TLS encryption, native autoscaling, a global edge network, and built-in service mesh & discovery.
+
+Follow the Koyeb [guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
+
+## [Qovery](https://www.qovery.com)
+
+Qovery provides free Cloud hosting with databases, SSL, a global CDN, and automatic deploys with Git.
+
+Follow the Qovery guide to [deploy your Gin project](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
+
+## [Render](https://render.com)
+
+Render is a modern cloud platform that offers native support for Go, fully managed SSL, databases, zero-downtime deploys, HTTP/2, and websocket support.
+
+Follow the Render [guide to deploying Gin projects](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE has two ways to deploy Go applications. The standard environment is easier to use but less customizable and prevents [syscalls](https://github.com/gin-gonic/gin/issues/1639) for security reasons. The flexible environment can run any framework or library.
+
+Learn more and pick your preferred environment at [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/en/docs/examples/ascii-json.md b/src/content/docs/en/docs/examples/ascii-json.md
new file mode 100644
index 000000000..7e2d2b0d0
--- /dev/null
+++ b/src/content/docs/en/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/en/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..138179eea
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Try to bind body into different structs"
+
+---
+
+The normal methods for binding request body consumes `c.Request.Body` and they
+cannot be called multiple times.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Always an error is occurred by this because c.Request.Body is EOF now.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This reads c.Request.Body and stores the result into the context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // At this time, it reuses body stored in the context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // And it can accepts other formats
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` stores body into the context before binding. This has
+a slight impact to performance, so you should not use this method if you are
+enough to call binding at once.
+* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
+can be called by `c.ShouldBind()` multiple times without any damage to
+performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/en/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/en/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..92ab2f4b8
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "Bind form-data request with custom struct"
+
+---
+
+The follow example using custom struct:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Using the command `curl` command result:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/en/docs/examples/bind-html-checkbox.md b/src/content/docs/en/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..4b1ee65ef
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Bind html checkboxes"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+result:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/en/docs/examples/bind-query-or-post.md b/src/content/docs/en/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..9912d908a
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "Bind query string or post data"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // If `GET`, only `Form` binding engine (`query`) used.
+ // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
+ // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Test it with:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/en/docs/examples/bind-single-binary-with-template.md b/src/content/docs/en/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..09e8b02fc
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,45 @@
+---
+title: "Build a single binary with templates"
+
+---
+## Use the third-party package
+
+You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/src/content/docs/en/docs/examples/bind-uri.md b/src/content/docs/en/docs/examples/bind-uri.md
new file mode 100644
index 000000000..4c74abfab
--- /dev/null
+++ b/src/content/docs/en/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Bind Uri"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err.Error()})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Test it with:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/en/docs/examples/binding-and-validation.md b/src/content/docs/en/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..40684022c
--- /dev/null
+++ b/src/content/docs/en/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Model binding and validation"
+
+---
+
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
+
+Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
+
+Also, Gin provides two sets of methods for binding:
+- **Type** - Must bind
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
+- **Type** - Should bind
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
+
+When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
+
+You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
+
+```go
+// Binding from JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Example for binding JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding a HTML form (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // This will infer what binder to use depending on the content-type header.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Sample request
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Skip validate
+
+When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/src/content/docs/en/docs/examples/controlling-log-output-coloring.md b/src/content/docs/en/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..c0973a85a
--- /dev/null
+++ b/src/content/docs/en/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Controlling Log output coloring"
+
+---
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/cookie.md b/src/content/docs/en/docs/examples/cookie.md
new file mode 100644
index 000000000..090e66354
--- /dev/null
+++ b/src/content/docs/en/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Set and get a cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/en/docs/examples/custom-http-config.md b/src/content/docs/en/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..42de78314
--- /dev/null
+++ b/src/content/docs/en/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "Custom HTTP configuration"
+
+---
+
+Use `http.ListenAndServe()` directly, like this:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/en/docs/examples/custom-log-format.md b/src/content/docs/en/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..6d6450341
--- /dev/null
+++ b/src/content/docs/en/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "Custom log file"
+
+---
+
+For example:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Sample Output**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/en/docs/examples/custom-middleware.md b/src/content/docs/en/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..8de8438b0
--- /dev/null
+++ b/src/content/docs/en/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Custom Middleware"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Set example variable
+ c.Set("example", "12345")
+
+ // before request
+
+ c.Next()
+
+ // after request
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // access the status we are sending
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // it would print: "12345"
+ log.Println(example)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/custom-validators.md b/src/content/docs/en/docs/examples/custom-validators.md
new file mode 100644
index 000000000..114de29af
--- /dev/null
+++ b/src/content/docs/en/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Custom validators"
+
+---
+
+It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking contains binded and validated data.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
+See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/src/content/docs/en/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/en/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..44bd991a9
--- /dev/null
+++ b/src/content/docs/en/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "Define format for the log of routes"
+
+---
+
+The default log of routes is:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
+In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/en/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/en/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..f3a6b10d6
--- /dev/null
+++ b/src/content/docs/en/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Goroutines inside a middleware"
+
+---
+
+When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // create copy to be used inside the goroutine
+ cCp := c.Copy()
+ go func() {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // note that you are using the copied context "cCp", IMPORTANT
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // since we are NOT using a goroutine, we do not have to copy the context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/graceful-restart-or-stop.md b/src/content/docs/en/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..26e6a67bc
--- /dev/null
+++ b/src/content/docs/en/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,85 @@
+---
+title: "Graceful restart or stop"
+
+---
+
+Do you want to graceful restart or stop your web server?
+There are some ways this can be done.
+
+We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+An alternative to endless:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router.Handler(),
+ }
+
+ go func() {
+ // service connections
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Wait for interrupt signal to gracefully shutdown the server with
+ // a timeout of 5 seconds.
+ quit := make(chan os.Signal, 1)
+ // kill (no param) default send syscall.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // catching ctx.Done(). timeout of 5 seconds.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/grouping-routes.md b/src/content/docs/en/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..c7f7a7245
--- /dev/null
+++ b/src/content/docs/en/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Grouping routes"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Simple group: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Simple group: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/html-rendering.md b/src/content/docs/en/docs/examples/html-rendering.md
new file mode 100644
index 000000000..787248795
--- /dev/null
+++ b/src/content/docs/en/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML rendering"
+
+---
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Using templates with same name in different directories
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Custom Template renderer
+
+You can also use your own html template render
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Custom Delimiters
+
+You may use custom delims
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Custom Template Funcs
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/en/docs/examples/http-method.md b/src/content/docs/en/docs/examples/http-method.md
new file mode 100644
index 000000000..b8d41d696
--- /dev/null
+++ b/src/content/docs/en/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Using HTTP method"
+
+---
+
+```go
+func main() {
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // By default it serves on :8080 unless a
+ // PORT environment variable was defined.
+ router.Run()
+ // router.Run(":3000") for a hard coded port
+}
+```
diff --git a/src/content/docs/en/docs/examples/http2-server-push.md b/src/content/docs/en/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..79dc31a7d
--- /dev/null
+++ b/src/content/docs/en/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+
+---
+
+http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // use pusher.Push() to do server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Listen and Serve in https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/index.md b/src/content/docs/en/docs/examples/index.md
new file mode 100644
index 000000000..8ad0c0828
--- /dev/null
+++ b/src/content/docs/en/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "Examples"
+
+sidebar:
+ order: 6
+---
+
+The section lists api usage.
diff --git a/src/content/docs/en/docs/examples/jsonp.md b/src/content/docs/en/docs/examples/jsonp.md
new file mode 100644
index 000000000..bc4439a44
--- /dev/null
+++ b/src/content/docs/en/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback is x
+ // Will output : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/en/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..5ed88b0b5
--- /dev/null
+++ b/src/content/docs/en/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Map as querystring or postform parameters"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/en/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/en/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..73fee286a
--- /dev/null
+++ b/src/content/docs/en/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded binding"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // you can bind multipart form with explicit binding declaration:
+ // c.ShouldBindWith(&form, binding.Form)
+ // or you can simply use autobinding with ShouldBind method:
+ var form LoginForm
+ // in this case proper binding will be automatically selected
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Test it with:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/en/docs/examples/multipart-urlencoded-form.md b/src/content/docs/en/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..04eab2373
--- /dev/null
+++ b/src/content/docs/en/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded form"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/multiple-template.md b/src/content/docs/en/docs/examples/multiple-template.md
new file mode 100644
index 000000000..28b58c213
--- /dev/null
+++ b/src/content/docs/en/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Multitemplate"
+
+---
+
+Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/src/content/docs/en/docs/examples/only-bind-query-string.md b/src/content/docs/en/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..bdd6c174e
--- /dev/null
+++ b/src/content/docs/en/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Only bind query string"
+
+---
+
+`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/en/docs/examples/param-in-path.md b/src/content/docs/en/docs/examples/param-in-path.md
new file mode 100644
index 000000000..b0a4a3b68
--- /dev/null
+++ b/src/content/docs/en/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Parameters in path"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // This handler will match /user/john but will not match /user/ or /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // However, this one will match /user/john/ and also /user/john/send
+ // If no other routers match /user/john, it will redirect to /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/pure-json.md b/src/content/docs/en/docs/examples/pure-json.md
new file mode 100644
index 000000000..5fbf8bfc1
--- /dev/null
+++ b/src/content/docs/en/docs/examples/pure-json.md
@@ -0,0 +1,30 @@
+---
+title: "PureJSON"
+
+---
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/query-and-post-form.md b/src/content/docs/en/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..5c8e6d21e
--- /dev/null
+++ b/src/content/docs/en/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Query and post form"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/en/docs/examples/querystring-param.md b/src/content/docs/en/docs/examples/querystring-param.md
new file mode 100644
index 000000000..cba891746
--- /dev/null
+++ b/src/content/docs/en/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Query string parameters"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Query string parameters are parsed using the existing underlying request object.
+ // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/redirects.md b/src/content/docs/en/docs/examples/redirects.md
new file mode 100644
index 000000000..e62a9952e
--- /dev/null
+++ b/src/content/docs/en/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirects"
+
+---
+
+Issuing a HTTP redirect is easy. Both internal and external locations are supported.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Issuing a Router redirect, use `HandleContext` like below.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/en/docs/examples/rendering.md b/src/content/docs/en/docs/examples/rendering.md
new file mode 100644
index 000000000..c9c705c65
--- /dev/null
+++ b/src/content/docs/en/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf rendering"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H is a shortcut for map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // You also can use a struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Note that msg.Name becomes "user" in the JSON
+ // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/run-multiple-service.md b/src/content/docs/en/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..0dba2ab95
--- /dev/null
+++ b/src/content/docs/en/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Run multiple service"
+
+---
+
+See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/secure-json.md b/src/content/docs/en/docs/examples/secure-json.md
new file mode 100644
index 000000000..82e63a4c4
--- /dev/null
+++ b/src/content/docs/en/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // You can also use your own secure json prefix
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Will output : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/security-headers.md b/src/content/docs/en/docs/examples/security-headers.md
new file mode 100644
index 000000000..9fa537894
--- /dev/null
+++ b/src/content/docs/en/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "Security Headers"
+
+---
+
+It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection).
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+You can test it via `curl`:
+
+```bash
+// Check Headers
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// Check Host Header Injection
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/en/docs/examples/serving-data-from-reader.md b/src/content/docs/en/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..614db12ce
--- /dev/null
+++ b/src/content/docs/en/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Serving data from reader"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/serving-static-files.md b/src/content/docs/en/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..bda67da07
--- /dev/null
+++ b/src/content/docs/en/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Serving static files"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/support-lets-encrypt.md b/src/content/docs/en/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..841c1a7f9
--- /dev/null
+++ b/src/content/docs/en/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Support Let's Encrypt"
+
+---
+
+example for 1-line LetsEncrypt HTTPS servers.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+example for custom autocert manager.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/upload-file/index.md b/src/content/docs/en/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..d0ff99e85
--- /dev/null
+++ b/src/content/docs/en/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Upload files"
+
+---
+
+The section lists upload file api usage.
diff --git a/src/content/docs/en/docs/examples/upload-file/multiple-file.md b/src/content/docs/en/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..185b7b5f6
--- /dev/null
+++ b/src/content/docs/en/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Multiple files"
+
+---
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/en/docs/examples/upload-file/single-file.md b/src/content/docs/en/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..5fe274dc7
--- /dev/null
+++ b/src/content/docs/en/docs/examples/upload-file/single-file.md
@@ -0,0 +1,37 @@
+---
+title: "Single file"
+
+---
+
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // single file
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/en/docs/examples/using-basicauth-middleware.md b/src/content/docs/en/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..cc68db4a0
--- /dev/null
+++ b/src/content/docs/en/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Using BasicAuth middleware"
+
+---
+
+```go
+// simulate some private data
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Group using gin.BasicAuth() middleware
+ // gin.Accounts is a shortcut for map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets endpoint
+ // hit "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // get user, it was set by the BasicAuth middleware
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/examples/using-middleware.md b/src/content/docs/en/docs/examples/using-middleware.md
new file mode 100644
index 000000000..5fc4154db
--- /dev/null
+++ b/src/content/docs/en/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Using middleware"
+
+---
+
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.Recovery())
+
+ // Per route middleware, you can add as many as you desire.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Authorization group
+ // authorized := r.Group("/", AuthRequired())
+ // exactly the same as:
+ authorized := r.Group("/")
+ // per group middleware! in this case we use the custom created
+ // AuthRequired() middleware just in the "authorized" group.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // nested group
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/en/docs/examples/without-middleware.md b/src/content/docs/en/docs/examples/without-middleware.md
new file mode 100644
index 000000000..6ef54bda0
--- /dev/null
+++ b/src/content/docs/en/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Without middleware by default"
+
+---
+
+Use
+
+```go
+r := gin.New()
+```
+
+instead of
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
diff --git a/src/content/docs/en/docs/examples/write-log.md b/src/content/docs/en/docs/examples/write-log.md
new file mode 100644
index 000000000..759423de4
--- /dev/null
+++ b/src/content/docs/en/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "How to write log file"
+
+---
+
+```go
+func main() {
+ // Disable Console Color, you don't need console color when writing the logs to file.
+ gin.DisableConsoleColor()
+
+ // Logging to a file.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Use the following code if you need to write the logs to file and console at the same time.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/en/docs/faq/index.md b/src/content/docs/en/docs/faq/index.md
new file mode 100644
index 000000000..ad348f11f
--- /dev/null
+++ b/src/content/docs/en/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: record some frequently asked question from GitHub Issue tab.
+
diff --git a/src/content/docs/en/docs/features/index.md b/src/content/docs/en/docs/features/index.md
new file mode 100644
index 000000000..862f6a687
--- /dev/null
+++ b/src/content/docs/en/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "Features"
+
+sidebar:
+ order: 4
+---
+
+## Gin v1 stable features:
+
+- Zero allocation router.
+
+- Still the fastest http router and framework. From routing to writing.
+
+- Complete suite of unit tests.
+
+- Battle tested.
+
+- API frozen, new releases will not break your code.
diff --git a/src/content/docs/en/docs/index.md b/src/content/docs/en/docs/index.md
new file mode 100644
index 000000000..ebd9854a1
--- /dev/null
+++ b/src/content/docs/en/docs/index.md
@@ -0,0 +1,22 @@
+---
+title: "Documentation"
+linkTitle: "Documentation"
+sidebar:
+ order: 1
+---
+
+## What is Gin?
+
+Gin is a HTTP web framework written in Go (Golang). It features a Martini-like API, but with performance up to 40 times faster than Martini. If you need smashing performance, get yourself some Gin.
+
+## How to use Gin?
+
+We provide API usage [examples](https://github.com/gin-gonic/examples) and list some publicly known [Gin users](./users).
+
+## How to contribute to Gin?
+
+* Help people on the discussion forums
+* Tell us your success stories using Gin
+* Tell us how we can improve Gin and help us do it
+* Contribute to an existing library
+
diff --git a/src/content/docs/en/docs/introduction/index.md b/src/content/docs/en/docs/introduction/index.md
new file mode 100644
index 000000000..cc36bab4b
--- /dev/null
+++ b/src/content/docs/en/docs/introduction/index.md
@@ -0,0 +1,48 @@
+---
+title: "Introduction"
+
+sidebar:
+ order: 1
+---
+
+Gin is a web framework written in Go (Golang). It features a martini-like API with much better performance, up to 40 times faster thanks to [httprouter](https://github.com/julienschmidt/httprouter). If you need performance and good productivity, you will love Gin.
+
+In this section we will walk through what Gin is, what problems it solves, and how it can help your project.
+
+Or, if you are ready to use Gin in to your project, visit the [Quickstart](https://gin-gonic.com/docs/quickstart/).
+
+## Features
+
+### Fast
+
+Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
+
+### Middleware support
+
+An incoming HTTP request can be handled by a chain of middlewares and the final action.
+For example: Logger, Authorization, GZIP and finally post a message in the DB.
+
+### Crash-free
+
+Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. As an example - it’s also possible to report this panic to Sentry!
+
+### JSON validation
+
+Gin can parse and validate the JSON of a request - for example, checking the existence of required values.
+
+### Routes grouping
+
+Organize your routes better. Authorization required vs non required, different API versions... In addition, the groups can be nested unlimitedly without degrading performance.
+
+### Error management
+
+Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, a middleware can write them to a log file, to a database and send them through the network.
+
+### Rendering built-in
+
+Gin provides an easy to use API for JSON, XML and HTML rendering.
+
+### Extendable
+
+Creating a new middleware is so easy, just check out the sample codes.
+
diff --git a/src/content/docs/en/docs/jsoniter/index.md b/src/content/docs/en/docs/jsoniter/index.md
new file mode 100644
index 000000000..e06c641be
--- /dev/null
+++ b/src/content/docs/en/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## Build with [jsoniter](https://github.com/json-iterator/go)
+
+Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/en/docs/quickstart/index.md b/src/content/docs/en/docs/quickstart/index.md
new file mode 100644
index 000000000..714579157
--- /dev/null
+++ b/src/content/docs/en/docs/quickstart/index.md
@@ -0,0 +1,92 @@
+---
+title: "Quickstart"
+
+sidebar:
+ order: 2
+---
+
+In this quickstart, we’ll glean insights from code segments and learn how to:
+
+## Requirements
+
+- Go 1.16 or above
+
+## Installation
+
+To install Gin package, you need to install Go and set your Go workspace first.
+
+1. Download and install it:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+Or install:
+```sh
+$ go install github.com/gin-gonic/gin@latest
+```
+
+2. Import it in your code:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (Optional) Import `net/http`. This is required for example if using constants such as `http.StatusOK`.
+
+```go
+import "net/http"
+```
+
+1. Create your project folder and `cd` inside
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. Copy a starting template inside your project
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. Run your project
+
+```sh
+$ go run main.go
+```
+
+## Getting Started
+
+> Unsure how to write and execute Go code? [Click here](https://golang.org/doc/code.html).
+
+First, create a file called `example.go`:
+
+```sh
+# assume the following codes in example.go file
+$ touch example.go
+```
+
+Next, put the following code inside of `example.go`:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+And, You can run the code via `go run example.go`:
+
+```sh
+# run example.go and visit 0.0.0.0:8080/ping on browser
+$ go run example.go
+```
diff --git a/src/content/docs/en/docs/testing/index.md b/src/content/docs/en/docs/testing/index.md
new file mode 100644
index 000000000..afd8c7f3e
--- /dev/null
+++ b/src/content/docs/en/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "Testing"
+
+sidebar:
+ order: 7
+---
+
+## How to write test case for Gin?
+
+The `net/http/httptest` package is preferable way for HTTP testing.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+Test for code example above:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/en/docs/users/index.md b/src/content/docs/en/docs/users/index.md
new file mode 100644
index 000000000..4b3e43ce0
--- /dev/null
+++ b/src/content/docs/en/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Users"
+
+sidebar:
+ order: 8
+---
+
+##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
+
+* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
+
+* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+
+* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+
+* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
+
+* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
+
+* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/src/content/docs/en/index.mdx b/src/content/docs/en/index.mdx
new file mode 100644
index 000000000..607eddb38
--- /dev/null
+++ b/src/content/docs/en/index.mdx
@@ -0,0 +1,50 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: The fastest full-featured web framework for Go. Crystal clear.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Read the docs
+ link: /en/docs/
+ icon: right-arrow
+ - text: Download
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## What is Gin?
+
+Gin is a web framework written in Golang. It features a Martini-like API, but with performance up to 40 times faster than Martini. If you need performance and productivity, you will love Gin.
+
+
+
+ Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
+
+
+ An incoming HTTP request can be handled by a chain of middleware and the final action. For example: Logger, Authorization, GZIP and finally post a message in the DB.
+
+
+ Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
+
+
+ Gin can parse and validate the JSON of a request, checking, for example, the existence of required values.
+
+
+ Organize your routes better. Authorization required vs non required, different API versions. In addition, groups can be nested infinitely without degrading performance.
+
+
+ Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, middleware can write them to a log file, to a database and send them through the network.
+
+
+ Gin provides an easy to use API for JSON, XML and HTML rendering.
+
+
+ Creating new middleware is so easy, just check out the sample code.
+
+
\ No newline at end of file
diff --git a/src/content/docs/es/blog/index.md b/src/content/docs/es/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/es/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/es/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/es/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/es/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/es/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/es/blog/releases/release13.md b/src/content/docs/es/blog/releases/release13.md
similarity index 100%
rename from content/es/blog/releases/release13.md
rename to src/content/docs/es/blog/releases/release13.md
diff --git a/content/es/blog/releases/release14.md b/src/content/docs/es/blog/releases/release14.md
similarity index 100%
rename from content/es/blog/releases/release14.md
rename to src/content/docs/es/blog/releases/release14.md
diff --git a/content/es/blog/releases/release15.md b/src/content/docs/es/blog/releases/release15.md
similarity index 100%
rename from content/es/blog/releases/release15.md
rename to src/content/docs/es/blog/releases/release15.md
diff --git a/content/es/blog/releases/release16.md b/src/content/docs/es/blog/releases/release16.md
similarity index 100%
rename from content/es/blog/releases/release16.md
rename to src/content/docs/es/blog/releases/release16.md
diff --git a/src/content/docs/es/docs/benchmarks/index.md b/src/content/docs/es/docs/benchmarks/index.md
new file mode 100644
index 000000000..73cceab90
--- /dev/null
+++ b/src/content/docs/es/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "Benchmarks"
+
+sidebar:
+ order: 3
+---
+
+Gin usa una versión personalizada de [HttpRouter](https://github.com/julienschmidt/httprouter)
+
+[Ver todos los benchmarks](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): Repeticiones totales logradas en tiempo constante, a mayor valor el resultado es mejor
+- (2): Duración de repetición única (ns/op), el valor menor es mejor
+- (3): Memoria del heap (B/op), el valor menor es mejor
+- (4): Asignaciones promedio por repetición (allocs/op), el valor menor es mejor
diff --git a/src/content/docs/es/docs/deployment/index.md b/src/content/docs/es/docs/deployment/index.md
new file mode 100644
index 000000000..40135b23e
--- /dev/null
+++ b/src/content/docs/es/docs/deployment/index.md
@@ -0,0 +1,20 @@
+---
+title: "Despliegue"
+
+sidebar:
+ order: 6
+---
+
+Los proyectos en Gin pueden ser desplegados fácilmente en cualquier proveedor en la nube.
+
+## [Render](https://render.com)
+
+Render es una plataforma moderna en la nube que ofrece soporte nativo para Go, SSL totalmente administrado, bases de datos, despliegues con disponibilidad ininterrumpida, HTTP/2 y soporte websockets.
+
+Sigue la [guía para desplegar proyectos Gin en Render](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+Google App Engine tiene dos formas de implementar aplicaciones Go. El entorno estándar es más fácil de usar, pero menos personalizable y evita [llamadas al sistema](https://github.com/gin-gonic/gin/issues/1639) por razones de seguridad. El entorno flexible puede ejecutar cualquier framework o librería.
+
+Conoce más información y elije el entorno preferido en [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/es/docs/examples/ascii-json.md b/src/content/docs/es/docs/examples/ascii-json.md
new file mode 100644
index 000000000..89bd3f832
--- /dev/null
+++ b/src/content/docs/es/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Uso de AsciiJSON para generar respuestas JSON únicamente con caracteres ASCII y escape de caracteres no-ASCII.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // retornará : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/es/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..028b3282e
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Vincular el cuerpo de un request en distintos tipos de structs"
+
+---
+
+El método común para vincular el cuerpo de un request emplea `c.Request.Body` pero presenta
+el limitante que no puede llamarse múltiples veces.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // c.ShouldBind consume c.Request.Body y no puede volverse a usar.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // La condición de error siempre se cumplirá aquí porque c.Request.Body retornará EOF.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // Aquí se lee c.Request.Body y el resultado es almacenado en context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Esta vez, se reúsa el body almacenado en el context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // También puede aceptar otros formatos
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` almacena el cuerpo en el context antes de hacer el vínculo. Esto tiene
+un ligero impacto en el rendimiento, así que no deberías usar este método si
+no es necesario vincular más de un tipo de struct a la vez.
+* Esta característica sólamente es necesaria en algunos formatos -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. Para otros tipos, `Query`, `Form`, `FormPost`, `FormMultipart`,
+puede ser llamada a través de `c.ShouldBind()` sin impacto negativo
+en el rendimiento (Véase [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/es/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/es/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..aa68ca52b
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,76 @@
+---
+title: "Vincular una petición form-data con un struct personalizado"
+
+---
+
+El siguiente es el ejemplo para un struct personalizado:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Empleando el comando `curl` las respuestas serían:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
diff --git a/src/content/docs/es/docs/examples/bind-html-checkbox.md b/src/content/docs/es/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..2b0acfb01
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Vincular checkboxes html"
+
+---
+
+Revise la [información detallada](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+resultado:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/es/docs/examples/bind-query-or-post.md b/src/content/docs/es/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..aa4c29454
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "Vincular parámetros get o data Post"
+
+---
+
+Revise la [información detallada](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // Si se usa `GET`, únicamente es empleado el `Form` binding engine (`query`).
+ // Si se emplea `POST`, se revisa primero el `content-type` para `JSON` o `XML`, para así usar entonces `Form` (`form-data`).
+ // Véase más en https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Puede probar con:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/es/docs/examples/bind-single-binary-with-template.md b/src/content/docs/es/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..fa2b0c7db
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,44 @@
+---
+title: "Crear un ejecutable individual con templates"
+
+---
+
+Puede crear un servidor en un solo binario que contenga templates usando [go-assets](https://github.com/jessevdk/go-assets).
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate carga templates incrustadas por medio de go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+Puede ver un ejemplo completo en el directorio [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/src/content/docs/es/docs/examples/bind-uri.md b/src/content/docs/es/docs/examples/bind-uri.md
new file mode 100644
index 000000000..5d99350b4
--- /dev/null
+++ b/src/content/docs/es/docs/examples/bind-uri.md
@@ -0,0 +1,36 @@
+---
+title: "Vincular un Uri"
+
+---
+
+Revise la [información detallada](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Se puede probar utilizando:
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/es/docs/examples/binding-and-validation.md b/src/content/docs/es/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..91bdc00de
--- /dev/null
+++ b/src/content/docs/es/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Vincular y validar un Modelo"
+
+---
+
+Para vincular el cuerpo de un request en un tipo, puede hacerse el vínculo a un modelo. Actualmente se soporta el vínculo a JSON, XML, YAML y valores estandar para formularios (foo=bar&boo=baz).
+
+Gin emplea para realizar validación el paquete [**go-playground/validator/v10**](https://github.com/go-playground/validator). Puedes revisar la documentación completa de validación por medio de tags [aquí](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Es necesario establecer el tag correspondiente en todos los campos que se desea vincular. Por ejemplo, cuando se vinculan datos de JSON debe definirse el tag `json:"fieldname"`.
+
+Adicionalmente, Gin dispone de dos conjunto de métodos para vincular:
+- **Tipo** - Must bind (Vínculo obligatorio)
+ - **Métodos** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Comportamiento** - Estos métodos emplean internamente `MustBindWith`. Si ocurre un error al vincularse, la petición se aborta con `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. Esto configura el estatus de la respuesta 400 y el header `Content-Type` se establece en `text/plain; charset=utf-8`. Nótese que si se intenta establecer otro tipo de códgio de respuesta posteriormente, provocará la generación de una advertencia `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. Para un control más personalizado de este comportamiento, puede emplearse el método equivalente `ShouldBind`.
+- **Tipo** - Should bind (Vínculo no obligatorio)
+ - **Métodos** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Comportamiento** - Estos métodos implementan `ShouldBindWith` internamente. Si ocurre un error al vincularse, el error es retornado y queda a juicio del desarrollador la forma apropiada de manejar la petición y el error ocurrido.
+
+Cuando se usa el método de vínculo, Gin tratará de inferir dependiendo del valor del header Content-Type. Si se cuenta con total certeza del tipo de dato a vincular ,puede usarse `MustBindWith` ó `ShouldBindWith`.
+
+También pueden declararse los campos como requeridos. Si un campo tiene declarado el tag `binding:"required"` y el valor viene vacío devolverá un error al tratar de vincularse.
+
+```go
+// Vincular empleando JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Ejemplo para vincular JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Vincular empleando XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Ejemplo para vincular un formulario HTML (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // De esta forma se intenta vincular tratando a partir del valor del header content-type.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Petición de ejemplo
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Evitar la validación
+
+Al ejecutar el el ejemplo de arriba con el comando `curl` devuelve error a causa del tag `binding:"required"` para el campo `Password`. El error deja de aparecer si se remplaza por el tag `binding:"-"`.
diff --git a/src/content/docs/es/docs/examples/controlling-log-output-coloring.md b/src/content/docs/es/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..f62e9bb13
--- /dev/null
+++ b/src/content/docs/es/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Controlar el color del texto del Log en cónsola"
+
+---
+
+Por defecto la la salida en cónsola puede tener color, dependiendo del TTY detectado.
+
+Definir logs monocromáticos:
+
+```go
+func main() {
+ // Deshabilita el color del log
+ gin.DisableConsoleColor()
+
+ // Crea un route de gin con middleware por defecto:
+ // logger y recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+Definir logs siempre colorizados:
+
+```go
+func main() {
+ // Obliga a generar logs siempre con colores
+ gin.ForceConsoleColor()
+
+ // Crea un route de gin con middleware por defecto:
+ // logger y recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/cookie.md b/src/content/docs/es/docs/examples/cookie.md
new file mode 100644
index 000000000..82e377ceb
--- /dev/null
+++ b/src/content/docs/es/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Crear y obtener una cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/es/docs/examples/custom-http-config.md b/src/content/docs/es/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..a61d08e79
--- /dev/null
+++ b/src/content/docs/es/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "Configuración personalizada HTTP"
+
+---
+
+Se puede utilizar `http.ListenAndServe()` directamente, como se muestra:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+ó modificando valores de la siguiente manera:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/es/docs/examples/custom-log-format.md b/src/content/docs/es/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..12711aaf0
--- /dev/null
+++ b/src/content/docs/es/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "Personalizar formato de Logs"
+
+---
+
+For example:
+
+```go
+func main() {
+ router := gin.New()
+ // El middleware LoggerWithFormatter guardará los a gin.DefaultWriter
+ // Por defecto gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // Formato personalizado
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Ejemplo de Salida**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/es/docs/examples/custom-middleware.md b/src/content/docs/es/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..0ad0b4447
--- /dev/null
+++ b/src/content/docs/es/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Personalizar un Middleware"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Establecer el valor de la variable example
+ c.Set("example", "12345")
+
+ // antes de la petición
+
+ c.Next()
+
+ // después de la petición
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // acceso al estatus que se está enviando
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // debe retornar: "12345"
+ log.Println(example)
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/custom-validators.md b/src/content/docs/es/docs/examples/custom-validators.md
new file mode 100644
index 000000000..8d4b170dc
--- /dev/null
+++ b/src/content/docs/es/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Personalizar Validaciones"
+
+---
+
+Es posible registrar validaciones personalizadas como puede verse en el [código de ejemplo](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// el tipo Booking contiene datos vinculados y con validación.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+Las [validaciones a nivel de struct](https://github.com/go-playground/validator/releases/tag/v8.7) pueden registrarse de esta manera también.
+Véase el ejemplo de [validación a nivel de struct](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) para mayor referencia.
diff --git a/src/content/docs/es/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/es/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..487ed467e
--- /dev/null
+++ b/src/content/docs/es/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,45 @@
+---
+title: "Definir el formato para el log de rutas"
+
+---
+
+El log de rutas por defecto es:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+Si se desea registrar la información en un formato dado (Ejemplo, registrando valores de la petición, JSON, o algo más), se puede definir el formato con `gin.DebugPrintRouteFunc`.
+En el siguiente ejemplo se registran todas las rutas con el paquete estandar de log, sin embargo se puede emplear otro paquete de log que se adapte a lo necesitado.
+
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/es/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..8a43a09e0
--- /dev/null
+++ b/src/content/docs/es/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Goroutines dentro de un middleware"
+
+---
+
+Cuando se inicia una goroutine dentro de un middleware o un handler, **NO SE DEBE** utilizar el context dentro de él, debe emplearse una copia de lectura.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // crear una copia para usar dentro de la rutina
+ cCp := c.Copy()
+ go func() {
+ // se simula una tarea prolongada con un time.Sleep(). de 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // IMPORTANTE: nótese que se trabaja con la copia del contexto "cCp"
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // se simula una tarea prolongada con un time.Sleep(). de 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // debido a que NO se está usando una goroutine, no necesitamos una copia del context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/graceful-restart-or-stop.md b/src/content/docs/es/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..a91dad8e6
--- /dev/null
+++ b/src/content/docs/es/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,83 @@
+---
+title: "Apagado o reinicio controlado del servidor web"
+
+---
+
+Estas son algunas formas de reiniciar o detener el servidor web controladamente.
+
+Se puede utilizar [fvbock/endless](https://github.com/fvbock/endless) para sustituir al `ListenAndServe` por defecto. Véase más detalles en [#296](https://github.com/gin-gonic/gin/issues/296).
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+Alternativas de endless:
+
+* [manners](https://github.com/braintree/manners): Un servidor HTTP para Go con apagado controlado.
+* [graceful](https://github.com/tylerb/graceful): Graceful es un paquete de Go que habilita el apagado controlado de un servidor http.Handler.
+* [grace](https://github.com/facebookgo/grace): Reinicio controlado y despliegue para servidores Go con libre de interrupción del servicio.
+
+Si estás usando Go 1.8, no necesitas hacer uso de esta librería!. Considera el uso del método [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) que viene incluído en `http.Server` para el apagado controlado. Véase el ejemplo de [apagado controlado](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) con Gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // conexiones de servicio
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Espera por la señal de interrupción para el apagado controlado del servidor
+ // con un tiempo de espera de 5 segundos.
+ quit := make(chan os.Signal, 1)
+ // kill (sin parámetro) envío por defecto de la señal syscanll.SIGTERM
+ // kill -2 es syscall.SIGINT
+ // kill -9 es syscall.SIGKILL pero no se puede atrapar, así que no es necesario agregarlo
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // controlando ctx.Done(). tiempo de espera de 5 segundos.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
diff --git a/src/content/docs/es/docs/examples/grouping-routes.md b/src/content/docs/es/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..33f65749c
--- /dev/null
+++ b/src/content/docs/es/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Grouping routes"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Grupo simple con ruta: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Grupo simple con ruta: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/html-rendering.md b/src/content/docs/es/docs/examples/html-rendering.md
new file mode 100644
index 000000000..2b3127092
--- /dev/null
+++ b/src/content/docs/es/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "Representación de HTML"
+
+---
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Utilizando plantillas de mismo nombre en directorios diferentes
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Representación de Plantilla personalizada
+
+Puede emplearse una representación de plantillas html propia.
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Configuración separadores personalizados
+
+Pueden establecerse separadores personalizados
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Funciones personalizadas en plantillas
+
+Véase con más detalle el [código de ejemplo](https://github.com/gin-gonic/examples/tree/master/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/es/docs/examples/http-method.md b/src/content/docs/es/docs/examples/http-method.md
new file mode 100644
index 000000000..34e755b7a
--- /dev/null
+++ b/src/content/docs/es/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Uso de un método específico de HTTP"
+
+---
+
+```go
+func main() {
+ // Crea un route de gin con middleware por defecto:
+ // logger y recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // Sirve por defecto en el puerto 8080
+ // Salvo que una Variable de entorno PORT haya sido definida
+ router.Run()
+ // router.Run(":3000") para definir por código el puerto 3000
+}
+```
diff --git a/src/content/docs/es/docs/examples/http2-server-push.md b/src/content/docs/es/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..521b6d009
--- /dev/null
+++ b/src/content/docs/es/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+
+---
+
+http.Pusher sólo es compatible con versiones **go1.8+ en adelante**. Véase el [blog de golang](https://blog.golang.org/h2push) para información detallada.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // Utilice pusher.Push() para hacer server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Escucha y sirve peticiones en https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/index.md b/src/content/docs/es/docs/examples/index.md
new file mode 100644
index 000000000..2fb403419
--- /dev/null
+++ b/src/content/docs/es/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "Ejemplos"
+
+sidebar:
+ order: 6
+---
+
+Sección con la lista de ejemplos para el uso del API.
diff --git a/src/content/docs/es/docs/examples/jsonp.md b/src/content/docs/es/docs/examples/jsonp.md
new file mode 100644
index 000000000..2d82c3054
--- /dev/null
+++ b/src/content/docs/es/docs/examples/jsonp.md
@@ -0,0 +1,26 @@
+---
+title: "JSONP"
+
+---
+
+Uso de JSONP para realizar una petición de datos desde un servidor en un dominio diferente
+Using JSONP to request data from a server in a different domain. Agregue un callback al cuerpo de respuesta si existe un callback del parámetro de consulta.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ // el callback es x
+ // Retorna : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/es/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..9468104eb
--- /dev/null
+++ b/src/content/docs/es/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Map a partir de una cadena de parámetros GET o parámetros de un formulario POST"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/es/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/es/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..99d4bc594
--- /dev/null
+++ b/src/content/docs/es/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Vincular formularios Multipart/Urlencoded"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // se puede vincular un formulario multipart con declaración explícita:
+ // c.ShouldBindWith(&form, binding.Form)
+ // o simplemente se hace auto vinculación por médio del método ShouldBind:
+ var form LoginForm
+ // en este caso la vinculación adecuada se seleccionará automáticamente
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Puede probarse el código por medio del siguiente curl:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/es/docs/examples/multipart-urlencoded-form.md b/src/content/docs/es/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..3a15a5e6c
--- /dev/null
+++ b/src/content/docs/es/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Formulario Multipart/Urlencoded"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/multiple-template.md b/src/content/docs/es/docs/examples/multiple-template.md
new file mode 100644
index 000000000..cbbdffd8e
--- /dev/null
+++ b/src/content/docs/es/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Multiplantillas"
+
+---
+
+Gin permite por defecto el úso de sólo una html.Template. Puede revisar [un interpretador multi plantilas](https://github.com/gin-contrib/multitemplate) para emplear características como `block template` de go 1.6.
diff --git a/src/content/docs/es/docs/examples/only-bind-query-string.md b/src/content/docs/es/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..9c6e48308
--- /dev/null
+++ b/src/content/docs/es/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Vincular únicamente un parámetros GET"
+
+---
+
+La función `ShouldBindQuery` sólo vincula parámetros GET y excluye los datos POST. Véase la [información detallada](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/es/docs/examples/param-in-path.md b/src/content/docs/es/docs/examples/param-in-path.md
new file mode 100644
index 000000000..efd67bd2e
--- /dev/null
+++ b/src/content/docs/es/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Parámetros en rutas"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // El manejo de esta ruta aceptará valores como /user/john pero no manejará rutas como /user/ o /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // Sin embargo, en este caso si podrá manejar rutas como /user/john/ e inclusive /user/john/send
+ // Si no hay otra ruta que coincida con /user/john, será redireccionada hacia /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/pure-json.md b/src/content/docs/es/docs/examples/pure-json.md
new file mode 100644
index 000000000..30bd67c04
--- /dev/null
+++ b/src/content/docs/es/docs/examples/pure-json.md
@@ -0,0 +1,38 @@
+---
+title: "PureJSON"
+
+---
+Usualmente, JSON sustituye carácteres especiales HTML con sus entidades unicode. Por ejemplo `<` se convierte a `\u003c`. Si se requiere condificar este tipo de caracteres literalmente, se puede utilizar PureJSON.
+Esta característica no está disponible en Go 1.6 o versiones inferiores.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Sirve entidades unicode
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Sirve carácteres literales
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Escucha y sirve peticiones en 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
+Utilizando `curl` tenemos:
+```
+curl http://localhost:8080/purejson
+{"html":"Hello, world!"}
+
+curl http://localhost:8080/json
+{"html":"\u003cb\u003eHello, world!\u003c/b\u003e"}%
+```
diff --git a/src/content/docs/es/docs/examples/query-and-post-form.md b/src/content/docs/es/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..78e0eb652
--- /dev/null
+++ b/src/content/docs/es/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Formulario POST y parámetros GET en URL"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/es/docs/examples/querystring-param.md b/src/content/docs/es/docs/examples/querystring-param.md
new file mode 100644
index 000000000..546dbad01
--- /dev/null
+++ b/src/content/docs/es/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Parámetros GET en URL"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Los parámetros son interpretados usando el objeto de peticiones existente.
+ // La petición responde a un url que coincide con: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // método abreviado para c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/redirects.md b/src/content/docs/es/docs/examples/redirects.md
new file mode 100644
index 000000000..ee2c28dd4
--- /dev/null
+++ b/src/content/docs/es/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirección"
+
+---
+
+Emitir una redirección HTTP es sencillo. Son soportadas las rutas internas o externas.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Emitir una redirección HTTP desde POST. Véase en el issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Emitir una redirección hacia un Router, puede emplearse `HandleContext` como en el ejemplo inferior.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/es/docs/examples/rendering.md b/src/content/docs/es/docs/examples/rendering.md
new file mode 100644
index 000000000..60cbb2e1a
--- /dev/null
+++ b/src/content/docs/es/docs/examples/rendering.md
@@ -0,0 +1,53 @@
+---
+title: "Procesamiento de XML/JSON/YAML/ProtoBuf"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H es un método abreviado para map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // También puedes usar un struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Nótese que msg.Name se convierte en "user" dentro del JSON
+ // Arrojará : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // La definición del protobuf se encuentra escrita en el archivo testdata/protoexample.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Nota: en la respuesta los datos se vuelven binarios
+ // Arrojará la data serializada de protoexample.Test
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/run-multiple-service.md b/src/content/docs/es/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..109e0fc05
--- /dev/null
+++ b/src/content/docs/es/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Ejecutar múltiples servicios a la vez"
+
+---
+
+Véase la [pregunta](https://github.com/gin-gonic/gin/issues/346) e intente el siguiente ejemplo:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/secure-json.md b/src/content/docs/es/docs/examples/secure-json.md
new file mode 100644
index 000000000..5221d0845
--- /dev/null
+++ b/src/content/docs/es/docs/examples/secure-json.md
@@ -0,0 +1,23 @@
+---
+title: "Uso de SecureJSON"
+
+---
+Usando SecureJSON para evitar el secuestro de JSON. Por defecto se antepone `"while(1),"` al cuerpo de respuesta si la estructura dada son valores de array.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Se puede emplear un prefijo JSON seguro propio
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Retornará : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/security-headers.md b/src/content/docs/es/docs/examples/security-headers.md
new file mode 100644
index 000000000..fa0ee9e34
--- /dev/null
+++ b/src/content/docs/es/docs/examples/security-headers.md
@@ -0,0 +1,74 @@
+---
+title: "Encabezados de seguridad"
+
+---
+Es importante utilizar cabeceras de seguridad para proteger su aplicación web de vulnerabilidades de seguridad comunes. Este ejemplo le muestra cómo añadir cabeceras de seguridad a su aplicación Gin y también cómo evitar ataques relacionados con Host Header Injection (SSRF, Open Redirection).
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+Puede probarlo mediante `curl`:
+
+```bash
+// ヘッダーのチェック
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// ホスト・ヘッダー・インジェクションのチェック
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/es/docs/examples/serving-data-from-reader.md b/src/content/docs/es/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..8dbed958b
--- /dev/null
+++ b/src/content/docs/es/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Retornando data a partir de un reader"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/serving-static-files.md b/src/content/docs/es/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..608e3896a
--- /dev/null
+++ b/src/content/docs/es/docs/examples/serving-static-files.md
@@ -0,0 +1,15 @@
+---
+title: "Sirviendo archivos estáticos"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/support-lets-encrypt.md b/src/content/docs/es/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..4f6449b39
--- /dev/null
+++ b/src/content/docs/es/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Soporte de certificados Let's Encrypt"
+
+---
+
+Ejemplo para servidores HTTPS 1-line LetsEncrypt HTTPS.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Manejador de Ping
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+Ejemplo para manejador de autocert personalizado.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Manejador de Ping
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/upload-file/index.md b/src/content/docs/es/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..67d8d1f99
--- /dev/null
+++ b/src/content/docs/es/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Subir archivos"
+
+---
+
+La sección enumera el uso de la API para subir archivos.
diff --git a/src/content/docs/es/docs/examples/upload-file/multiple-file.md b/src/content/docs/es/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..acc0715ea
--- /dev/null
+++ b/src/content/docs/es/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Múltiples archivos"
+
+---
+
+Vea el código de [ejemplo detallado](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Establecer un límite de memoria inferior para formularios de multipart (el valor predeterminado es 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Formulario multipart
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Guarda el archivo recibido a un destino específico
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+Ejemplo para ejecutar `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/es/docs/examples/upload-file/single-file.md b/src/content/docs/es/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..02d8d7474
--- /dev/null
+++ b/src/content/docs/es/docs/examples/upload-file/single-file.md
@@ -0,0 +1,37 @@
+---
+title: "Subir un archivo individual"
+
+---
+
+Issue de referencia [#774](https://github.com/gin-gonic/gin/issues/774) y código [detallado de ejemplo](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **NO DEBE** confiar en su totalidad en la extensión del archivo. Véase en [`Content-Disposition` de MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) y [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> El nombre de archivo siempre es opcional y la aplicación no debe usarlo a ciegas: la información de su ubicación debe eliminarse y debe hacerse la conversión a las reglas del sistema de archivos del servidor.
+
+```go
+func main() {
+ router := gin.Default()
+ // Establecer un límite de memoria inferior para formularios de multipart (el valor predeterminado es 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Archivo individual
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Guarda el archivo recibido a un destino específico
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+Ejemplo para ejecutar `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/es/docs/examples/using-basicauth-middleware.md b/src/content/docs/es/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..35a72c25e
--- /dev/null
+++ b/src/content/docs/es/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,40 @@
+---
+title: "Uso del middleware BasicAuth"
+
+---
+
+```go
+// Se simula una información privada
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Agrupación de rutas usando el middleware gin.BasicAuth()
+ // gin.Accounts es una abreviatura para map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // el endpoint /admin/secrets
+ // será para el url "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // para obtener user, es configurado por el middleware BasicAuth
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/examples/using-middleware.md b/src/content/docs/es/docs/examples/using-middleware.md
new file mode 100644
index 000000000..4796fc68b
--- /dev/null
+++ b/src/content/docs/es/docs/examples/using-middleware.md
@@ -0,0 +1,42 @@
+---
+title: "Usando middleware"
+
+---
+
+```go
+func main() {
+ // Se crea el router por defecto sin ningún middleware
+ r := gin.New()
+
+ // Middleware global
+ // El middlware Logger escribirá los logs hacia gin.DefaultWriter incluso si se configura GIN_MODE=release.
+ // Por defecto será gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // El middleware Recovery recupera al servicio de cualquier panics y registra un error 500 si existiese uno.
+ r.Use(gin.Recovery())
+
+ // Middleware por ruta, se pueden añadir tantos como sea necesario.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Grupo de Authorization
+ // authorized := r.Group("/", AuthRequired())
+ // exactamente el mismo que:
+ authorized := r.Group("/")
+ // Middleware por grupo. En este caso usamos el grupo creado
+ // y se aplicará AuthRequired() middleware únicamente en el grupo "authorized".
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // Grupo anidado
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/es/docs/examples/without-middleware.md b/src/content/docs/es/docs/examples/without-middleware.md
new file mode 100644
index 000000000..274162597
--- /dev/null
+++ b/src/content/docs/es/docs/examples/without-middleware.md
@@ -0,0 +1,18 @@
+---
+title: "Usar Gin sin los middleware por defecto"
+
+---
+
+Utilice
+
+```go
+r := gin.New()
+```
+
+En vez de
+
+```go
+// De esta forma
+// Los middleware Logger y Recovery ya vienen activos
+r := gin.Default()
+```
diff --git a/src/content/docs/es/docs/examples/write-log.md b/src/content/docs/es/docs/examples/write-log.md
new file mode 100644
index 000000000..be6ab31f0
--- /dev/null
+++ b/src/content/docs/es/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "Como registrar un Log en un archivo"
+
+---
+
+```go
+func main() {
+ // Deshabilita el color en la cónsola. Es innecesario si se desea registrar los logs en un archivo.
+ gin.DisableConsoleColor()
+
+ // Declarando el archivo del Log.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Utilice el siguiente código si necesita registrar el log en un archivo y en la cónsola al mismo tiempo.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/es/docs/faq/index.md b/src/content/docs/es/docs/faq/index.md
new file mode 100644
index 000000000..da14005b0
--- /dev/null
+++ b/src/content/docs/es/docs/faq/index.md
@@ -0,0 +1,8 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: Se registrarán las preguntas frecuentes de la sección para [issues de GitHub](https://github.com/gin-gonic/gin/issues).
diff --git a/src/content/docs/es/docs/features/index.md b/src/content/docs/es/docs/features/index.md
new file mode 100644
index 000000000..0c4bc3e1c
--- /dev/null
+++ b/src/content/docs/es/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "Características"
+
+sidebar:
+ order: 4
+---
+
+## Gin versión 1 estable ofrece:
+
+- Router de cero alocación en memoria.
+
+- Sigue siendo el más rápido http router y framework. Desde el enrutamiento hasta la escritura.
+
+- Conjunto completo de pruebas unitarias.
+
+- Probado en batalla.
+
+- API congelada, las nuevas versiones no romperán su código.
diff --git a/src/content/docs/es/docs/index.md b/src/content/docs/es/docs/index.md
new file mode 100644
index 000000000..173d2390f
--- /dev/null
+++ b/src/content/docs/es/docs/index.md
@@ -0,0 +1,21 @@
+---
+title: "Documentación"
+linkTitle: "Documentación"
+sidebar:
+ order: 1
+---
+
+## ¿Qué es Gin?
+
+Gin es un framework para desarrollo web escrito en Go (Golang). Cuenta con una API tipo martini con un rendimiento mucho mayor -- hasta 40 veces más rápido. Si necesitas un rendimiento sensacional, sírvete un Gin.
+
+## ¿Cómo usar Gin?
+
+Ofrecemos ejemplos de uso del API [ejemplos](https://github.com/gin-gonic/examples) y listas de [usuarios de Gin conocidos](./users).
+
+## ¿Cómo puedes contribuir con Gin?
+
+* Ayudando a la comunidad en los foros de discusión
+* Contándonos tus historias de éxito utilizando Gin
+* Comunícanos cómo podemos mejorar Gin y ayudando a hacerlo posible
+* Contribuyendo a una librería existente
diff --git a/src/content/docs/es/docs/introduction/index.md b/src/content/docs/es/docs/introduction/index.md
new file mode 100644
index 000000000..fd4393e6d
--- /dev/null
+++ b/src/content/docs/es/docs/introduction/index.md
@@ -0,0 +1,47 @@
+---
+title: "Introducción"
+
+sidebar:
+ order: 1
+---
+
+Gin es un framework para desarrollo web escrito en Go (Golang). Cuenta con una API tipo martini, con un rendimiento mucho mayor, hasta 40 veces más rápido gracias a [httprouter](https://github.com/julienschmidt/httprouter). Si necesitas rendimiento y productividad amarás a Gin.
+
+En esta sección veremos qué es Gin, qué problemas resuelve y cómo puede ayudar a tu proyecto.
+
+O, si está listo para usar Gin en su proyecto, visita el [Inicio Rápido](https://gin-gonic.com/es/docs/quickstart/).
+
+## Características
+
+### Veloz
+
+Enrutamiento basado en Radix tree, poco consumo de memoria. Sin reflection. Rendimiento predecible del API.
+
+### Soporte de middleware
+
+Una petición entrante HTTP puede ser manejada por diversos middleware encadenados y la acción final.
+Ejemplo: Logger, Authorization, GZIP y por úlitmo guardar el mensaje en la BD.
+
+### Libre de crashes
+
+Gin puede recibir y recuperarse de un panic ocurrido durante una petición HTTP. Así tu servidor estará siempre disponible. También es posible hacer un reporte del panic, por ejemplo ¡a Sentry!
+
+### Validación de JSON
+
+Gin permite analizar y validar datos JSON en una petición, y por ejemplo, revisar la existencia de datos requeridos.
+
+### Agrupación de rutas
+
+Organiza mejor tus rutas: Rutas con autorización vs rutas públicas, versiones diferentes de API. Adicionalmente los grupos de rutas pueden anidarse ilimitadamente sin afectar el rendimiento.
+
+### Manejo de errores
+
+Gin ofrece una conveniente forma de recopilar los errores ocurridos durante una petición HTTP. Un middleware puede incluso registrarlos en un archivo de logs, la BD o enviarlos por la red.
+
+### Render incluído
+
+Gin cuenta con una API fácil de usar para el render de JSON, XML y HTML.
+
+### Extensible
+
+Crear un middleware nuevo es muy sencillo. Sólo debes revisar los códigos de ejemplo.
diff --git a/src/content/docs/es/docs/jsoniter/index.md b/src/content/docs/es/docs/jsoniter/index.md
new file mode 100644
index 000000000..6d65596b2
--- /dev/null
+++ b/src/content/docs/es/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## Go Build con [jsoniter](https://github.com/json-iterator/go)
+
+Gin utiliza `encoding/json` como paquete por defecto para json, pero se puede cambiar por [jsoniter](https://github.com/json-iterator/go) especificándolo en el tag al hacer go build.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/es/docs/quickstart/index.md b/src/content/docs/es/docs/quickstart/index.md
new file mode 100644
index 000000000..565ada410
--- /dev/null
+++ b/src/content/docs/es/docs/quickstart/index.md
@@ -0,0 +1,88 @@
+---
+title: "Inicio Rápido"
+
+sidebar:
+ order: 2
+---
+
+En este inicio rápido, captaremos información y aprenderemos por medio de porciones de código:
+
+## Requerimientos
+
+- Go 1.16 o superior
+
+## Instalación
+
+Para instalar Gin, primero debe instalar Go y configurar el espacio de trabajo Go.
+
+1. Descargar e instalar:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. Importar en el código:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. Importar el paquete `net/http` (Opcional). Es requerido para el uso de constantes como por ejemplo `http.StatusOK`.
+
+```go
+import "net/http"
+```
+
+1. Crear la carpeta del proyecto e ingresar en ella con `cd`
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. Copiar una plantilla de inicio dentro del proyecto
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. Ejecutar el proyecto
+
+```sh
+$ go run main.go
+```
+
+## Primeros Pasos
+
+> ¿No sabes cómo escribir y ejecutar código Go? [Click aquí](https://golang.org/doc/code.html).
+
+Primero, crear un archivo llamado `example.go`:
+
+```sh
+# asumimos que el código siguiente se encontrará en el archivo example.go
+$ touch example.go
+```
+
+A continuación, coloque el siguiente código dentro en `example.go`:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // Sirve y escucha peticiones en 0.0.0.0:8080
+}
+```
+
+Y ahora, puede ejecutar el código a través de `go run example.go`:
+
+```sh
+# ejecuta example.go y visita 0.0.0.0:8080/ping en el navegador
+$ go run example.go
+```
diff --git a/src/content/docs/es/docs/testing/index.md b/src/content/docs/es/docs/testing/index.md
new file mode 100644
index 000000000..b481c6e38
--- /dev/null
+++ b/src/content/docs/es/docs/testing/index.md
@@ -0,0 +1,93 @@
+---
+title: "Testing en Gin"
+
+sidebar:
+ order: 7
+---
+
+## ¿Cómo escribir casos de prueba en Gin?
+
+El paquete `net/http/httptest` es la forma preferible para las pruebas de HTTP
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+Test para el código anterior de ejemplo:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
+
+
+
diff --git a/src/content/docs/es/docs/users/index.md b/src/content/docs/es/docs/users/index.md
new file mode 100644
index 000000000..07d8f9fd7
--- /dev/null
+++ b/src/content/docs/es/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Usuarios"
+
+sidebar:
+ order: 8
+---
+
+##### Lista de proyectos fantásticos que usan [Gin](https://github.com/gin-gonic/gin) web framework:
+
+* [gorush](https://github.com/appleboy/gorush): Servidor de notificaciones push escrito en Go.
+
+* [fnproject](https://github.com/fnproject/fn): Plataforma serverless basada en contenedores nativamente, y agnóstica de cloud.
+
+* [photoprism](https://github.com/photoprism/photoprism): Administrador de fotos personales basado en Go y TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Gateway API de ultra rendimiento con middlewares.
+
+* [picfit](https://github.com/thoas/picfit): Servidor de cambio de tamaño de imagen escrito en Go.
+
+* [gotify](https://github.com/gotify/server): Un servidor simple para enviar y recibir mensajes en tiempo real a través de web sockets.
+
+* [cds](https://github.com/ovh/cds): Plataforma open source de Continuous Delivery y automatización DevOps de nivel empresarial.
diff --git a/src/content/docs/es/index.mdx b/src/content/docs/es/index.mdx
new file mode 100644
index 000000000..c220d13bc
--- /dev/null
+++ b/src/content/docs/es/index.mdx
@@ -0,0 +1,61 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Claramente, el framework más rápido para desarrollo web en Go.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Ver Más
+ link: /es/docs/
+ icon: right-arrow
+ - text: Descargar
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from "@astrojs/starlight/components";
+
+## ¿Qué es Gin?
+
+Gin es un framework para desarrollo web escrito en Golang. Cuenta con una API tipo martini con un rendimiento mucho mayor, hasta 40 veces más rápido. Si necesitas rendimiento y productividad amarás a Gin.
+
+
+
+ Enrutamiento basado en Radix tree, poco consumo de memoria. Sin reflection.
+ Rendimiento predecible del API.
+
+
+ Una petición entrante HTTP puede ser manejada por diversos middleware
+ encadenados y la acción final. Ejemplo: Logger, Authorization, GZIP y por
+ úlitmo guardar el mensaje en la BD.
+
+
+ Gin puede recibir y recuperarse de un panic ocurrido durante una petición
+ HTTP. Así tu servidor estará siempre disponible. También es posible hacer un
+ reporte del panic, por ejemplo ¡a Sentry!
+
+
+ Gin permite analizar y validar datos JSON en una petición, y por ejemplo,
+ revisar la existencia de datos requeridos.
+
+
+ Organiza mejor tus rutas: Rutas con autorización vs rutas públicas,
+ versiones diferentes de API. Adicionalmente los grupos de rutas pueden
+ anidarse ilimitadamente sin afectar el rendimiento.
+
+
+ Gin ofrece una conveniente forma de recopilar los errores ocurridos durante
+ una petición HTTP. Un middleware puede incluso registrarlos en un archivo de
+ logs, la BD o enviarlos por la red.
+
+
+ Gin cuenta con una API fácil de usar para el render de JSON, XML y HTML.
+
+
+ Crear un middleware nuevo es muy sencillo. Sólo debes revisar los códigos de
+ ejemplo.
+
+
diff --git a/src/content/docs/fa/blog/index.md b/src/content/docs/fa/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/fa/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/fa/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/fa/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/fa/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/fa/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/fa/blog/releases/release13.md b/src/content/docs/fa/blog/releases/release13.md
similarity index 100%
rename from content/fa/blog/releases/release13.md
rename to src/content/docs/fa/blog/releases/release13.md
diff --git a/content/fa/blog/releases/release14.md b/src/content/docs/fa/blog/releases/release14.md
similarity index 100%
rename from content/fa/blog/releases/release14.md
rename to src/content/docs/fa/blog/releases/release14.md
diff --git a/content/fa/blog/releases/release15.md b/src/content/docs/fa/blog/releases/release15.md
similarity index 100%
rename from content/fa/blog/releases/release15.md
rename to src/content/docs/fa/blog/releases/release15.md
diff --git a/content/fa/blog/releases/release16.md b/src/content/docs/fa/blog/releases/release16.md
similarity index 100%
rename from content/fa/blog/releases/release16.md
rename to src/content/docs/fa/blog/releases/release16.md
diff --git a/src/content/docs/fa/docs/benchmarks/index.md b/src/content/docs/fa/docs/benchmarks/index.md
new file mode 100644
index 000000000..b5a8b975a
--- /dev/null
+++ b/src/content/docs/fa/docs/benchmarks/index.md
@@ -0,0 +1,50 @@
+---
+title: "بنچ مارک ها"
+
+sidebar:
+ order: 3
+---
+
+جین از یک نسخه سفارشی از [HttpRouter](https://github.com/julienschmidt/httprouter) استفاده میکند.
+
+[نتایج همه بنچ مارک ها رو اینجا ببینید](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | --------: | --------------: | -----------: | --------------: |
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+راهنمای جدول بالا
+
+- (1): Total Repetitions achieved in constant time -> بالاتر یعنی نتیجه با اطمینان بیشتری است
+- (2): Single Repetition Duration (ns/op) -> هرچه پایین تر بهتر است
+- (3): Heap Memory (B/op) -> هرچه پایین تر بهتر است
+- (4): Average Allocations per Repetition (allocs/op) -> هرچه پایین تر بهتر است
diff --git a/src/content/docs/fa/docs/deployment/index.md b/src/content/docs/fa/docs/deployment/index.md
new file mode 100644
index 000000000..885a80a08
--- /dev/null
+++ b/src/content/docs/fa/docs/deployment/index.md
@@ -0,0 +1,26 @@
+---
+title: "دیپلوی"
+
+sidebar:
+ order: 6
+---
+
+جین به راحتی میتواند روی هر فضای ابری دیپلوی شود.
+
+## [Qovery](https://www.qovery.com)
+
+Qovery یک هاست رایگان همراه با دیتابیس ssl , CDN را ارائه میدهد و همچنین به صورت خودکار با گیت دیپلوی میشود.
+
+[پروژه جین خودتو با استفاده از Qovery دیپلوی کن](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
+
+## [Render](https://render.com)
+
+Render یک پلت فرم ابری مدرن است که پشتیبانی نیتیو از Go ، SSL کاملاً مدیریت شده ، دیتابیس ،zero-downtime deploys ، HTTP / 2 و پشتیبانی از websocket را ارائه می دهد.
+
+[پروژه جین خودتو با Render دیپلوی کن](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE دو روش برای دیپلوی برنامه های Go دارد. استفاده از محیط استاندارد آسان تر است اما کمتر قابل تنظیم است و به دلایل امنیتی از [syscalls](https://github.com/gin-gonic/gin/issues/1639) جلوگیری می کند. محیط انعطاف پذیر آن می تواند هر چارچوب یا کتابخانه ای را اجرا کند.
+
+[محیط خودتو با Google App Engine بساز](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/fa/docs/examples/ascii-json.md b/src/content/docs/fa/docs/examples/ascii-json.md
new file mode 100644
index 000000000..7e2d2b0d0
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/fa/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..138179eea
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Try to bind body into different structs"
+
+---
+
+The normal methods for binding request body consumes `c.Request.Body` and they
+cannot be called multiple times.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Always an error is occurred by this because c.Request.Body is EOF now.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This reads c.Request.Body and stores the result into the context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // At this time, it reuses body stored in the context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // And it can accepts other formats
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` stores body into the context before binding. This has
+a slight impact to performance, so you should not use this method if you are
+enough to call binding at once.
+* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
+can be called by `c.ShouldBind()` multiple times without any damage to
+performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/fa/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/fa/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..92ab2f4b8
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "Bind form-data request with custom struct"
+
+---
+
+The follow example using custom struct:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Using the command `curl` command result:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/fa/docs/examples/bind-html-checkbox.md b/src/content/docs/fa/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..4b1ee65ef
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Bind html checkboxes"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+result:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/fa/docs/examples/bind-query-or-post.md b/src/content/docs/fa/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..9912d908a
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "Bind query string or post data"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // If `GET`, only `Form` binding engine (`query`) used.
+ // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
+ // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Test it with:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/fa/docs/examples/bind-single-binary-with-template.md b/src/content/docs/fa/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..09e8b02fc
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,45 @@
+---
+title: "Build a single binary with templates"
+
+---
+## Use the third-party package
+
+You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/src/content/docs/fa/docs/examples/bind-uri.md b/src/content/docs/fa/docs/examples/bind-uri.md
new file mode 100644
index 000000000..b2092e977
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Bind Uri"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Test it with:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/fa/docs/examples/binding-and-validation.md b/src/content/docs/fa/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..40684022c
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Model binding and validation"
+
+---
+
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
+
+Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
+
+Also, Gin provides two sets of methods for binding:
+- **Type** - Must bind
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
+- **Type** - Should bind
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
+
+When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
+
+You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
+
+```go
+// Binding from JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Example for binding JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding a HTML form (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // This will infer what binder to use depending on the content-type header.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Sample request
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Skip validate
+
+When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/src/content/docs/fa/docs/examples/controlling-log-output-coloring.md b/src/content/docs/fa/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..c0973a85a
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Controlling Log output coloring"
+
+---
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/cookie.md b/src/content/docs/fa/docs/examples/cookie.md
new file mode 100644
index 000000000..090e66354
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Set and get a cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/fa/docs/examples/custom-http-config.md b/src/content/docs/fa/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..e8b921b73
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/custom-http-config.md
@@ -0,0 +1,29 @@
+---
+title: "Custom HTTP configuration"
+
+---
+
+Use `http.ListenAndServe()` directly, like this:
+
+```go
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/fa/docs/examples/custom-log-format.md b/src/content/docs/fa/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..6d6450341
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "Custom log file"
+
+---
+
+For example:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Sample Output**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/fa/docs/examples/custom-middleware.md b/src/content/docs/fa/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..8de8438b0
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Custom Middleware"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Set example variable
+ c.Set("example", "12345")
+
+ // before request
+
+ c.Next()
+
+ // after request
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // access the status we are sending
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // it would print: "12345"
+ log.Println(example)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/custom-validators.md b/src/content/docs/fa/docs/examples/custom-validators.md
new file mode 100644
index 000000000..114de29af
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Custom validators"
+
+---
+
+It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking contains binded and validated data.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
+See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/src/content/docs/fa/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/fa/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..44bd991a9
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "Define format for the log of routes"
+
+---
+
+The default log of routes is:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
+In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/fa/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/fa/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..f3a6b10d6
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Goroutines inside a middleware"
+
+---
+
+When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // create copy to be used inside the goroutine
+ cCp := c.Copy()
+ go func() {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // note that you are using the copied context "cCp", IMPORTANT
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // since we are NOT using a goroutine, we do not have to copy the context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/graceful-restart-or-stop.md b/src/content/docs/fa/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..633ad5324
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,85 @@
+---
+title: "Graceful restart or stop"
+
+---
+
+Do you want to graceful restart or stop your web server?
+There are some ways this can be done.
+
+We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+An alternative to endless:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // service connections
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Wait for interrupt signal to gracefully shutdown the server with
+ // a timeout of 5 seconds.
+ quit := make(chan os.Signal, 1)
+ // kill (no param) default send syscanll.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // catching ctx.Done(). timeout of 5 seconds.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/grouping-routes.md b/src/content/docs/fa/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..c7f7a7245
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Grouping routes"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Simple group: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Simple group: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/html-rendering.md b/src/content/docs/fa/docs/examples/html-rendering.md
new file mode 100644
index 000000000..787248795
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML rendering"
+
+---
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Using templates with same name in different directories
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Custom Template renderer
+
+You can also use your own html template render
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Custom Delimiters
+
+You may use custom delims
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Custom Template Funcs
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/fa/docs/examples/http-method.md b/src/content/docs/fa/docs/examples/http-method.md
new file mode 100644
index 000000000..b8d41d696
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Using HTTP method"
+
+---
+
+```go
+func main() {
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // By default it serves on :8080 unless a
+ // PORT environment variable was defined.
+ router.Run()
+ // router.Run(":3000") for a hard coded port
+}
+```
diff --git a/src/content/docs/fa/docs/examples/http2-server-push.md b/src/content/docs/fa/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..192d22a45
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+
+---
+
+http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // use pusher.Push() to do server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Listen and Server in https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/index.md b/src/content/docs/fa/docs/examples/index.md
new file mode 100644
index 000000000..c371f9c5f
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "مثال ها"
+
+sidebar:
+ order: 6
+---
+
+لیست مثال ها.
diff --git a/src/content/docs/fa/docs/examples/jsonp.md b/src/content/docs/fa/docs/examples/jsonp.md
new file mode 100644
index 000000000..bc4439a44
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback is x
+ // Will output : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/fa/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..5ed88b0b5
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Map as querystring or postform parameters"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/fa/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/fa/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..73fee286a
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded binding"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // you can bind multipart form with explicit binding declaration:
+ // c.ShouldBindWith(&form, binding.Form)
+ // or you can simply use autobinding with ShouldBind method:
+ var form LoginForm
+ // in this case proper binding will be automatically selected
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Test it with:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/fa/docs/examples/multipart-urlencoded-form.md b/src/content/docs/fa/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..04eab2373
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded form"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/multiple-template.md b/src/content/docs/fa/docs/examples/multiple-template.md
new file mode 100644
index 000000000..28b58c213
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Multitemplate"
+
+---
+
+Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/src/content/docs/fa/docs/examples/only-bind-query-string.md b/src/content/docs/fa/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..bdd6c174e
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Only bind query string"
+
+---
+
+`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/param-in-path.md b/src/content/docs/fa/docs/examples/param-in-path.md
new file mode 100644
index 000000000..b0a4a3b68
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Parameters in path"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // This handler will match /user/john but will not match /user/ or /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // However, this one will match /user/john/ and also /user/john/send
+ // If no other routers match /user/john, it will redirect to /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/pure-json.md b/src/content/docs/fa/docs/examples/pure-json.md
new file mode 100644
index 000000000..5fbf8bfc1
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/pure-json.md
@@ -0,0 +1,30 @@
+---
+title: "PureJSON"
+
+---
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/query-and-post-form.md b/src/content/docs/fa/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..5c8e6d21e
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Query and post form"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/fa/docs/examples/querystring-param.md b/src/content/docs/fa/docs/examples/querystring-param.md
new file mode 100644
index 000000000..cba891746
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Query string parameters"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Query string parameters are parsed using the existing underlying request object.
+ // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/redirects.md b/src/content/docs/fa/docs/examples/redirects.md
new file mode 100644
index 000000000..e62a9952e
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirects"
+
+---
+
+Issuing a HTTP redirect is easy. Both internal and external locations are supported.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Issuing a Router redirect, use `HandleContext` like below.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/fa/docs/examples/rendering.md b/src/content/docs/fa/docs/examples/rendering.md
new file mode 100644
index 000000000..c9c705c65
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf rendering"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H is a shortcut for map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // You also can use a struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Note that msg.Name becomes "user" in the JSON
+ // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/run-multiple-service.md b/src/content/docs/fa/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..0dba2ab95
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Run multiple service"
+
+---
+
+See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/secure-json.md b/src/content/docs/fa/docs/examples/secure-json.md
new file mode 100644
index 000000000..82e63a4c4
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // You can also use your own secure json prefix
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Will output : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/security-headers.md b/src/content/docs/fa/docs/examples/security-headers.md
new file mode 100644
index 000000000..9fa537894
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "Security Headers"
+
+---
+
+It's important to use security headers to protect your web application from common security vulnerabilities. This example shows you how to add security headers to your Gin application and also how to avoid Host Header Injection related attacks (SSRF, Open Redirection).
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+You can test it via `curl`:
+
+```bash
+// Check Headers
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// Check Host Header Injection
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/fa/docs/examples/serving-data-from-reader.md b/src/content/docs/fa/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..614db12ce
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Serving data from reader"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/serving-static-files.md b/src/content/docs/fa/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..bda67da07
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Serving static files"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/support-lets-encrypt.md b/src/content/docs/fa/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..841c1a7f9
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Support Let's Encrypt"
+
+---
+
+example for 1-line LetsEncrypt HTTPS servers.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+example for custom autocert manager.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/upload-file/index.md b/src/content/docs/fa/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..d0ff99e85
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Upload files"
+
+---
+
+The section lists upload file api usage.
diff --git a/src/content/docs/fa/docs/examples/upload-file/multiple-file.md b/src/content/docs/fa/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..185b7b5f6
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Multiple files"
+
+---
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/fa/docs/examples/upload-file/single-file.md b/src/content/docs/fa/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..5fe274dc7
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/upload-file/single-file.md
@@ -0,0 +1,37 @@
+---
+title: "Single file"
+
+---
+
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // single file
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/fa/docs/examples/using-basicauth-middleware.md b/src/content/docs/fa/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..cc68db4a0
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Using BasicAuth middleware"
+
+---
+
+```go
+// simulate some private data
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Group using gin.BasicAuth() middleware
+ // gin.Accounts is a shortcut for map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets endpoint
+ // hit "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // get user, it was set by the BasicAuth middleware
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/examples/using-middleware.md b/src/content/docs/fa/docs/examples/using-middleware.md
new file mode 100644
index 000000000..5fc4154db
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Using middleware"
+
+---
+
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.Recovery())
+
+ // Per route middleware, you can add as many as you desire.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Authorization group
+ // authorized := r.Group("/", AuthRequired())
+ // exactly the same as:
+ authorized := r.Group("/")
+ // per group middleware! in this case we use the custom created
+ // AuthRequired() middleware just in the "authorized" group.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // nested group
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/fa/docs/examples/without-middleware.md b/src/content/docs/fa/docs/examples/without-middleware.md
new file mode 100644
index 000000000..6ef54bda0
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Without middleware by default"
+
+---
+
+Use
+
+```go
+r := gin.New()
+```
+
+instead of
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
diff --git a/src/content/docs/fa/docs/examples/write-log.md b/src/content/docs/fa/docs/examples/write-log.md
new file mode 100644
index 000000000..759423de4
--- /dev/null
+++ b/src/content/docs/fa/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "How to write log file"
+
+---
+
+```go
+func main() {
+ // Disable Console Color, you don't need console color when writing the logs to file.
+ gin.DisableConsoleColor()
+
+ // Logging to a file.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Use the following code if you need to write the logs to file and console at the same time.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/fa/docs/faq/index.md b/src/content/docs/fa/docs/faq/index.md
new file mode 100644
index 000000000..ad348f11f
--- /dev/null
+++ b/src/content/docs/fa/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: record some frequently asked question from GitHub Issue tab.
+
diff --git a/src/content/docs/fa/docs/features/index.md b/src/content/docs/fa/docs/features/index.md
new file mode 100644
index 000000000..8014b6e54
--- /dev/null
+++ b/src/content/docs/fa/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "امکانات"
+
+sidebar:
+ order: 4
+---
+
+## امکانات نسخه پایدار 1 جین :
+
+- Zero allocation router.
+
+- هنوز سریعترین روتر و فریم ورک http. از مسیریابی گرفته تا نوشتن.
+
+- مجموعه کامل یونیت تست ها
+
+- نبرد تست شده.
+
+- API forzen ، در نسخه های جدید کد شما بریک نمیشود.
diff --git a/src/content/docs/fa/docs/index.md b/src/content/docs/fa/docs/index.md
new file mode 100644
index 000000000..426d02268
--- /dev/null
+++ b/src/content/docs/fa/docs/index.md
@@ -0,0 +1,21 @@
+---
+title: "اسناد"
+linkTitle: "اسناد/"
+sidebar:
+ order: 1
+---
+
+## Gin چیست ؟
+
+جین یکی از وب فریم ورکهای زبان گو است که امکاناتی مانند فریم ورک martini داره ولی با کارایی بهتر یعنی چیزی حدود 40 برابر سریع تر از martini اگر به عملکرد فوق العاده ای نیاز دارید ، خودتان امتحان کنید.
+
+## چگونه از Gin استفاده کنیم ؟
+
+ما نمونه های استفاده از API را ارائه می دهیم که میتونید مثال ها رو [اینجا](https://github.com/gin-gonic/examples) ببنید و برخی از کاربران Gin را که به طور عمومی شناخته شده اند لیست می کنیم. که میتونید [اینجا](./users) ببینید.
+
+## چگونه میتوان به Gin کمک کرد ؟
+
+- در انجمن های گفتگو به افراد کمک کنید
+- داستانهای موفقیت خود را با استفاده از جین برای ما بگویید
+- به ما بگویید که چگونه می توانیم جین را بهبود بخشیم و به ما در انجام آن کمک کنیم
+- به یک کتابخانه موجود کمک کنید
diff --git a/src/content/docs/fa/docs/introduction/index.md b/src/content/docs/fa/docs/introduction/index.md
new file mode 100755
index 000000000..dd2e3e121
--- /dev/null
+++ b/src/content/docs/fa/docs/introduction/index.md
@@ -0,0 +1,47 @@
+---
+title: "مقدمه"
+
+sidebar:
+ order: 1
+---
+
+Gin یک فریم ورک وب ساخته شده با Go است که امکاناتی مانند martini دارد (یکی دیگر از فریم ورک های وب گو) ولی با کارایی بالاتر چیزی حدود 40 برابر سریع تر با تشکر از [httprouter](https://github.com/iamAmirrezaSaki/website.git).اگه به عملکرد فوق العاده ایی نیاز دارید عاشق Gin می شوید.
+
+در این بخش ما به بررسی جین میپردازیم که چه مشکلاتی را حل می کند و چگونه می تواند به پروژه شما کمک کند.
+
+یا اگر آماده استفاده از Gin برای پروژه خود هستید ، به [شروع سریع] (https://gin-gonic.com/docs/quickstart/) سر بزنید.
+
+## امکانات
+
+### سرعت بالا(سریع)
+
+مسیریابی مبتنی بر درخت ردیکس(Radix tree based routing) ، چاپ ردپا روی حافظه کم(small memory foot print). بدون تأمل. عملکرد قابل پیش بینی API.
+
+### پشتیبانی از میان افزارها(middleware)
+
+یک درخواست HTTP ورودی میتواند از میان زنجیره ایی از میان افزار ها بگردد و سپس به یک اقدام نهایی منجر شود.
+برای مثال: زنجیره ی میان افزار ها -> Logger, Authorization, GZIOP و در نهایت یک اقدام یا پروسه نهایی که منجرب به ذخیره ی یک پیام در دیتابیس میشود.
+
+### (بدون خرابی)Crash-free
+
+Gin می تواند در هنگام درخواست HTTP دچار پنیک(کرش) شود و آن را بازیابی کند. به این ترتیب سرور شما همیشه در دسترس خواهد بود و پایدار میماند. همچنین می توانید این پنیک(کرش) را به Sentry گزارش دهید!
+
+### JSON validation(اعتبار سنجی فرمت JSON)
+
+جین می تواند JSON ورودی را تجزیه و اعتبار سنجی کند - به عنوان مثال ، بررسی مقادیر مورد نیاز.(فیلد های اجباری مورد نیاز)
+
+### Routes grouping(گروه بندی کردن مسیر ها یا API ها)
+
+مسیرهای خود را بهتر سازماندهی کنید. گروه ها می توانند بدون محدودیت عملکرد به صورت نامحدود تو در تو قرار بگیرند.
+
+### Error management(مدیریت خطا)
+
+جین یک روش مناسب برای جمع آوری تمام خطاهایی که در هنگام درخواست HTTP رخ داده است فراهم می کند. در نهایت ، یک میان افزار می تواند آنها را در یک فایل log یا یک پایگاه داده بنویسد و از طریق شبکه ارسال کند.
+
+### Rendering built-in(رندر داخلی)
+
+Gin استفاده آسان از API را برای استفاده از JSON ، XML و HTML فراهم می کند.
+
+### Extendable(توسعه پذیر)
+
+ساخت یک میان افزار جدید بسیار ساده است. تنها کافی است به نمونه کدها یه نگاه بندازید.
diff --git a/src/content/docs/fa/docs/jsoniter/index.md b/src/content/docs/fa/docs/jsoniter/index.md
new file mode 100644
index 000000000..242b2987a
--- /dev/null
+++ b/src/content/docs/fa/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## [jsoniter](https://github.com/json-iterator/go)
+
+جین به صورت پیشفرض از پکیج 'encoding/json' استفاده میکند ولی شما میتوانید ان را به jsoniter تغییر دهید با استفاده از تگ jsoniter در هنگام بیلد.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/fa/docs/quickstart/index.md b/src/content/docs/fa/docs/quickstart/index.md
new file mode 100644
index 000000000..36d2fd4fd
--- /dev/null
+++ b/src/content/docs/fa/docs/quickstart/index.md
@@ -0,0 +1,88 @@
+---
+title: "شروع سریع"
+
+sidebar:
+ order: 2
+---
+
+در اینجا ما اطلاعاتی را در کدها دریافت میکنیم و همچنین یاد میگیریم که :
+
+## الزامات
+
+- Go 1.16 یا بالا تر
+
+## نصب و راه اندازی
+
+برای نصب پکیج Gin ابتدا باید گو را نصب کنید و محیط خودتون رو تنظیم کنید.
+
+1. دانلود و نصب:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. جین را به پروژتون اضافه کنید
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. وارد کنید "net/http" برای متغیر های ثابت مثل http.StatusOK (اختیاری).
+
+```go
+import "net/http"
+```
+
+1. یک پوشه بسازید و وارد اون پوشه بشید
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. یک الگوی اولیه برای شروع را در داخل پروژه خود کپی کنید
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. پروژتون رو اجرا کنید
+
+```sh
+$ go run main.go
+```
+
+## شروع
+
+> نمیدونید چطور یک کد گو رو اجرا کنید ؟ [اینجا کلیک کنید](https://golang.org/doc/code.html).
+
+ابتدا یک فایل به اسم `example.go` بسازید :
+
+```sh
+# assume the following codes in example.go file
+$ touch example.go
+```
+
+سپس کد های زیر رو توی فایل `example.go` بنویسید :
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+حالا میتوانید کد رو با دستور زیر اجرا کنید :
+
+```sh
+# run example.go and visit 0.0.0.0:8080/ping on browser
+$ go run example.go
+```
diff --git a/src/content/docs/fa/docs/testing/index.md b/src/content/docs/fa/docs/testing/index.md
new file mode 100644
index 000000000..40ec4d3a6
--- /dev/null
+++ b/src/content/docs/fa/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "تست"
+
+sidebar:
+ order: 7
+---
+
+## چگونه در gin تست بنویسیم ؟
+
+پکیج `net/http/httptest` روشی برتر برای آزمایش HTTP است.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+تست برای کد بالا :
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/fa/docs/users/index.md b/src/content/docs/fa/docs/users/index.md
new file mode 100644
index 000000000..bd3f67a87
--- /dev/null
+++ b/src/content/docs/fa/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "کاربران"
+
+sidebar:
+ order: 8
+---
+
+##### لیستی عالی از پروژه های ساخته شده با [Gin](https://github.com/gin-gonic/gin):
+
+- [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.(سرور پوش نوتیفیکیشن)
+
+- [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+
+- [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+
+- [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+
+- [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
+
+- [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
+
+- [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/src/content/docs/fa/index.mdx b/src/content/docs/fa/index.mdx
new file mode 100644
index 000000000..f591364c5
--- /dev/null
+++ b/src/content/docs/fa/index.mdx
@@ -0,0 +1,54 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: The fastest full-featured web framework for Go. Crystal clear.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Read the docs
+ link: /fa/docs/
+ icon: right-arrow
+ - text: Download
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## Gin چیست?
+
+جین یک فریم ورک وبه که با زبان گو ساخته شده.
+
+.جین یک فریم ورک شبیه به مارتینه(یکی دیگه از وب فریم ورک های گو) ولی با پرفورمنس بهتر . چیزی حدود 40 برار سریع تر
+
+اگه شما نیازمند پرفورمنس و کارایی بالا(بهره بری بالا) هستید عاشق جین میشید.
+
+
+
+ Radix tree based routing(مسیریابی مبتنی بر درخت ردیکس), small memory foot print. No reflection(بدون تامل). Predictable API performance.
+
+
+ An incoming HTTP request can be handled by a chain of middleware and the final action. For example: Logger, Authorization, GZIP and finally post a message in the DB.
+
+
+ Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
+
+
+ Gin can parse and validate the JSON of a request, checking, for example, the existence of required values.
+
+
+ Organize your routes better. Authorization required vs non required, different API versions. In addition, groups can be nested infinitely without degrading performance.
+
+
+ Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, middleware can write them to a log file, to a database and send them through the network.
+
+
+ Gin provides an easy to use API for JSON, XML and HTML rendering.
+
+
+ Creating new middleware is so easy, just check out the sample code.
+
+
\ No newline at end of file
diff --git a/src/content/docs/index.mdx b/src/content/docs/index.mdx
new file mode 100644
index 000000000..19d7f4b82
--- /dev/null
+++ b/src/content/docs/index.mdx
@@ -0,0 +1,61 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: The fastest full-featured web framework for Go. Crystal clear.
+ image:
+ file: ../../assets/gin.png
+ actions:
+ - text: Read the docs
+ link: /en/docs/
+ icon: right-arrow
+ - text: Download
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## What is Gin?
+
+Gin is a web framework written in Golang. It features a Martini-like API, but with performance up to 40 times faster than Martini. If you need performance and productivity, you will love Gin.
+
+
+
+ Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
+
+
+ An incoming HTTP request can be handled by a chain of middleware and the final action. For example: Logger, Authorization, GZIP and finally post a message in the DB.
+
+
+ Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
+
+
+ Gin can parse and validate the JSON of a request, checking, for example, the existence of required values.
+
+
+ Organize your routes better. Authorization required vs non required, different API versions. In addition, groups can be nested infinitely without degrading performance.
+
+
+ Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, middleware can write them to a log file, to a database and send them through the network.
+
+
+ Gin provides an easy to use API for JSON, XML and HTML rendering.
+
+
+ Creating new middleware is so easy, just check out the sample code.
+
+
+
+## How to use Gin?
+
+We provide API usage [examples](https://github.com/gin-gonic/examples) and list some publicly known [Gin users](/en/docs/users).
+
+## How to contribute to Gin?
+
+* Help people on the discussion forums
+* Tell us your success stories using Gin
+* Tell us how we can improve Gin and help us do it
+* Contribute to an existing library
\ No newline at end of file
diff --git a/src/content/docs/ja/blog/index.md b/src/content/docs/ja/blog/index.md
new file mode 100644
index 000000000..e01b20dce
--- /dev/null
+++ b/src/content/docs/ja/blog/index.md
@@ -0,0 +1,11 @@
+---
+title: "ブログ"
+linkTitle: "ブログ"
+sidebar:
+ order: 30
+---
+
+
+ここれは **blog** セクションです。ニュースとリリースという2種類のカテゴリがあります。
+
+このディレクトリ内のファイルは時系列の降順にリストされます。
diff --git a/content/ja/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/ja/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/ja/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/ja/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/ja/blog/releases/release13.md b/src/content/docs/ja/blog/releases/release13.md
similarity index 100%
rename from content/ja/blog/releases/release13.md
rename to src/content/docs/ja/blog/releases/release13.md
diff --git a/content/ja/blog/releases/release14.md b/src/content/docs/ja/blog/releases/release14.md
similarity index 100%
rename from content/ja/blog/releases/release14.md
rename to src/content/docs/ja/blog/releases/release14.md
diff --git a/content/ja/blog/releases/release15.md b/src/content/docs/ja/blog/releases/release15.md
similarity index 100%
rename from content/ja/blog/releases/release15.md
rename to src/content/docs/ja/blog/releases/release15.md
diff --git a/src/content/docs/ja/docs/benchmarks/index.md b/src/content/docs/ja/docs/benchmarks/index.md
new file mode 100644
index 000000000..029d5f56d
--- /dev/null
+++ b/src/content/docs/ja/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "ベンチマーク"
+
+sidebar:
+ order: 3
+---
+
+Gin は [HttpRouter](https://github.com/julienschmidt/httprouter) をカスタムしたバージョンを利用しています。
+
+[すべてのベンチマークを見る](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): 一定時間内を満たした総試行回数。高いとよりよい結果を示している。
+- (2): 1試行にかかった時間(ns/op)。低いと良い。
+- (3): ヒープメモリ。低いと良い。
+- (4): 1試行回数当たりの平均ヒープアロケーション。低いと良い。
diff --git a/src/content/docs/ja/docs/deployment/index.md b/src/content/docs/ja/docs/deployment/index.md
new file mode 100644
index 000000000..53e55fc7e
--- /dev/null
+++ b/src/content/docs/ja/docs/deployment/index.md
@@ -0,0 +1,20 @@
+---
+title: "Deployment"
+
+sidebar:
+ order: 6
+---
+
+Ginのプロジェクトはあらゆるクラウドサービス上に簡単にデプロイできます。
+
+## [Render](https://render.com)
+
+RenderはGoをネイティブサポートするモダンなクラウドプラットフォームで、フルマネージドSSL、データベース、ダウンタイムのないデプロイ、HTTP/2、そしてwebsocketもサポートしています。
+
+Renderの[Ginプロジェクトのデプロイガイド](https://render.com/docs/deploy-go-gin)に詳細な記述があります。
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAEでGoのアプリケーションをデプロイするには2つの方法があります。スタンダード環境は簡単に使用できますが、カスタマイズ性は低く、セキュリティ上の問題で[システムコール](https://github.com/gin-gonic/gin/issues/1639)の使用は避けるべきです。フレキシブル環境はあらゆるフレームワークやライブラリが使用できます。
+
+さらに学んだり、より適した環境を探すには[Google App Engine 上での Go の使用](https://cloud.google.com/appengine/docs/go/)を参考にしてください。
diff --git a/src/content/docs/ja/docs/examples/ascii-json.md b/src/content/docs/ja/docs/examples/ascii-json.md
new file mode 100644
index 000000000..cfb04242f
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/ascii-json.md
@@ -0,0 +1,26 @@
+---
+title: "AsciiJSON"
+
+---
+
+AsciiJSON メソッドを使うことで、ASCII 文字列以外をエスケープした
+ASCII 文字列のみの JSON を出力できます。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"} が出力されます
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ja/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/ja/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..593e4cd05
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,54 @@
+---
+title: "body を異なる構造体にバインドするには"
+
+---
+
+通常のリクエスト本文をバインドするメソッドたちは、`c.Request.Body` を消費します。よってそれらのメソッドは複数回呼び出すことができません。
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // この c.ShouldBind メソッドは c.Request.Body を消費し、再利用できなくします。
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // c.Request.Body が EOF なので、常にエラーとなります。
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+複数回呼び出したい場合、`c.ShouldBindBodyWith` を使ってください。
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // このコードは、c.Request.Body を読み込み、そして結果を context に保存します。
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // ここでは、context に保存された body を再利用します。
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // 他のフォーマットも受け付けます。
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` はバインド前に context にリクエスト本文を保存します。この処理は、パフォーマンスにわずかな影響を与えます。バインディングが一度だけで良いなら、このメソッドは使うべきではありません。
+* この機能は `JSON`, `XML`, `MsgPack`,`ProtoBuf` のフォーマットでのみ必要です。`Query`, `Form`, `FormPost`, `FormMultipart` のような他のフォーマットでは `c.ShouldBind()` を何度も呼び出せるので、パフォーマンスへの影響はありません。(Issue [#1341](https://github.com/gin-gonic/gin/pull/1341) も参照ください)
diff --git a/src/content/docs/ja/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/ja/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..f7900823c
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,96 @@
+---
+title: "フォーム投稿されたリクエストを構造体にバインドする"
+
+---
+
+下記のサンプルコードは、カスタム構造体を使っています。
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+`curl` を使った結果です。
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
+**NOTE**: 下記の構造体はサポートしていません。
+
+```go
+type StructX struct {
+ X struct {} `form:"name_x"` // ここが form を持ってしまっている
+}
+
+type StructY struct {
+ Y StructX `form:"name_y"` // ここが form を持ってしまっている
+}
+
+type StructZ struct {
+ Z *StructZ `form:"name_z"` // ここが form を持ってしまっている
+}
+```
+
+端的に言えば、ネストした構造体は `form` を今は持つことができません。
+
+
diff --git a/src/content/docs/ja/docs/examples/bind-html-checkbox.md b/src/content/docs/ja/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..6b9ee36c9
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "HTMLチェックボックスをバインドする"
+
+---
+
+[詳細な情報](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092) はこちら。
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+結果
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/ja/docs/examples/bind-query-or-post.md b/src/content/docs/ja/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..4400bcc57
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "クエリ文字列あるいはポストされたデータをバインドする"
+
+---
+
+[詳細](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292) はこちら。
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // `GET` の場合、`Form` (クエリ文字列) がバインディングのみが使われます
+ // `POST` の場合、まず `JSON` か `XML` か判断するために `content-type` がチェックされ、そして `Form` (フォームデータ) が使われます。
+ // 詳細は https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48 を参照
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+以下のコードでテストできます。
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/ja/docs/examples/bind-single-binary-with-template.md b/src/content/docs/ja/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..c3afa7d7f
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,48 @@
+---
+title: "テンプレートを含めた1つのバイナリをビルドする"
+
+---
+
+[go-assets](https://github.com/jessevdk/go-assets) を利用することで、サーバーアプリケーションを、テンプレートを含む1つのバイナリにまとめることができます。
+
+[go-assets]: https://github.com/jessevdk/go-assets
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate は go-assets-builder によって埋め込まれたテンプレートたちをロードします。
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+完全なサンプルコードは、[assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) を見てください。
+
+
diff --git a/src/content/docs/ja/docs/examples/bind-uri.md b/src/content/docs/ja/docs/examples/bind-uri.md
new file mode 100644
index 000000000..b51626248
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/bind-uri.md
@@ -0,0 +1,38 @@
+---
+title: "URLをバインドする"
+
+---
+
+[詳細](https://github.com/gin-gonic/gin/issues/846) はこちら。
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+以下のコードでテストできます。
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
+
diff --git a/src/content/docs/ja/docs/examples/binding-and-validation.md b/src/content/docs/ja/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..7baa1d050
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "モデルへのバインディングとバリデーションする"
+
+---
+
+リクエストボディをある型にバインドするには、モデルへのバインディングを利用してください。Gin は今のところ JSON, XML, YAML と標準的なフォームの値(foo=bar&boo=baz)をサポートしています。
+
+Gin は [**go-playground/validator/v10**](https://github.com/go-playground/validator) をバリデーションに使用しています。 タグの使い方のすべてのドキュメントを読むには [ここ](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags) を参照してください。
+
+バインドしたいすべてのフィールドに対応するタグを設定する必要があることに注意してください。たとえば、JSONからバインドする場合は、`json:"fieldname"` を設定します。
+
+また、Gin は2種類のバインドのためのメソッドを用意しています。
+- **種類** - Must bind
+ - **メソッド** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **挙動** - これらのメソッドは、内部では `MustBindWith` メソッドを使っています。もしバインド時にエラーがあった場合、ユーザーからのリクエストは `c.AbortWithError(400, err).SetType(ErrorTypeBind)` で中止されます。この処理は、ステータスコード 400 を設定し、`Content-Type` ヘッダーに `text/plain; charset=utf-8` をセットします。もしこのあとにステータスコードを設定しようとした場合、`[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422` という注意メッセージが表示されるので注意してください。もしこの挙動をよりコントロールする必要がある場合、`ShouldBind` という同様のメソッドを利用することを検討してください。
+- **種類** - Should bind
+ - **メソッド** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **挙動** - これらのメソッドは、内部では `ShouldBindWith` メソッドを使っています。もしバインド時にエラーがあった場合、エラーが返ってくるので、開発者の責任で、適切にエラーやリクエストをハンドリングします。
+
+`Bind` メソッドを使用するとき、Gin は Content-Type ヘッダーに応じて何のバインダーでバインドするか推測しようとします。もし何のバインダーでバインドするかわかるならば、`MustBindWith` や `ShouldBindWith` が使えます。
+
+また、どのフィールドが必須か指定することができます。もしフィールドが、`binding:"required"` 指定されていて、バインディングの際に値が空であれば、エラーが返ります。
+
+```go
+// JSON からバインドする
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // JSON でバインドする例 ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // XML でバインドする例 (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // HTML Form からバインドする例 (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // このコードは、content-type ヘッダーから類推して HTML Form でバインドする
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てる
+ router.Run(":8080")
+}
+```
+
+### リクエスト例
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### バリデーションをスキップする
+
+上記の `curl` コマンドのサンプルを実行すると、エラーが返ります。これはサンプルコードで `binding:"required"` が `Password` フィールドに指定されているからです。`binding:"-"` を `Password` フィールドに指定することで、上記のサンプルを実行してもエラーは返らなくなります。
diff --git a/src/content/docs/ja/docs/examples/controlling-log-output-coloring.md b/src/content/docs/ja/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..556f9bb1c
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "ログ出力の色付けを制御する"
+
+---
+
+デフォルトでは、ログ出力は検出された TTY に応じて色付けされます。
+
+ログの色付けを止めるには:
+
+```go
+func main() {
+ // ログの色付けを無効にする:
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+常にログの色付けをするには:
+
+```go
+func main() {
+ // ログの色付けを常に有効にする:
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ja/docs/examples/cookie.md b/src/content/docs/ja/docs/examples/cookie.md
new file mode 100644
index 000000000..638d28558
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "cookieの設定と取得"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/ja/docs/examples/custom-http-config.md b/src/content/docs/ja/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..870d7f670
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/custom-http-config.md
@@ -0,0 +1,35 @@
+---
+title: "カスタム HTTP 設定"
+
+---
+
+以下のように `http.ListenAndServe()` を直接使ってください。
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+あるいは
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/custom-log-format.md b/src/content/docs/ja/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..7e17f736b
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "カスタムログファイル"
+
+---
+
+例:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter ミドルウェアは gin.DefaultWriter にログを出力する
+ // デフォルトでは gin.DefaultWriter は os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**出力例**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/ja/docs/examples/custom-middleware.md b/src/content/docs/ja/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..a553491ff
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/custom-middleware.md
@@ -0,0 +1,44 @@
+---
+title: "カスタムミドルウェア"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // サンプル変数を設定
+ c.Set("example", "12345")
+
+ // request 処理の前
+
+ c.Next()
+
+ // request 処理の後
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // 送信予定のステータスコードにアクセスする
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // "12345" が表示される
+ log.Println(example)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/custom-validators.md b/src/content/docs/ja/docs/examples/custom-validators.md
new file mode 100644
index 000000000..d7a7466b4
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/custom-validators.md
@@ -0,0 +1,70 @@
+---
+title: "カスタムバリデーション"
+
+---
+
+カスタムしたバリデーションを使用することもできます。[サンプルコード](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) も見てみてください。
+
+```go
+package main
+
+import (
+ "net/http"
+ "reflect"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking はバリデーションされてバインドされたデータを持ちます
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+func bookableDate(
+ v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
+ field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
+) bool {
+ if date, ok := field.Interface().(time.Time); ok {
+ today := time.Now()
+ if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
+{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) もこの方法で登録できます。
+[struct-lvl-validation のサンプルコード](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) を見ることでより学べます。
diff --git a/src/content/docs/ja/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/ja/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..183cedd4c
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,45 @@
+---
+title: "ルーティングログのフォーマットを定義する"
+
+---
+
+デフォルトのルーティングログは以下のようになります。
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+もしログのフォーマットを定義したい(JSONやキーバリュー形式、その他)なら、`gin.DebugPrintRouteFunc` を定義することで可能です。
+以下のサンプルコードでは、すべてのルーティングを標準の log パッケージで記録していますが、必要に応じて最適な別のログツールを利用することも可能です。
+
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // http://0.0.0.0:8080 でサーバーを立てる
+ r.Run()
+}
+```
diff --git a/src/content/docs/ja/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/ja/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..013c07163
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,37 @@
+---
+title: "ミドルウェア内の Goroutine"
+
+---
+
+新しい goroutine をミドルウェアやハンドラー内で生成する場合、goroutine の内部でオリジナルの context を **使用しないでください**。読み込み用のコピーを使ってください。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // goroutine 内で使用するコピーを生成します
+ cCp := c.Copy()
+ go func() {
+ // time.Sleep() を使って、長時間かかる処理をシミュレートします。5秒です。
+ time.Sleep(5 * time.Second)
+
+ // コピーされた context である "cCp" を使ってください。重要!
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // time.Sleep() を使って、長時間かかる処理をシミュレートします。5秒です。
+ time.Sleep(5 * time.Second)
+
+ // goroutine を使ってなければ、context をコピーする必要はありません。
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/graceful-restart-or-stop.md b/src/content/docs/ja/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..86b998af8
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,85 @@
+---
+title: "graceful restart と stop"
+
+---
+
+graceful restart と stop をしたいですか?
+いくつかの方法があります。
+
+[fvbock/endless](https://github.com/fvbock/endless) を使って、デフォルトの `ListenAndServe` を置き換えることができます。詳細は Issue [#296](https://github.com/gin-gonic/gin/issues/296) を参照ください。
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+endless の代わりは以下があります。
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+もし Go 1.8 を使っているなら、これらのライブラリを使う必要はないかもしれません!http.Server 組み込みの [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) メソッドを、graceful shutdowns に利用することを検討してみてください。詳細は Gin の [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) サンプルコードを見てみてください。
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // サービスの接続
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // シグナル割り込みを待ち、タイムアウト時間が5秒の graceful shutdown をする
+ quit := make(chan os.Signal, 1)
+ // kill (no param) default send syscanll.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // ctx.Done() をキャッチする。5秒間のタイムアウト。
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/grouping-routes.md b/src/content/docs/ja/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..ac9c06c02
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/grouping-routes.md
@@ -0,0 +1,30 @@
+---
+title: "ルーティングをグループ化する"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // v1 のグループ
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // v2 のグループ
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/html-rendering.md b/src/content/docs/ja/docs/examples/html-rendering.md
new file mode 100644
index 000000000..10768fae0
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML をレンダリングする"
+
+---
+
+LoadHTMLGlob() あるいは LoadHTMLFiles() メソッドを使用してください。
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+別のディレクトリにある同名のテンプレートを使う方法です。
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### カスタムテンプレートエンジン
+
+独自のHTMLテンプレートエンジンを使うこともできます。
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### カスタムデリミタ
+
+独自のデリミタを使用することもできます。
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### カスタムテンプレート関数
+
+詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/template) を参照。
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/ja/docs/examples/http-method.md b/src/content/docs/ja/docs/examples/http-method.md
new file mode 100644
index 000000000..4fac17962
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/http-method.md
@@ -0,0 +1,27 @@
+---
+title: "GET,POST,PUT,PATCH,DELETE,OPTIONS メソッドを使う"
+
+---
+
+```go
+func main() {
+ // デフォルトのミドルウェアで新しい gin ルーターを作成する
+ // logger とアプリケーションクラッシュをキャッチする recovery ミドルウェア
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // デフォルトではポート 8080 が利用されるが、
+ // 環境変数 PORT を指定していればそちらが優先される。
+ router.Run()
+ // router.Run(":3000") と書くことでポートをハードコーディングできる
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/http2-server-push.md b/src/content/docs/ja/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..b6fad27e9
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/http2-server-push.md
@@ -0,0 +1,52 @@
+---
+title: "HTTP/2 サーバープッシュ"
+
+---
+
+http.Pusher は **go1.8+** 以降でのみサポートしています。 詳細な情報は [golang blog](https://blog.golang.org/h2push) を見てください。
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // サーバープッシュするために pusher.Push() を使う
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // https://127.0.0.1:8080 でサーバーを立てる
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/index.md b/src/content/docs/ja/docs/examples/index.md
new file mode 100644
index 000000000..ae97f0d4f
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "APIの使い方のサンプル"
+
+sidebar:
+ order: 6
+---
+
+このセクションでは APIの使い方のサンプルを挙げます。
diff --git a/src/content/docs/ja/docs/examples/jsonp.md b/src/content/docs/ja/docs/examples/jsonp.md
new file mode 100644
index 000000000..df51ec131
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/jsonp.md
@@ -0,0 +1,27 @@
+---
+title: "JSONP をレンダリングする"
+
+---
+
+JSONP を使うことで、別のドメインのサーバーからレスポンスを受け取ることができます。callback をクエリ文字列に指定することで、レスポンスに callback を追加します。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback は x です。
+ // x({\"foo\":\"bar\"}) が出力されます。
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/ja/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..7bdda1b86
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,32 @@
+---
+title: "クエリ文字列やフォーム投稿によるパラメータをマッピングする"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/ja/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..e50521516
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,43 @@
+---
+title: "Multipart/Urlencoded されたデータをバインドする"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // 明示的にバインディングを定義して、multipart form をバインドすることができます。
+ // c.ShouldBindWith(&form, binding.Form)
+ // あるいは、ShouldBind メソッドを使うことで、シンプルに自動でバインドすることもできます。
+ var form LoginForm
+ // このケースでは正しいバインディングが自動で選択されます。
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+以下のコードでテストできます。
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/multipart-urlencoded-form.md b/src/content/docs/ja/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..ea82458b8
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,24 @@
+---
+title: "Multipart/Urlencoded フォーム"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/multiple-template.md b/src/content/docs/ja/docs/examples/multiple-template.md
new file mode 100644
index 000000000..bad43f9eb
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/multiple-template.md
@@ -0,0 +1,9 @@
+---
+title: "複数のテンプレート"
+
+---
+
+Gin はデフォルトでは、1つの html.Template しか使用できません。
+go 1.6 の `block template` のような機能が使用できる [a multitemplate render](https://github.com/gin-contrib/multitemplate) を検討してください。
+
+
diff --git a/src/content/docs/ja/docs/examples/only-bind-query-string.md b/src/content/docs/ja/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..db458ef69
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/only-bind-query-string.md
@@ -0,0 +1,39 @@
+---
+title: "クエリ文字列のみバインドする"
+
+---
+
+`ShouldBindQuery` 関数はクエリ文字列のみをバインドし、POSTデータをバインドしません。[詳細](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017) はこちら。
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+
+```
+
diff --git a/src/content/docs/ja/docs/examples/param-in-path.md b/src/content/docs/ja/docs/examples/param-in-path.md
new file mode 100644
index 000000000..fe9e178b0
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/param-in-path.md
@@ -0,0 +1,29 @@
+---
+title: "パスに含まれるパラメータ"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // このハンドラは /user/john にはマッチするが、/user/ や /user にはマッチしない
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // しかし、下記は /user/john/ と /user/john/send にマッチする
+ // もしほかのルーターが /user/john にマッチしなければ、/user/john/ にリダイレクトしてくれる
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/pure-json.md b/src/content/docs/ja/docs/examples/pure-json.md
new file mode 100644
index 000000000..d5bf9cc60
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/pure-json.md
@@ -0,0 +1,33 @@
+---
+title: "PureJSON"
+
+---
+
+通常、JSON メソッドは `<` のようなHTML 文字を `\u003c` のような Unicode に置き換えます。
+もしこのような文字をそのままエンコードしたい場合、PureJSON メソッドを代わりに使用してください。
+この機能は、Go 1.6 以下では使えません。
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Unicode を返します
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // そのままの文字を返します
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/query-and-post-form.md b/src/content/docs/ja/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..82db6daf5
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/query-and-post-form.md
@@ -0,0 +1,34 @@
+---
+title: "フォーム投稿によるクエリ文字列"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/querystring-param.md b/src/content/docs/ja/docs/examples/querystring-param.md
new file mode 100644
index 000000000..271300336
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/querystring-param.md
@@ -0,0 +1,22 @@
+---
+title: "クエリ文字列のパラメータ"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // クエリ文字列のパラメータは、既存の Request オブジェクトによって解析される。
+ // このルーターは、/welcome?firstname=Jane&lastname=Doe にマッチしたURLにアクセスすると、レスポンスを返す
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname") へのショートカット
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/redirects.md b/src/content/docs/ja/docs/examples/redirects.md
new file mode 100644
index 000000000..056b74820
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/redirects.md
@@ -0,0 +1,35 @@
+---
+title: "リダイレクト"
+
+---
+
+HTTP リダイレクトするのは簡単です。内部パス、外部URL両方のリダイレクトに対応しています。
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+POSTからのHTTPリダイレクトのissueは [#444](https://github.com/gin-gonic/gin/issues/444) を参照してください。
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Router でリダイレクトするには、下記のように `HandleContext` メソッドを使ってください。
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
+
+
+
diff --git a/src/content/docs/ja/docs/examples/rendering.md b/src/content/docs/ja/docs/examples/rendering.md
new file mode 100644
index 000000000..ccd0394d8
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/rendering.md
@@ -0,0 +1,56 @@
+---
+title: "XML, JSON, YAML, ProtoBuf をレンダリングする"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H は map[string]interface{} へのショートカットです。
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // 構造体を使うこともできます。
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // msg.Name は JSON 内で "user" となることに注意してください
+ // 右記が出力されます : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // protobuf の定義は testdata/protoexample にかかれています。
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // データはレスポンス時にバイナリデータになることに注意してください。
+ // protoexample.Test の protobuf でシリアライズされたデータが出力されます。
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/run-multiple-service.md b/src/content/docs/ja/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..7cb113c08
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/run-multiple-service.md
@@ -0,0 +1,83 @@
+---
+title: "Gin を使って複数のサービスを稼働させる"
+
+---
+
+[issue](https://github.com/gin-gonic/gin/issues/346) を見て、以下のサンプルコードを試してみてください。
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
diff --git a/src/content/docs/ja/docs/examples/secure-json.md b/src/content/docs/ja/docs/examples/secure-json.md
new file mode 100644
index 000000000..0b65dca8e
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/secure-json.md
@@ -0,0 +1,27 @@
+---
+title: "SecureJSON"
+
+---
+
+SecureJSON メソッドを使うことで、JSON ハイジャックを防げます。与えられた構造体が Array であれば、
+デフォルトで `"while(1),"` がレスポンスに含まれます。
+
+```go
+func main() {
+ r := gin.Default()
+
+ // 別の prefix を使うこともできます
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // while(1);["lena","austin","foo"] が出力されます。
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ja/docs/examples/security-headers.md b/src/content/docs/ja/docs/examples/security-headers.md
new file mode 100644
index 000000000..fa5d348ea
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/security-headers.md
@@ -0,0 +1,76 @@
+---
+title: "セキュリティ・ヘッダ"
+
+---
+
+セキュリティヘッダの使用は、一般的なセキュリティの脆弱性からウェブアプリケーションを守るために重要です。この例では、Gin アプリケーションにセキュリティヘッダーを追加する方法と、ホストヘッダーインジェクションに関連する攻撃(SSRF、Open Redirection)を回避する方法を示します。
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+`curl`でテストできます:
+
+
+```bash
+// ヘッダーのチェック
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// ホスト・ヘッダー・インジェクションのチェック
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/ja/docs/examples/serving-data-from-reader.md b/src/content/docs/ja/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..0abac2721
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,30 @@
+---
+title: "io.Reader からのデータを返す"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/serving-static-files.md b/src/content/docs/ja/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..57d80fa76
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "静的ファイルを返す"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ja/docs/examples/support-lets-encrypt.md b/src/content/docs/ja/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..2451acae3
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,61 @@
+---
+title: "Let's Encrypt のサポート"
+
+---
+
+1行の Let's Encrypt HTTPS サーバーのサンプルコードです。
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+カスタム autocert manager を利用したサンプルコードです。
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/upload-file/index.md b/src/content/docs/ja/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..ed7b6105b
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "ファイルアップロード"
+
+---
+
+このセクションではファイルのアップロードAPIの使い方を列挙します。
diff --git a/src/content/docs/ja/docs/examples/upload-file/multiple-file.md b/src/content/docs/ja/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..4033edb60
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "複数のファイル"
+
+---
+
+詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple) 参照のこと.
+
+```go
+func main() {
+ router := gin.Default()
+ // マルチパートフォームが利用できるメモリの制限を設定する(デフォルトは 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // マルチパートフォーム
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // 特定のディレクトリにファイルをアップロードする
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+`curl` での使い方:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/ja/docs/examples/upload-file/single-file.md b/src/content/docs/ja/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..11d5baae6
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/upload-file/single-file.md
@@ -0,0 +1,38 @@
+---
+title: "単一のファイル"
+
+---
+
+issue [#774](https://github.com/gin-gonic/gin/issues/774) と、詳細は [サンプルコード](https://github.com/gin-gonic/examples/tree/master/upload-file/single) 参照。
+
+`file.Filename` を信用する**べきではありません**。 [MDN の `Content-Disposition`](https://developer.mozilla.org/ja/docs/Web/HTTP/Headers/Content-Disposition#Directives) と [#1693](https://github.com/gin-gonic/gin/issues/1693) を参照。
+
+> ファイル名は常にオプションであり、アプリケーションで闇雲に使用しないでください。パス情報を削除し、サーバーのファイルシステムルールに変換すべきです。
+
+```go
+func main() {
+ router := gin.Default()
+ // マルチパートフォームが利用できるメモリの制限を設定する(デフォルトは 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // 単一のファイル
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // 特定のディレクトリにファイルをアップロードする
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+`curl` での使い方:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
+
diff --git a/src/content/docs/ja/docs/examples/using-basicauth-middleware.md b/src/content/docs/ja/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..e0ec502f5
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,42 @@
+---
+title: "BasicAuth ミドルウェアを使う"
+
+---
+
+```go
+// 秘匿されたデータをシミュレートする
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // gin.BasicAuth() ミドルウェアを使用したグループ
+ // gin.Accounts は map[string]string へのショートカットです。
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets エンドポイントは localhost:8080/admin/secrets です。
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // BasicAuth ミドルウェアで設定されたユーザー名にアクセスします。
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // 0.0.0.0:8080 でサーバーを立てます。
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/using-middleware.md b/src/content/docs/ja/docs/examples/using-middleware.md
new file mode 100644
index 000000000..9995e8763
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "ミドルウェアを利用する"
+
+---
+
+```go
+func main() {
+ // デフォルトのミドルウェアが何もない router を作成する
+ r := gin.New()
+
+ // グローバルなミドルウェア
+ // Logger ミドルウェアは GIN_MODE=release を設定してても、 gin.DefaultWriter にログを出力する
+ // gin.DefaultWriter はデフォルトでは os.Stdout。
+ r.Use(gin.Logger())
+
+ // Recovery ミドルウェアは panic が発生しても 500 エラーを返してくれる
+ r.Use(gin.Recovery())
+
+ // 個別のルーティングに、ミドルウェアを好きに追加することもできる
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // 認証が必要なグループ
+ // authorized := r.Group("/", AuthRequired())
+ // 下記と同一
+ authorized := r.Group("/")
+ // 個別のグループのミドルウェア。この例では、AuthRequired() ミドルウェアを認証が必要なグループに設定している。
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // ネストしたグループ
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // 0.0.0.0:8080 でサーバーを立てる
+ r.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/without-middleware.md b/src/content/docs/ja/docs/examples/without-middleware.md
new file mode 100644
index 000000000..517eeef29
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "デフォルトで設定されるミドルウェアがない空の Gin を作成する"
+
+---
+
+```go
+r := gin.New()
+```
+
+下記のコードではなく、上記のコードを利用する
+
+```go
+// Default は Logger と Recovery ミドルウェアが既にアタッチされている
+r := gin.Default()
+```
+
+
diff --git a/src/content/docs/ja/docs/examples/write-log.md b/src/content/docs/ja/docs/examples/write-log.md
new file mode 100644
index 000000000..5f3e56909
--- /dev/null
+++ b/src/content/docs/ja/docs/examples/write-log.md
@@ -0,0 +1,27 @@
+---
+title: "ログファイルへ書き込むには"
+
+---
+
+```go
+func main() {
+ // コンソール出力時の色を無効にする。ログファイルに書き込むならば、色は不要なので。
+ gin.DisableConsoleColor()
+
+ // ファイルへログを書き込む
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // ログに書き込みつつ、コンソールにも出力する場合、下記のコードを利用する。
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+
diff --git a/src/content/docs/ja/docs/faq/index.md b/src/content/docs/ja/docs/faq/index.md
new file mode 100644
index 000000000..20f2e9fe8
--- /dev/null
+++ b/src/content/docs/ja/docs/faq/index.md
@@ -0,0 +1,8 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: Github の Issue でよく聞かれる質問を書く
diff --git a/src/content/docs/ja/docs/features/index.md b/src/content/docs/ja/docs/features/index.md
new file mode 100644
index 000000000..9318e97b4
--- /dev/null
+++ b/src/content/docs/ja/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "機能"
+
+sidebar:
+ order: 4
+---
+
+#### Gin v1 の安定性
+
+- ヒープメモリの拡張が0のルーター
+
+- 最速の http ルーターとフレームワーク
+
+- 一揃いのユニットテストをすべて満たしている
+
+- バトルがテストされている
+
+- APIは固まっており、新しいバージョンが既存のコードを壊すことはない
diff --git a/src/content/docs/ja/docs/index.md b/src/content/docs/ja/docs/index.md
new file mode 100644
index 000000000..aeca095d2
--- /dev/null
+++ b/src/content/docs/ja/docs/index.md
@@ -0,0 +1,21 @@
+---
+title: "ドキュメント"
+linkTitle: "ドキュメント"
+sidebar:
+ order: 1
+---
+
+## Gin ってなに?
+
+Gin は Golang で書かれた Web アプリケーションフレームワークです。[martini](https://github.com/go-martini/martini) に似たAPIを持ちながら、[httprouter](https://github.com/julienschmidt/httprouter) のおかげでそれより40倍以上も速いパフォーマンスがあります。良いパフォーマンスと生産性が必要であれば、Gin が好きになれるでしょう。
+
+## Gin はどうやって使うの?
+
+APIの使い方の[サンプル](https://github.com/gin-gonic/examples)と、公開されている gin を利用しているプロダクトの[リスト](./users)を提供しています。
+
+## Gin にコントリビュートするには?
+
+* 議論の場で人々を助けてあげてください
+* Gin を利用した成功事例を教えてください
+* Gin を良くするにはどうすればいいか教えてください
+* 既に存在するライブラリにコントリビュートしてください
diff --git a/src/content/docs/ja/docs/introduction/index.md b/src/content/docs/ja/docs/introduction/index.md
new file mode 100644
index 000000000..fb777aa45
--- /dev/null
+++ b/src/content/docs/ja/docs/introduction/index.md
@@ -0,0 +1,39 @@
+---
+title: "まず始めに"
+
+sidebar:
+ order: 1
+---
+
+Gin は Golang で書かれた Web アプリケーションフレームワークです。martini に似たAPIを持ちながら、httprouter のおかげでそれより40倍以上も速いパフォーマンスがあります。良いパフォーマンスと生産性が必要であれば、Gin が好きになれるでしょう。
+
+この章では、Gin とは何か、どんな問題を解決してくれるのか、そしてどのようにあなたのプロジェクトを助かるのかを説明します。
+
+あなたがプロジェクトで Gin を使う準備がもし整っているのならば、[クイックスタート](../quickstart)を見てください。
+
+# 機能
+
+#### 高速
+基数木ベースのルーティング、そして小さなメモリ使用量。reflection は使っていません。予測可能なAPIパフォーマンス。
+
+#### ミドルウェアの支援
+受け取った HTTP リクエストは、一連のミドルウェアと、最終的なアクションによって処理されます。
+例:ログ出力、認証、GZIP 圧縮、そして最終的にDBにメッセージを投稿します。
+
+#### クラッシュフリー
+Gin は、HTTP リクエストの処理中に発生した panic を recover します。これにより、サーバーは常にユーザーからの応答を返すことができます。またこれにより例えば panic を Sentry に送ったりすることも可能です!
+
+#### JSON バリデーション
+Gin は JSON によるリクエストを解析してバリデーションすることができます。例えば必要な値の存在をチェックすることができます。
+
+#### ルーティングのグループ化
+ルーティングをもっとよく整理しましょう。認証が必要かどうか、異なるバージョンのAPIかどうか...加えて、パフォーマンスを低下させることなく、無制限にネストしたグループ化を行うことができます。
+
+#### エラー管理
+Ginは、HTTP リクエスト中に発生したすべてのエラーを収集するための便利な方法を提供します。最終的に、ミドルウェアはそれらをログファイル、データベースに書き込み、ネットワーク経由で送信することができます。
+
+#### 組み込みのレンダリング
+Ginは、JSON、XML、およびHTMLでレンダリングするための使いやすいAPIを提供します。
+
+#### 拡張性
+とても簡単に新しいミドルウェアを作成できます。サンプルコードをチェックしてみてください。
diff --git a/src/content/docs/ja/docs/jsoniter/index.md b/src/content/docs/ja/docs/jsoniter/index.md
new file mode 100644
index 000000000..da2e4be2c
--- /dev/null
+++ b/src/content/docs/ja/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## [jsoniter](https://github.com/json-iterator/go) でビルドする
+
+Gin はデフォルトの json パッケージとして `encoding/json` を使っていますが、他のタグからビルドすることで、[jsoniter](https://github.com/json-iterator/go) を使うこともできます。
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/ja/docs/quickstart/index.md b/src/content/docs/ja/docs/quickstart/index.md
new file mode 100644
index 000000000..28fbcf271
--- /dev/null
+++ b/src/content/docs/ja/docs/quickstart/index.md
@@ -0,0 +1,87 @@
+---
+title: "クイックスタート"
+
+sidebar:
+ order: 2
+---
+
+このクイックスタートでは、コードの集まりからの洞察を収集し、どのようにするかを学びます。
+
+## 要件
+
+- Gin を利用するには Go 1.16 以上が必要です。
+
+## インストール
+
+Gin をインストールするには、まず Go のインストールおよび Go のワークスペースを作ることが必要です。
+
+1. ダウンロードしてインストールする
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. コード内でインポートする
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (オプション) `net/http` をインポートする。`http.StatusOK` のような定数を使用する場合に必要です
+
+```go
+import "net/http"
+```
+
+1. プロジェクトフォルダを作り、 `cd` で中に入ります。
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. 開始用テンプレートをプロジェクトディレクトリにコピーする
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. プロジェクトを実行する
+
+```sh
+$ go run main.go
+```
+
+## Getting Started
+
+> Go のコードを書いて実行する方法がわからない? [ここをクリックしてください](https://golang.org/doc/code.html).
+
+まず、`example.go` を作成します。
+
+```sh
+# 後述のコードが、example.go のファイルにあるとします。
+$ touch example.go
+```
+
+次に、下記のコードを `example.go` に書きます。
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // 0.0.0.0:8080 でサーバーを立てます。
+}
+```
+
+そして `go run example.go` でコードを実行します。
+
+```
+# example.go を実行し、ブラウザで 0.0.0.0:8080/ping にアクセスする
+$ go run example.go
+```
diff --git a/src/content/docs/ja/docs/testing/index.md b/src/content/docs/ja/docs/testing/index.md
new file mode 100644
index 000000000..a79a42a9d
--- /dev/null
+++ b/src/content/docs/ja/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "テスト"
+
+sidebar:
+ order: 7
+---
+
+##### Gin でテストコードを書くには
+
+`net/http/httptest` パッケージが、HTTP テストをするには好ましい方法です。
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+テストコードの例は以下のようになります。
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/ja/docs/users/index.md b/src/content/docs/ja/docs/users/index.md
new file mode 100644
index 000000000..6fb8465e2
--- /dev/null
+++ b/src/content/docs/ja/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Gin のユーザー"
+
+sidebar:
+ order: 8
+---
+
+##### [Gin](https://github.com/gin-gonic/gin) を利用している素晴らしいプロジェクト一覧。
+
+* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
+
+* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+
+* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+
+* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
+
+* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
+
+* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/src/content/docs/ja/index.mdx b/src/content/docs/ja/index.mdx
new file mode 100644
index 000000000..f8da26e77
--- /dev/null
+++ b/src/content/docs/ja/index.mdx
@@ -0,0 +1,53 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Go 言語のためのフル機能の最速 Web フレームワーク。水晶のようにクリア。
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: 詳しく見る
+ link: /ja/docs/
+ icon: right-arrow
+ - text: Download
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## Ginとは何か
+
+Gin は、Golang で書かれた Web フレームワークです。 martini に似た API を持ちながら、非常に優れたパフォーマンスを発揮し、最大で40倍高速であることが特徴です。 性能と優れた生産性が必要なら、きっと Gin が好きになれるでしょう。
+
+
+
+ 基数木(redix tree)を元にしたルーティング、小さなメモリフットプリント、リフレクションなし、予測可能な API 性能などの特徴があります。
+
+
+ 受信したHTTPリクエストをミドルウェアのチェーンと最終的なアクションによりハンドリングできます。たとえば、ロガー、認証、GZIP、さらに DB へのメッセージのポストなどが可能です。
+
+
+ Gin は、HTTP リクエスト中に発生した panic をキャッチし、回復することが可能です。これにより、サーバーが常に利用可能な状態になります。さらに、この panic を Sentry などに報告することもできます。
+
+
+ Gin はリクエストの JSON をパース・検証できます。たとえば、必須の値が存在するかどうかをチェックできます。
+
+
+ ルートを上手く組織化しましょう。認証が必要なページと必要のないページ、異なるバージョンの API などを区別できます。さらに、各グループは性能劣化なしに無制限にネストできます。
+
+
+ Gin は HTTP リクエスト中に発生したすべてのエラーを収集する便利な手段を提供します。最終的に、ミドルウェアによって、ログファイルへの書き込み、データベースへの格納、ネットワーク越しの送信などが行われます。
+
+
+ Gin は JSON、XML、HTML のレンダリングのための簡単に使える API を提供します。
+
+
+ 新しいミドルウェアの作成は非常に簡単です。サンプルコードを見てみてください。
+
+
+
+
+
diff --git a/src/content/docs/ko-kr/blog/index.md b/src/content/docs/ko-kr/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/ko-kr/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/ko-kr/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/ko-kr/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/ko-kr/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/ko-kr/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/ko-kr/blog/releases/release13.md b/src/content/docs/ko-kr/blog/releases/release13.md
similarity index 100%
rename from content/ko-kr/blog/releases/release13.md
rename to src/content/docs/ko-kr/blog/releases/release13.md
diff --git a/content/ko-kr/blog/releases/release14.md b/src/content/docs/ko-kr/blog/releases/release14.md
similarity index 100%
rename from content/ko-kr/blog/releases/release14.md
rename to src/content/docs/ko-kr/blog/releases/release14.md
diff --git a/content/ko-kr/blog/releases/release15.md b/src/content/docs/ko-kr/blog/releases/release15.md
similarity index 100%
rename from content/ko-kr/blog/releases/release15.md
rename to src/content/docs/ko-kr/blog/releases/release15.md
diff --git a/src/content/docs/ko-kr/docs/benchmarks/index.md b/src/content/docs/ko-kr/docs/benchmarks/index.md
new file mode 100644
index 000000000..ad3f250d1
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "벤치마크"
+
+sidebar:
+ order: 3
+---
+
+Gin은 [HttpRouter](https://github.com/julienschmidt/httprouter)을 커스텀 한 버전을 사용합니다.
+
+[모든 벤치마크 보기](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| 벤치마크 이름 | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): 일정한 시간 내에 실행된 총횟수, 높을수록 더 좋은 결과를 뜻합니다.
+- (2): 1회 실행에 걸린 시간 (ns/op), 낮을수록 좋습니다.
+- (3): 힙 메모리 (B/op), 낮을수록 좋습니다.
+- (4): 1회 실행에 할당된 메모리 평균량 (allocs/op), 낮을수록 좋습니다.
diff --git a/src/content/docs/ko-kr/docs/deployment/index.md b/src/content/docs/ko-kr/docs/deployment/index.md
new file mode 100644
index 000000000..bc76791da
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/deployment/index.md
@@ -0,0 +1,20 @@
+---
+title: "배포"
+
+sidebar:
+ order: 6
+---
+
+Gin 프로젝트는 모든 클라우드 제공 업체에 쉽게 배포 할 수 있습니다.
+
+## [Render](https://render.com)
+
+Render은 Go를 기본 지원하는 최신 클라우드 플랫폼으로, SSL관리, 데이터베이스, 무중단 배포, HTTP/2, websocket을 지원합니다.
+
+Render의 [Gin프로젝트 배포 가이드](https://render.com/docs/deploy-go-gin)를 참조하세요.
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE에는 Go어플리케이션을 배포하는 두 가지 방법이 있습니다. 표준환경은 간단히 사용할 수 있으나, 사용자 정의가 어려우며 보안상의 이유로 [syscalls](https://github.com/gin-gonic/gin/issues/1639)를 사용할 수 없습니다. 가변형 환경은 모든 프레임워크와 라이브러리를 사용할 수 있습니다.
+
+[Google App Engine의 Go](https://cloud.google.com/appengine/docs/go/)에서 자세히 알아보고 자신에게 알맞은 환경을 선택하세요.
diff --git a/src/content/docs/ko-kr/docs/examples/ascii-json.md b/src/content/docs/ko-kr/docs/examples/ascii-json.md
new file mode 100644
index 000000000..dcdd5bb2c
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+이스케이프 된 비 ASCII character를 AsciiJSON을 사용하여 ASCII 전용 JSON을 생성합니다
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // 출력내용 : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..37e5ad19e
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,59 @@
+---
+title: "body를 다른 구조체에 바인드 하기"
+
+---
+
+일반적인 body 바인딩 메소드는 `c.Request.Body`를 소모합니다.
+따라서 이러한 메소드들은 여러번 호출할 수 없습니다.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // 아래의 c.ShouldBind는 c.Request.Body를 소모하며, 재이용이 불가능합니다.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // c.Request.Body가 EOF 이므로 에러가 발생합니다.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+이를 위해 `c.ShouldBindBodyWith`를 사용하여 해결 할 수 있습니다.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // c.Request.Body를 읽고 context에 결과를 저장합니다.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // context에 저장된 body를 읽어 재이용 합니다.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // 다른 형식을 사용할 수도 있습니다.
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith`는 바인딩 전에 context에 body를 저장합니다. 이것은 성능에 약간의
+영향을 미치기 때문에 한번의 바인딩으로 충분하다면, 이 메소드를 사용하지 않는 것이 좋습니다.
+* 이 기능은 `JSON`, `XML`, `MsgPack`,`ProtoBuf` 형식에만 필요합니다.
+`Query`, `Form`, `FormPost`, `FormMultipart`와 같은 다른 형식은 성능에 영향을 주지 않고
+`c.ShouldBind()`에 의해 여러번 호출 될 수 있습니다. (이슈 참고[#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..b2d0c6ec1
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "양식 데이터 리퀘스트를 구조체에 바인드 하기"
+
+---
+
+아래의 예제는 사용자 정의 구조체를 사용합니다:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+`curl` 명령어를 이용한 결과 입니다:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/bind-html-checkbox.md b/src/content/docs/ko-kr/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..06f615a8b
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "html 체크박스를 바인드 하기"
+
+---
+
+[자세한 정보](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)를 확인 하세요.
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+결과:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/bind-query-or-post.md b/src/content/docs/ko-kr/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..048f65f6a
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "쿼리 문자열 혹은 post 데이터를 바인드하기"
+
+---
+
+[자세한 정보](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292)를 확인하세요.
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // `GET`의 경우 `Form` (`query`)만 사용됩니다.
+ // `POST`의 경우, 먼저 `content-type`가 `JSON` 혹은 `XML`을 확인한 다음 `Form` (`form-data`)가 사용됩니다.
+ // 자세한 정보는 https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48 를 참고하세요.
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+다음과 같이 테스트 할 수 있습니다:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/ko-kr/docs/examples/bind-single-binary-with-template.md b/src/content/docs/ko-kr/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..fa93cacd5
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,44 @@
+---
+title: "템플릿을 포함한 단일 바이너리 빌드"
+
+---
+
+[go-assets](https://github.com/jessevdk/go-assets)를 사용하여 템플릿을 포함한 단일 바이너리로 서버를 만들 수 있습니다.
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate은 go-assets-builder에 의해 임베디드 된 템플릿을 로드합니다
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+전체 예제는 [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) 디렉토리에서 확인하세요.
diff --git a/src/content/docs/ko-kr/docs/examples/bind-uri.md b/src/content/docs/ko-kr/docs/examples/bind-uri.md
new file mode 100644
index 000000000..27cb7be8a
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "URI를 바인드하기"
+
+---
+
+[자세한 정보](https://github.com/gin-gonic/gin/issues/846)를 확인하세요.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+다음과 같이 테스트 할 수 있습니다:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/ko-kr/docs/examples/binding-and-validation.md b/src/content/docs/ko-kr/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..f23de115c
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/binding-and-validation.md
@@ -0,0 +1,119 @@
+---
+title: "모델 바인딩과 유효성 검사"
+
+---
+
+리퀘스트 바디를 바인딩하려면 모델 바인딩을 사용하세요. 현재 JSON, XML, YAML 및 표준 form values (foo=bar&boo=baz) 바인딩을 지원합니다.
+
+Gin은 유효성 검사에 [**go-playground/validator/v10**](https://github.com/go-playground/validator)을 사용합니다. 태그 사용법에 대한 전체 문서는 [여기](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags)를 확인하세요.
+
+바인딩 하려는 모든 항목에 대해 해당 바인딩 태그를 설정해야 합니다. 예를 들어, JSON을 바인딩 하려면 `json:"fieldname"`을 설정하세요.
+
+또한, Gin은 바인딩을 위해 2가지 방법을 제공합니다:
+
+- **타입** - Must bind
+ - **메소드** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **동작** - 이 메소드들은 내부에서 `MustBindWith`를 사용합니다. 바인딩 에러가 있는 경우, 리퀘스트는 `c.AbortWithError(400, err).SetType(ErrorTypeBind)`와 함께 중단됩니다. 응답코드는 400으로 설정되며, `Content-Type`헤더에는 `text/plain; charset=utf-8`이 설정됩니다. 이 이후에 응답코드를 설정하려고 하면 `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422` 경고가 발생합니다. 동작을 더 상세하게 제어하고 싶다면 `ShouldBind`와 같은 메소드를 사용하세요.
+- **타입** - Should bind
+ - **메소드** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **동작** - 이 메소드들은 내부에서 `ShouldBindWith`를 사용합니다. 바인딩 에러가 있는 경우, 에러를 적절히 처리하고 반환하는 것은 개발자의 몫입니다.
+
+Gin은 Bind-method를 사용할 때 Content-Type 헤더에 따라 바인더를 유추합니다. 바인딩하는 내용이 확실한 경우 `MustBindWith` 또는 `ShouldBindWith`를 사용할 수 있습니다.
+
+특정 항목을 필수로 지정할 수도 있습니다. 항목이 `binding:"required"`로 설정되어 있으나, 바인딩 할 값이 비어 있다면 에러가 반환됩니다.
+
+```go
+// JSON 바인딩
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // JSON 바인딩 예제 ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // XML 바인딩 예제 (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // HTML form 바인딩 예제 (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // content-type 헤더에 따라 사용할 바인더를 유추합니다.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ router.Run(":8080")
+}
+```
+
+### 요청문 예제
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### 유효성 검사 건너뛰기
+
+위의 `curl` 명령어를 실행하면, 에러가 반환됩니다. 이 예제에서는 `Password`에 `binding:"required"`가 설정되어 있기 때문입니다. `Password`에 `binding:"-"`을 설정한 후 실행하면 에러가 발생하지 않습니다.
diff --git a/src/content/docs/ko-kr/docs/examples/controlling-log-output-coloring.md b/src/content/docs/ko-kr/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..42a3c0f61
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "로그 출력 색상 설정"
+
+---
+
+기본적으로, 출력되는 로그의 색상은 감지된 TTY에 따라 지정 됩니다.
+
+로그에 색상이 적용되지 않습니다:
+
+```go
+func main() {
+ // 로그 색상을 비활성화 합니다
+ gin.DisableConsoleColor()
+
+ // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
+ // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+항상 로그의 색상이 적용됩니다:
+
+```go
+func main() {
+ // 강제적으로 로그의 색상을 지정합니다
+ gin.ForceConsoleColor()
+
+ // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
+ // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/cookie.md b/src/content/docs/ko-kr/docs/examples/cookie.md
new file mode 100644
index 000000000..45426b873
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "쿠키의 설정 및 가져오기"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/custom-http-config.md b/src/content/docs/ko-kr/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..1aef51c79
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "HTTP 구성 사용자 정의"
+
+---
+
+아래와 같이 직접 `http.ListenAndServe()` 를 사용하세요:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+혹은
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/custom-log-format.md b/src/content/docs/ko-kr/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..f6654cf3d
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "로그 파일 사용자 정의"
+
+---
+
+예제:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter 미들웨어는 gin.DefaultWriter에 로그를 작성합니다.
+ // 기본값 gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // 사용자 정의 형식
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**출력 예제**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/ko-kr/docs/examples/custom-middleware.md b/src/content/docs/ko-kr/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..a965e8ea0
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "커스텀 미들웨어"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // 샘플 변수 설정
+ c.Set("example", "12345")
+
+ // Request 이전
+
+ c.Next()
+
+ // Request 이후
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // 송신할 상태 코드에 접근
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // 출력내용: "12345"
+ log.Println(example)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/custom-validators.md b/src/content/docs/ko-kr/docs/examples/custom-validators.md
new file mode 100644
index 000000000..a6f0e53eb
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/custom-validators.md
@@ -0,0 +1,70 @@
+---
+title: "커스텀 유효성 검사"
+
+---
+
+커스텀 유효성 검사를 사용 할 수도있습니다. [예제 코드](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations)를 확인하세요.
+
+```go
+package main
+
+import (
+ "net/http"
+ "reflect"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking은 유효성 검사 후 바인딩 된 데이터를 갖습니다.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+func bookableDate(
+ v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
+ field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
+) bool {
+ if date, ok := field.Interface().(time.Time); ok {
+ today := time.Now()
+ if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
+{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
+```
+
+[구조체 레벨 유효성 검사](https://github.com/go-playground/validator/releases/tag/v8.7)도 이 방법으로 설정 할 수 있습니다.
+[struct-lvl-validation 예제](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations)를 보며 더 많은 것을 배울 수 있습니다.
diff --git a/src/content/docs/ko-kr/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/ko-kr/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..7308b4e52
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "라우트의 로그 형식을 정의"
+
+---
+
+라우트의 기본 로그는 다음과 같습니다:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+만약 로그 형식을 정의 하려면(JSON, 키-값 형식, 그 이외의 형식 등), `gin.DebugPrintRouteFunc`를 사용하여 정의할 수 있습니다.
+아래의 예제는 모든 라우트에 대해 표준 로그 패키지를 사용하고 있지만, 필요에 따라 적절한 다른 도구를 사용하는 것도 가능합니다.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // 서버가 실행 되고 http://0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run()
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/ko-kr/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..cca82848f
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "미들웨어 내부의 Go루틴"
+
+---
+
+미들웨어 혹은 핸들러 내부에서 새로운 Go루틴을 시작하려면, 기존의 context를 **사용해서는 안됩니다.** 읽기 전용으로 복사해서 사용해야 합니다.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // Go루틴 내부에서 사용하기 위한 복사본을 작성합니다.
+ cCp := c.Copy()
+ go func() {
+ // time.Sleep()를 사용하여 장시간(5초) 작업을 시뮬레이션 합니다.
+ time.Sleep(5 * time.Second)
+
+ // 중요! 복사된 context인 "cCp"를 사용하세요.
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // time.Sleep()를 사용하여 장시간(5초) 작업을 시뮬레이션 합니다.
+ time.Sleep(5 * time.Second)
+
+ // Go루틴을 사용하지 않는다면, context를 복사할 필요가 없습니다.
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/graceful-restart-or-stop.md b/src/content/docs/ko-kr/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..76db99cad
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,84 @@
+---
+title: "Graceful 재시작과 정지"
+
+---
+
+웹 서버를 graceful 재시작 혹은 정지를 하고 싶습니까?
+이 작업을 하기 위한 몇 가지 방법이 있습니다.
+
+[fvbock/endless](https://github.com/fvbock/endless)를 사용하여 기본 `ListenAndServe`를 바꿀 수 있습니다. 자세한 내용은 이슈 [#296](https://github.com/gin-gonic/gin/issues/296)를 참조하세요.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+endless의 대안은 다음과 같습니다:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+만약 Go 1.8을 사용한다면, 이 라이브러리를 사용할 필요가 없습니다! Graceful 종료를 위해 http.Server에 포함되어 있는 [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) 메소드를 사용할 것을 검토해보세요. 자세한 내용은 Gin의 [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) 예제에서 확인해 주세요.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // 서비스 접속
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // 5초의 타임아웃으로 인해 인터럽트 신호가 서버를 정상종료 할 때까지 기다립니다.
+ quit := make(chan os.Signal, 1)
+ // kill (파라미터 없음) 기본값으로 syscanll.SIGTERM를 보냅니다
+ // kill -2 는 syscall.SIGINT를 보냅니다
+ // kill -9 는 syscall.SIGKILL를 보내지만 캐치할수 없으므로, 추가할 필요가 없습니다.
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // 5초의 타임아웃으로 ctx.Done()을 캐치합니다.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/grouping-routes.md b/src/content/docs/ko-kr/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..41792adfc
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "라우트 그룹화"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // v1 그룹
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // v2 그룹
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/html-rendering.md b/src/content/docs/ko-kr/docs/examples/html-rendering.md
new file mode 100644
index 000000000..6e9215340
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML 랜더링"
+
+---
+
+LoadHTMLGlob() 혹은 LoadHTMLFiles()를 사용합니다.
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+다른 디렉토리에 있는 동일한 이름의 템플릿을 사용할 경우
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### 커스텀 템플릿 렌더링 엔진
+
+독자적인 HTML 템플릿 렌더링 엔진을 사용하는 것도 가능합니다.
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### 커스텀 구분자
+
+구분자를 사용자 정의하여 사용할 수도 있습니다.
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### 커스텀 템플릿 기능
+
+자세한 내용은 [예제 코드](https://github.com/gin-gonic/examples/tree/master/template)를 확인하세요.
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+결과:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/ko-kr/docs/examples/http-method.md b/src/content/docs/ko-kr/docs/examples/http-method.md
new file mode 100644
index 000000000..9f7f54f91
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "HTTP 메소드 사용"
+
+---
+
+```go
+func main() {
+ // 기본 미들웨어를 포함한 gin 라우터를 생성합니다:
+ // logger와 recovery (crash-free) 미들웨어가 포함됩니다.
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // 환경변수에 PORT가 지정되어 있지 않는 경우
+ // 기본값으로 8080 포트를 사용합니다.
+ router.Run()
+ // router.Run(":3000") 와 같이 하드코딩으로 포트를 지정 할 수 있습니다.
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/http2-server-push.md b/src/content/docs/ko-kr/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..47a5736a4
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 서버 푸시"
+
+---
+
+http.Pusher는 **go1.8 이상**에서만 지원됩니다. 자세한 정보는 [Go언어 블로그](https://blog.golang.org/h2push)에서 확인하세요.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // 서버 푸시를 위해 pusher.Push()를 사용합니다
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // 서버가 실행 되고 https://127.0.0.1:8080 에서 요청을 기다립니다.
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/index.md b/src/content/docs/ko-kr/docs/examples/index.md
new file mode 100644
index 000000000..e115857d3
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "예제"
+
+sidebar:
+ order: 6
+---
+
+이 장에는 API 사용법이 있습니다.
diff --git a/src/content/docs/ko-kr/docs/examples/jsonp.md b/src/content/docs/ko-kr/docs/examples/jsonp.md
new file mode 100644
index 000000000..cdf973c9a
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+JSONP를 사용하여 다른 도메인의 서버에 요청하고 데이터를 받아올 수 있습니다. 조회 매개변수 콜백이 존재하는 경우 응답 본문에 콜백을 추가하세요.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback은 x입니다
+ // 출력내용 : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/ko-kr/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..bd42376e7
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "쿼리 문자열 혹은 POST 폼의 파라미터에 매핑"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..1e3c8bbee
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded 바인딩"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // 명시적으로 바인딩을 정의하여 multipart form을 바인딩 할 수 있습니다:
+ // c.ShouldBindWith(&form, binding.Form)
+ // 혹은 ShouldBind 메소드를 사용하여 간단하게 자동으로 바인딩을 할 수 있습니다:
+ var form LoginForm
+ // 이 경우에는 자동으로 적절한 바인딩이 선택 됩니다
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+다음과 같이 테스트 할 수 있습니다:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-form.md b/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..9d82a28ee
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded 양식"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/multiple-template.md b/src/content/docs/ko-kr/docs/examples/multiple-template.md
new file mode 100644
index 000000000..d496c0b05
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "다중 템플릿"
+
+---
+
+Gin은 기본적으로 하나의 html.Template만 사용하도록 허용합니다. Go 1.6의 `block template`와 같은 기능을 사용 하려면 [다중 템플릿 렌더(multitemplate)](https://github.com/gin-contrib/multitemplate)를 확인하세요.
diff --git a/src/content/docs/ko-kr/docs/examples/only-bind-query-string.md b/src/content/docs/ko-kr/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..9734b394b
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "쿼리 문자열만 바인딩하기"
+
+---
+
+`ShouldBindQuery` 함수는 POST 데이터가 아닌 쿼리 파라미터만 바인딩 합니다. [자세한 정보](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017)를 확인 하세요.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/param-in-path.md b/src/content/docs/ko-kr/docs/examples/param-in-path.md
new file mode 100644
index 000000000..17837685a
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "경로를 포함한 파라미터"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // 이 핸들러는 /user/john와 매칭되지만 /user/ 또는 /user와는 매칭되지 않습니다.
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // 하지만, 이것은 /user/john/ 뿐만 아니라 /user/john/send와도 매칭됩니다.
+ // /user/john와 매칭되는 라우터가 없다면, /user/john/로 리다이렉트 됩니다.
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/pure-json.md b/src/content/docs/ko-kr/docs/examples/pure-json.md
new file mode 100644
index 000000000..3c91ab830
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/pure-json.md
@@ -0,0 +1,31 @@
+---
+title: "PureJSON"
+
+---
+
+일반적으로 JSON은 `<`와 같은 HTML문자를 `\u003c`처럼 유니코드로 변환 합니다.
+만약 이러한 문자를 그대로 인코딩 하려면 PureJSON을 사용하세요.
+이 기능은 Go 1.6 이하에서는 사용할 수 없습니다.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // 유니코드 엔티티 반환
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // 리터럴 문자 반환
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/query-and-post-form.md b/src/content/docs/ko-kr/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..ffe2ec004
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "POST 양식 쿼리"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/ko-kr/docs/examples/querystring-param.md b/src/content/docs/ko-kr/docs/examples/querystring-param.md
new file mode 100644
index 000000000..05f15f0fc
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "쿼리 문자열 파라미터"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // 쿼리 문자열 파라미터는 기존의 Request객체를 사용하여 분석 됩니다.
+ // 이 URL과 일치하는 요청에 대해 응답합니다: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname")의 단축어
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/redirects.md b/src/content/docs/ko-kr/docs/examples/redirects.md
new file mode 100644
index 000000000..a87b5334b
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "리디렉션"
+
+---
+
+HTTP 리다이렉트 하는 것은 간단합니다. 내부와 외부위치를 모두 지원합니다.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+라우터 리다이렉트를 실행하려면, 아래와 같이 `HandleContext`를 사용하세요.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/ko-kr/docs/examples/rendering.md b/src/content/docs/ko-kr/docs/examples/rendering.md
new file mode 100644
index 000000000..f2e71ff95
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf 랜더링"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H은 map[string]interface{} 타입입니다.
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // 구조체도 사용할 수 있습니다.
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // msg.Name은 JSON에서 "user"가 됩니다.
+ // 출력내용 : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // protobuf의 정의는 testdata/protoexample 파일에 작성되어 있습니다.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // 데이터는 응답(response)시에 이진 데이터가 됩니다.
+ // protobuf로 직렬화된 protoexample.Test가 출력됩니다.
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/run-multiple-service.md b/src/content/docs/ko-kr/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..96fb46db9
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "여러 개의 서비스를 실행하기"
+
+---
+
+이 [질문](https://github.com/gin-gonic/gin/issues/346)을 보고, 다음 예제를 실행해 보세요:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/secure-json.md b/src/content/docs/ko-kr/docs/examples/secure-json.md
new file mode 100644
index 000000000..50adc830c
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/secure-json.md
@@ -0,0 +1,26 @@
+---
+title: "SecureJSON"
+
+---
+
+json 하이재킹을 방지하기 위해 SecureJSON를 사용합니다.
+주어진 구조체가 배열인 경우, 기본적으로 `"while(1),"` 이 응답 본문에 포함 됩니다.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // 자체적인 보안 json 접두사를 사용할 수도 있습니다.
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // 출력내용 : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/security-headers.md b/src/content/docs/ko-kr/docs/examples/security-headers.md
new file mode 100644
index 000000000..fd0b0fc3c
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/security-headers.md
@@ -0,0 +1,76 @@
+---
+title: "보안 헤더"
+
+---
+
+일반적인 보안 취약점으로부터 웹 애플리케이션을 보호하려면 보안 헤더를 사용하는 것이 중요합니다. 이 예에서는 Gin 애플리케이션에 보안 헤더를 추가하는 방법과 호스트 헤더 인젝션 관련 공격(SSRF, 오픈 리디렉션)을 방지하는 방법을 설명합니다.
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+`curl` 로 테스트할 수 있습니다:
+
+
+```bash
+// 헤더 확인
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// 호스트 헤더 주입 확인
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/ko-kr/docs/examples/serving-data-from-reader.md b/src/content/docs/ko-kr/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..b038ed088
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Reader로 데이터 반환"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/serving-static-files.md b/src/content/docs/ko-kr/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..a5717ce07
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "정적 파일 반환"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/support-lets-encrypt.md b/src/content/docs/ko-kr/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..cdb181203
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Let's Encrypt 지원"
+
+---
+
+한 줄의 LetsEncrypt HTTPS 서버의 샘플입니다.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+autocert 관리자의 커스텀 예제.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/upload-file/index.md b/src/content/docs/ko-kr/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..1136def88
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "파일 업로드"
+
+---
+
+이 장에는 파일 업로드 API 사용법이 있습니다.
diff --git a/src/content/docs/ko-kr/docs/examples/upload-file/multiple-file.md b/src/content/docs/ko-kr/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..19b4708a7
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "여러 파일"
+
+---
+
+자세한 내용은 [예제 코드](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple)를 확인하세요.
+
+```go
+func main() {
+ router := gin.Default()
+ // 멀티파트 폼에 대한 최저 메모리 설정 (기본값 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // 멀티파트 폼
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // 특정 경로(dst)에 파일을 업로드 합니다.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+`curl` 사용방법:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/ko-kr/docs/examples/upload-file/single-file.md b/src/content/docs/ko-kr/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..887dd1a88
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/upload-file/single-file.md
@@ -0,0 +1,37 @@
+---
+title: "단일 파일"
+
+---
+
+이슈 [#774](https://github.com/gin-gonic/gin/issues/774) 혹은 자세한 [예제 코드](https://github.com/gin-gonic/examples/tree/master/upload-file/single)를 확인하세요.
+
+`file.Filename`은 **신뢰할 수 없습니다.**. MDN의 [`Content-Disposition`](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives)과 이슈 [#1693](https://github.com/gin-gonic/gin/issues/1693)를 참조하세요.
+
+> 파일 이름은 항상 선택 사항이며 응용 프로그램에서 맹목적으로 사용해서는 안됩니다. 경로 정보를 제거하고 서버 파일 시스템 규칙으로 변환해야합니다.
+
+```go
+func main() {
+ router := gin.Default()
+ // 멀티파트 폼에 대한 최저 메모리 설정 (기본값 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // 단일 파일
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // 특정 경로(dst)에 파일을 업로드 합니다.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+`curl` 사용방법:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/ko-kr/docs/examples/using-basicauth-middleware.md b/src/content/docs/ko-kr/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..5ebcd1241
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "기본인증(BasicAuth) 미들웨어 사용하기"
+
+---
+
+```go
+// 개인정보 샘플 데이터
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // gin.BasicAuth() 미들웨어를 사용하여 그룹화 하기
+ // gin.Accounts는 map[string]string 타입입니다.
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // 엔드포인트 /admin/secrets
+ // "localhost:8080/admin/secrets"로 접근합니다.
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // BasicAuth 미들웨어를 통해 유저를 설정합니다.
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/examples/using-middleware.md b/src/content/docs/ko-kr/docs/examples/using-middleware.md
new file mode 100644
index 000000000..e6f25e5e1
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "미들웨어를 사용하기"
+
+---
+
+```go
+func main() {
+ // 기본 미들웨어를 포함하지 않는 라우터를 작성합니다.
+ r := gin.New()
+
+ // Global middleware
+ // GIN_MODE=release로 하더라도 Logger 미들웨어는 gin.DefaultWriter에 로그를 기록합니다.
+ // 기본값 gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery 미들웨어는 panic이 발생하면 500 에러를 씁니다.
+ r.Use(gin.Recovery())
+
+ // 각 라우트 당 원하는만큼 미들웨어를 추가 할 수 있습니다.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // 권한 그룹
+ // authorized := r.Group("/", AuthRequired())
+ // 다음과 동일합니다:
+ authorized := r.Group("/")
+ // 그룹별로 미들웨어를 사용할 수 있습니다!
+ // 이 경우 "authorized"그룹에서만 사용자 정의 생성된 AuthRequired() 미들웨어를 사용합니다.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // 중첩 그룹
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ko-kr/docs/examples/without-middleware.md b/src/content/docs/ko-kr/docs/examples/without-middleware.md
new file mode 100644
index 000000000..a18fc1c45
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "기본 미들웨어를 포함하지 않는 방법"
+
+---
+
+이렇게 사용하세요.
+
+```go
+r := gin.New()
+```
+
+아래와 같은 코드는 기본 미들웨어를 포함합니다.
+
+```go
+// 로거와 복구 미들웨어가 이미 연결된 상태
+r := gin.Default()
+```
diff --git a/src/content/docs/ko-kr/docs/examples/write-log.md b/src/content/docs/ko-kr/docs/examples/write-log.md
new file mode 100644
index 000000000..c281e154e
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "로그 파일을 작성하는 방법"
+
+---
+
+```go
+func main() {
+ // 로그 파일 작성에는 색상이 필요 없으므로, 콘솔 색상을 비활성화 합니다.
+ gin.DisableConsoleColor()
+
+ // 파일에 로그를 작성합니다.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // 파일과 동시에 콘솔에도 로그를 작성해야 하는 경우에는 다음과 같은 코드를 사용하세요.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ko-kr/docs/faq/index.md b/src/content/docs/ko-kr/docs/faq/index.md
new file mode 100644
index 000000000..25dd07af0
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: GitHub 이슈탭에서 자주 받는 질문을 정리하기.
+
diff --git a/src/content/docs/ko-kr/docs/features/index.md b/src/content/docs/ko-kr/docs/features/index.md
new file mode 100644
index 000000000..6974af41b
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "기능"
+
+sidebar:
+ order: 4
+---
+
+## Gin v1 안정판의 기능:
+
+- 동적 메모리 할당이 0인 라우터
+
+- 가장 빠른 http 라우터와 프레임워크
+
+- 단위 테스트가 갖추어져 있음
+
+- 엄격한 테스트를 통과함 (Battle tested)
+
+- API는 고정되어 있고, 새로운 버전이 기존의 코드에 영향을 끼치지 않음
diff --git a/src/content/docs/ko-kr/docs/index.md b/src/content/docs/ko-kr/docs/index.md
new file mode 100644
index 000000000..461f7eccf
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/index.md
@@ -0,0 +1,21 @@
+---
+title: "문서"
+linkTitle: "문서"
+sidebar:
+ order: 1
+---
+
+## Gin 이란?
+
+Gin은 Go 언어로 작성된 HTTP Web 프레임워크입니다. [Martini](https://github.com/go-martini/martini)와 유사한 API를 제공하지만,최대 40배 빠른 성능을 발휘합니다. 매우 좋은 성능이 필요하다면 Gin을 사용하세요.
+
+## Gin의 사용법은?
+
+우리는 API [예제들](https://github.com/gin-gonic/examples)과 [Gin을 사용하는 프로젝트](./users) 리스트를 제공하고 있습니다.
+
+## Gin에 기여하기 위해서는?
+
+* 토론 포럼에서 사람들을 도와주세요
+* Gin을 사용한 성공사례를 알려주세요
+* Gin을 개선하기 위한 좋은 방법이 있다면 알려주세요
+* 기존의 라이브러리에 기여해주세요
diff --git a/src/content/docs/ko-kr/docs/introduction/index.md b/src/content/docs/ko-kr/docs/introduction/index.md
new file mode 100644
index 000000000..5834a7272
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/introduction/index.md
@@ -0,0 +1,48 @@
+---
+title: "소개"
+
+sidebar:
+ order: 1
+---
+
+Gin은 Go로 작성된 웹 프레임워크입니다. Martini와 비슷한 API를 제공하지만, [httprouter](https://github.com/julienschmidt/httprouter) 덕분에 최대 40배 빠른 성능을 제공합니다. 만약 뛰어난 생산성과 퍼포먼스가 필요하다면, Gin을 좋아하게 될 것입니다.
+
+이 페이지에서는 Gin이 무엇이고 또 어떤 문제를 해결하도록 도와주는지, 그리고 어떻게 당신의 프로젝트를 도와주는지 알아보겠습니다.
+
+혹은, 당신의 프로젝트가 Gin을 사용할 준비가 되어 있다면, [퀵 스타트](https://gin-gonic.com/docs/quickstart/)를 봐주세요.
+
+## 기능
+
+### 빠른 속도
+
+기수 트리(Radix tree)를 기반으로 한 라우팅, 적은 메모리 사용량. 리플렉션 미사용. 예측 가능한 API 성능.
+
+### 미들웨어 지원
+
+수신된 HTTP 요청은 미들웨어 체인과 최종적인 액션을 통한 처리가 가능합니다.
+예: Logger, 인증, GZIP 압축, DB에 메시지 전송.
+
+### 충돌방지
+
+Gin은 HTTP 요청 중 발생한 `panic` 을 감지하고 `recover` 할 수 있습니다. 따라서, 서버는 항상 이용 가능한 상태를 유지합니다. 예를 들면, 발생한 `panic` 을 Sentry에 보고 하는 것도 가능합니다!
+
+### JSON 유효성 검사
+
+Gin은 JSON 형식의 요청에 대해 파싱과 유효성 검사를 할 수 있습니다. 예를 들어, 필수값이 들어 있는지 확인 할 수 있습니다.
+
+### 라우팅 그룹화
+
+라우팅 경로를 더 좋게 정리 할 수 있습니다. 인증이 필요한지 아닌지, 버전이 다른 API인지 아닌지 등... 또한, 성능 저하 없이 그룹을 무제한 중첩할 수 있습니다.
+
+### 에러관리
+
+Gin은 HTTP 요청 중에 발생한 모든 에러를 수집하는 편리한 방법을 제공합니다. 이것을 통해 미들웨어는 로그 파일, 데이터베이스에 기록하고 네트워크를 통해 전송할 수 있습니다.
+
+### 렌더링 기능 내장
+
+Gin은 JSON, XML, HTML 렌더링을 위한 사용하기 쉬운 API를 제공합니다.
+
+### 확장 가능
+
+아주 쉽게 새로운 미들웨어를 만들 수 있습니다. 샘플 코드를 확인하세요.
+
diff --git a/src/content/docs/ko-kr/docs/jsoniter/index.md b/src/content/docs/ko-kr/docs/jsoniter/index.md
new file mode 100644
index 000000000..aac91af91
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## [jsoniter](https://github.com/json-iterator/go)로 빌드하기
+
+Gin은 기본적인 json 패키지로 `encoding/json` 를 사용하지만, 다른 태그로 빌드 하기 위해 [jsoniter](https://github.com/json-iterator/go)를 사용하는 것도 가능합니다.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/ko-kr/docs/quickstart/index.md b/src/content/docs/ko-kr/docs/quickstart/index.md
new file mode 100644
index 000000000..708d50bb2
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/quickstart/index.md
@@ -0,0 +1,102 @@
+---
+title: "퀵 스타트"
+
+sidebar:
+ order: 2
+---
+
+이 퀵 스타트에서는, 코드에서 통찰력을 얻고 어떤 식으로 할지 배울 것입니다:
+
+## 요구사항
+
+- Go 1.16 이상
+
+## 설치
+
+Gin을 설치 하기 위해서는, Go 언어를 설치 한 후 Go workspace를 설정해야 합니다.
+
+1. 다운로드 후 설치하기:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. 사용할 코드 내에서 임포트 하기:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (선택사항) `net/http`를 임포트 하기. `http.StatusOK` 와 같은 상수를 사용하는 경우 필요합니다.
+
+```go
+import "net/http"
+```
+
+### [Govendor](https://github.com/kardianos/govendor)같은 vendor 툴을 사용하기
+
+1. `go get` 을 이용하여 govendor 설치
+
+```sh
+$ go get github.com/kardianos/govendor
+```
+2. 프로젝트 디렉토리를 작성 한 후 `cd` 로 이동하기
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+3. Vendor로 프로젝트를 초기화 한 후 Gin을 추가하기
+
+```sh
+$ govendor init
+$ govendor fetch github.com/gin-gonic/gin@v1.3
+```
+
+4. 시작 템플릿을 프로젝트에 복사하기
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+5. 프로젝트 실행하기
+
+```sh
+$ go run main.go
+```
+
+## 시작하기
+
+> Go 코드 작성 및 실행 방법을 잘 모르시나요? [여기를 클릭하세요](https://golang.org/doc/code.html).
+
+우선 `example.go` 파일을 작성합니다.:
+
+```sh
+# 이후 코드는 example.go 파일에 작성합니다.
+$ touch example.go
+```
+
+다음으로, 아래의 코드를 `example.go` 에 작성합니다.:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // 서버가 실행 되고 0.0.0.0:8080 에서 요청을 기다립니다.
+}
+```
+
+그리고, `go run example.go` 로 코드를 실행합니다.:
+
+```sh
+# example.go 를 실행 후, 0.0.0.0:8080/ping 에 접속합니다.
+$ go run example.go
+```
diff --git a/src/content/docs/ko-kr/docs/testing/index.md b/src/content/docs/ko-kr/docs/testing/index.md
new file mode 100644
index 000000000..dfc2641d3
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/testing/index.md
@@ -0,0 +1,93 @@
+---
+title: "테스트"
+
+sidebar:
+ order: 7
+---
+
+## Gin의 테스트 케이스를 작성하는 방법은?
+
+`net/http/httptest` 패키지 는 HTTP테스트에 선호되는 방법입니다.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+위 예제의 테스트 코드:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
+
+
+
diff --git a/src/content/docs/ko-kr/docs/users/index.md b/src/content/docs/ko-kr/docs/users/index.md
new file mode 100644
index 000000000..fbb3031f1
--- /dev/null
+++ b/src/content/docs/ko-kr/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Gin을 사용하는 곳"
+
+sidebar:
+ order: 8
+---
+
+##### [Gin](https://github.com/gin-gonic/gin) 웹 프레임워크를 사용한 멋진 프로젝트 목록:
+
+* [gorush](https://github.com/appleboy/gorush): Go로 작성된 푸시 알림 서버.
+
+* [fnproject](https://github.com/fnproject/fn): 클라우드에 구애받지 않는 컨테이너 네이티브 서버리스 플렛폼.
+
+* [photoprism](https://github.com/photoprism/photoprism): Go와 Google TensorFlow 기반의 개인 사진관리.
+
+* [krakend](https://github.com/devopsfaith/krakend): 미들웨어가 포함된 고성능 API 게이트웨이.
+
+* [picfit](https://github.com/thoas/picfit): Go로 작성된 이미지 크기 조절 서버.
+
+* [gotify](https://github.com/gotify/server): 웹 소켓 당 실시간으로 메시지를 주고받는 간단한 서버.
+
+* [cds](https://github.com/ovh/cds): 엔터프라이즈급 지속적인 서비스 제공(CD) 및 DevOps 자동화 오픈 소스 플랫폼.
diff --git a/src/content/docs/ko-kr/index.mdx b/src/content/docs/ko-kr/index.mdx
new file mode 100644
index 000000000..4ce67991e
--- /dev/null
+++ b/src/content/docs/ko-kr/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: The fastest full-featured web framework for Go. Crystal clear.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Learn More
+ link: /ko-kr/docs/
+ icon: right-arrow
+ - text: Download
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## What is Gin?
+
+Gin is a web framework written in Golang. It features a martini-like API with much better performance, up to 40 times faster. If you need performance and good productivity, you will love Gin.
+
+
+
+ Radix tree based routing, small memory foot print. No reflection. Predictable API performance.
+
+
+ A incoming HTTP request can be handled by a chain of middlewares and the final action. For example: Logger, Authorization, GZIP and finally post a message in the DB.
+
+
+ Gin can catch a panic occurred during a HTTP request and recover it. This way, your server will be always available. It’s also possible to report this panic to Sentry for example!
+
+
+ Gin can parse and validate the JSON of a request, checking for example the existence of required values.
+
+
+ Organize your routes better. Authorization required vs non required, different API versions. In addition, the groups can be nested unlimitedly without degrading performance.
+
+
+ Gin provides a convenient way to collect all the errors occurred during a HTTP request. Eventually, a middleware can write them to a log file, to a database and send them through the network.
+
+
+ Gin provides an easy to use API for JSON, XML and HTML rendering.
+
+
+ Creating a new middleware is so easy, just check out the sample codes.
+
+
+
diff --git a/src/content/docs/pt/blog/index.md b/src/content/docs/pt/blog/index.md
new file mode 100644
index 000000000..abfaf1a4d
--- /dev/null
+++ b/src/content/docs/pt/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blogue"
+linkTitle: "Blogue"
+sidebar:
+ order: 30
+---
+
+
+Esta é a seção **blogue**. Ela tem duas categorias: Novidades e Lançamentos.
+
+Os ficheiros nestes diretórios serão listados em ordem cronológica inversa.
+
diff --git a/content/pt/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/pt/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/pt/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/pt/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/pt/blog/releases/release13.md b/src/content/docs/pt/blog/releases/release13.md
similarity index 100%
rename from content/pt/blog/releases/release13.md
rename to src/content/docs/pt/blog/releases/release13.md
diff --git a/content/pt/blog/releases/release14.md b/src/content/docs/pt/blog/releases/release14.md
similarity index 100%
rename from content/pt/blog/releases/release14.md
rename to src/content/docs/pt/blog/releases/release14.md
diff --git a/content/pt/blog/releases/release15.md b/src/content/docs/pt/blog/releases/release15.md
similarity index 100%
rename from content/pt/blog/releases/release15.md
rename to src/content/docs/pt/blog/releases/release15.md
diff --git a/content/pt/blog/releases/release16.md b/src/content/docs/pt/blog/releases/release16.md
similarity index 100%
rename from content/pt/blog/releases/release16.md
rename to src/content/docs/pt/blog/releases/release16.md
diff --git a/src/content/docs/pt/docs/benchmarks/index.md b/src/content/docs/pt/docs/benchmarks/index.md
new file mode 100644
index 000000000..d79c36760
--- /dev/null
+++ b/src/content/docs/pt/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "Analises Comparativas"
+
+sidebar:
+ order: 3
+---
+
+A Gin usa uma versão personalizada da [`HttpRouter`](https://github.com/julienschmidt/httprouter).
+
+[Consulte todos os analises comparativas](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md):
+
+| Nome da analise comparativa | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): Repetições Totais alcançadas em tempo constante, quanto mais alto, significa mais segurança do resultado.
+- (2): Duração de Uma Repetição (ns/op), quanto mais baixo, melhor.
+- (3): Amontoar Memória (B/op), quanto mais baixo, melhor.
+- (4): Alocações Média por Repetição (allocs/op), quanto mais baixo, melhor.
diff --git a/src/content/docs/pt/docs/deployment/index.md b/src/content/docs/pt/docs/deployment/index.md
new file mode 100644
index 000000000..d88f7f968
--- /dev/null
+++ b/src/content/docs/pt/docs/deployment/index.md
@@ -0,0 +1,32 @@
+---
+title: "Implementação em Produção"
+
+sidebar:
+ order: 6
+---
+
+Os projetos de Gin podem ser implementados em produção facilmente em qualquer provedor da nuvem.
+
+## [Koyeb](https://www.koyeb.com)
+
+A Koyeb é uma plataforma sem servidor amistosa ao programador para implementar as aplicações localmente em produção com a implementação baseada em Git, encriptação de TLS, auto-escalamento nativo, rede de fio global, e malha de rede de serviço e descoberta embutido.
+
+Siga o [guia da Koyeb para implementar em produção os teus projetos de Gin](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
+
+## [Qovery](https://www.qovery.com)
+
+A Qovery fornece hospedagem de nuvem gratuita com bases de dados, SSL, uma CDN global e implementações em produção automáticas com a Git.
+
+Siga o [guia da Qovery para implementar o teu projeto de Gin em produção](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
+
+## [Render](https://render.com)
+
+A Render é uma plataforma da nuvem moderna que oferece suporte nativo para a Go, SSL completamente administrado, bases de dados, implementações em produção com tempo de inatividade zero, HTTP/2, e suporte a websocket.
+
+Siga o [guia da Render para implementação de projetos de Gin em produção](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+A GAE tem duas maneiras de implementar aplicações de Go em produção. O ambiente padrão é mais fácil de usar mas menos personalizável e impedi [syscalls](https://github.com/gin-gonic/gin/issues/1639) por razões de segurança. O ambiente flexível pode executar qualquer abstração ou biblioteca.
+
+Saiba mais e escolha o teu ambiente preferido na [Go sobre a Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/pt/docs/examples/ascii-json.md b/src/content/docs/pt/docs/examples/ascii-json.md
new file mode 100644
index 000000000..43342827d
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Usando a `AsciiJSON` para gerar JSON de apenas ASCII com caracteres que não são ASCII escapados:
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // resultará em : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Ouvir e servir na 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/pt/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..e8b0f38d0
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,56 @@
+---
+title: "Tentar vincular o corpo à diferentes estruturas"
+
+---
+
+Os métodos normais para vincular o corpo da requisição consumem a `c.Request.Body` e não podem ser chamados várias vezes:
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // Este c.ShouldBind consume o c.Request.Body e não pode ser reutilizado.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Um erro sempre acontecerá por aqui porque c.Request.Body agora é EOF
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+Para isto, podes usar `c.ShouldBindBodyWith`:
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // Isto lê c.Request.Body e armazena o resultado no contexto.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Neste momento, ela reutiliza o corpo armazenado no contexto.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // E pode aceitar outros formatos
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWidth` armazena o corpo no contexto antes da vinculação. Isto tem um ligeiro impacto no desempenho, então não deverias usar este método se estás bem para chamar a vinculação imediatamente.
+
+* Esta funcionalidade é apenas necessário para alguns formatos -- `JSON`, `XML`, `MsgPack`, `ProtoBuf`. Para outros formatos, `Query`, `Form`, `FormPost`, `FormMultipart`, podem ser chamados pela `c.ShouldBind()` várias vezes sem qualquer dado para o desempenho (consulte a [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/pt/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/pt/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..47391edeb
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "Vincular a requisição de dados de formulário com a estrutura personalizada"
+
+---
+
+O seguinte exemplo usando estrutura personalizada:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Usando o comando `url` e resultado do comando:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/pt/docs/examples/bind-html-checkbox.md b/src/content/docs/pt/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..0d63e3624
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Vincular caixas de confirmações de HTML"
+
+---
+
+Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092):
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+resultado:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/pt/docs/examples/bind-query-or-post.md b/src/content/docs/pt/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..6286c7342
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-query-or-post.md
@@ -0,0 +1,49 @@
+---
+title: "Vincular a sequência de caracteres de consulta ou publicar dados"
+
+---
+
+Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292):
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // Se `GET`, apenas o motor de vinculação de `Form` (`query`) é usada.
+ // Se `POST`, primeiro conferi o `content-type` por `JSON` ou `XML`, depois use o `Form` (`form-data`).
+ // Consulte mais na https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Testá-lo com:
+
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/pt/docs/examples/bind-single-binary-with-template.md b/src/content/docs/pt/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..65d708b98
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,45 @@
+---
+title: "Construir um único binário com modelos de marcação"
+
+---
+## Usar o pacote de terceiro
+
+Tu podes usar o pacote de terceiro para construir um servidor em um único binário contendo os modelos de marcação usando o [go-assets](https://github.com/jessevdk/go-assets):
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate carrega os modelos de marcação fixado pelo go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+Consulte um exemplo completo no diretório [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/src/content/docs/pt/docs/examples/bind-uri.md b/src/content/docs/pt/docs/examples/bind-uri.md
new file mode 100644
index 000000000..880823238
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Vincular a URI"
+
+---
+
+Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/846):
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Testá-lo com:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/pt/docs/examples/binding-and-validation.md b/src/content/docs/pt/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..a983e9cb5
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/binding-and-validation.md
@@ -0,0 +1,119 @@
+---
+title: "Vinculação de Modelo e Validação"
+
+---
+
+Para vincular uma corpo de requisição à um tipo, use a vinculação de modelo. Nós atualmente suportamos a vinculação de JSON, XML, YAML e valores de formulário padrão (foo=bar&boo=baz).
+
+A Gin usa [**`go-playground/validator/v10`**](https://github.com/go-playground/validator) para a validação. Consulte a documentação completa sobre o uso de marcadores [nesta ligação](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Nota que precisas de definir o marcador da vinculação correspondente em todos os campos que quiseres vincular. Por exemplo, quando estiveres a vincular a partir de JSON, defina `json:"fieldname"`.
+
+Além disto, a Gin fornece dois conjuntos de métodos para vinculação:
+
+- **Tipo** - Deve vincular
+ - **Métodos** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Comportamento** - Estes métodos usam `MustBindWith` nos bastidores. Se houver um erro de vinculação, a requisição é abortada com `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. Isto define o código do estado da resposta para 400 e o cabeçalho `Content-Type` é definido para `text/plain; charset=utf-8`. Nota que se tentares definir o código da resposta depois disto, resultará em um aviso `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. Se desejas ter maior controlo sobre o comportamento, considere usar o método equivalente `ShouldBind`.
+- **Tipo** - Deveria vincular
+ - **Métodos** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Comportamento** - Estes métodos usam `ShouldBindWith` nos bastidores. Se houver um erro de vinculação, o erro é retornado e é responsabilidade do programador manipular a requisição e o erro apropriadamente.
+
+Quando estiveres o método `Bind`, a Gin tenta inferir o vinculador dependendo do cabeçalho do `Content-Type`. Se estiveres certo daquilo que estiveres a vincular, podes usar `MustBindWith` ou `ShouldBindWith`.
+
+Tu podes também especificar que os campos específicos são obrigatório. Se um campo for decorado com `binding:"required"` e tiver um valor vazio quando estiveres a vincular, um erro será retornado:
+
+```go
+// Vinculando a partir de JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Exemplo para vincular o JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Exemplo pra vincular o XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Exemplo para vincular um formulário de HTML (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // Isto inferirá qual vinculador usar dependendo do cabeçalho do `content-type`.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Ouvir e servir na 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Requisição Simples
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Saltar a Validação
+
+Quando estiveres a executar o exemplo de cima usando o comando `curl` de cima, isto retorna erro. Porque o exemplo usa `binding:"required"` para `Password`. Se usares `binding:"-"` para `Password`, então este não retornará erro quando estiveres a executar o exemplo de cima novamente.
diff --git a/src/content/docs/pt/docs/examples/controlling-log-output-coloring.md b/src/content/docs/pt/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..7ede1eaab
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Controlando a Colorização da Saída de Registo"
+
+---
+
+Por padrão, a saída de registos na consola deveria ser colorida dependendo do TTY detetado.
+
+Nunca colorir os registos:
+
+```go
+func main() {
+ // Desativar a cor do registo
+ gin.DisableConsoleColor()
+
+ // Criar um roteador de Gin com o intermediário padrão:
+ // registador e intermediário de recuperação (livre de avaria)
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Sempre colorir os registos:
+
+```go
+func main() {
+ // Forçar a cor do registo
+ gin.ForceConsoleColor()
+
+ // Criar um roteador de Gin com o intermediário padrão:
+ // registador e intermediário de recuperação (livre de avaria)
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/cookie.md b/src/content/docs/pt/docs/examples/cookie.md
new file mode 100644
index 000000000..507c53feb
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Definir e Recuperar um Cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/pt/docs/examples/custom-http-config.md b/src/content/docs/pt/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..224f73e29
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/custom-http-config.md
@@ -0,0 +1,30 @@
+---
+title: "Configuração de HTTP Personalizada"
+
+---
+
+Usar o `http.ListenAndServe()` diretamente, desta maneira:
+
+```go
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+
+ou
+
+```go
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/pt/docs/examples/custom-log-format.md b/src/content/docs/pt/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..175c5e263
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/custom-log-format.md
@@ -0,0 +1,39 @@
+---
+title: "Ficheiro de Registo Personalizado"
+
+---
+
+Por exemplo:
+
+```go
+func main() {
+ router := gin.New()
+ // O intermediário `LoggerWithFormatter` escreverá os registos para `gin.DefaultWriter`
+ // Por padrão `gin.DefaultWriter = os.Stdout`
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // o teu formato personalizado
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Saída de Exemplo**:
+
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/pt/docs/examples/custom-middleware.md b/src/content/docs/pt/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..cfc637d3d
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Intermediário Personalizado"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Definir a variável de exemplo
+ c.Set("example", "12345")
+
+ // antes da requisição
+
+ c.Next()
+
+ // depois da requisição
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // acessar o estado que estamos a enviar
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // imprimiria: "12345"
+ log.Println(example)
+ })
+
+ // Ouvir e servir na 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/custom-validators.md b/src/content/docs/pt/docs/examples/custom-validators.md
new file mode 100644
index 000000000..eaec97ffb
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Validadores Personalizados"
+
+---
+
+Também é possível registar validadores personalizados. Consulte o [código de exemplo](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations):
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// `Booking` (contratação) contém dados vinculados e validados.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+As [validações a nível estrutural](https://github.com/go-playground/validator/releases/tag/v8.7) também podem ser registadas desta maneira.
+Consulte o [exemplo `struct-lvl-validation`](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) para saber mais.
diff --git a/src/content/docs/pt/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/pt/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..5fed784f5
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,46 @@
+---
+title: "Definir o Formato para o Registo de Rotas"
+
+---
+
+O registo padrão de rotas é:
+
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+Se quiseres registar esta informação em dado formato (por exemplo, JSON, valores de chave ou outra coisa), então podes definir este formato com `gin.DebugPrintRouteFunc`.
+No exemplo abaixo, registamos todas as rotas com o pacote de registo padrão mas podes usar uma outra ferramenta de registo adequada as tuas necessidades:
+
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Ouvir e servir na http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/pt/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/pt/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..aa303d4a8
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Rotinas de Go dentro dum Intermediário"
+
+---
+
+Quando começares novas rotinas de Go dentro dum intermediário ou manipulador, **NÃO DEVERIAS** usar o contexto original dentro dele, tens que usar uma cópia de apenas leitura.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // criar cópia a ser usada dentro da rotina de go
+ cCp := c.Copy()
+ go func() {
+ // simular uma tarefa longa com time.Sleep(). 5 segundos
+ time.Sleep(5 * time.Second)
+
+ // nota que estás a usar o contexto copiado "cCp", IMPORTANTE
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simular uma tarefa longa com time.Sleep(). 5 segundos
+ time.Sleep(5 * time.Second)
+
+ // já que não estamos a usar uma rotina de Go, não temos que copiar o contexto
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // ouvir e servir na porta 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/graceful-restart-or-stop.md b/src/content/docs/pt/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..6e1e7690d
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,86 @@
+---
+title: "Reinicialização ou Interrupção Graciosa"
+
+---
+
+Queres reiniciar ou parar graciosamente o teu servidor de web?
+Existem algumas maneiras disto poder ser feito.
+
+Nós podemos usar o [fvbock/endless](https://github.com/fvbock/endless) para substituir o `ListenAndServe` padrão. Consulte a questão [#296](https://github.com/gin-gonic/gin/issues/296) por mais detalhes:
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+Uma alternativa ao `endless`:
+
+* [`manners`](https://github.com/braintree/manners): Um servidor de HTTP de Go delicado que desliga graciosamente.
+* [`graceful`](https://github.com/tylerb/graceful): é uma pacote de Go que ativa a paragem graciosa dum servidor de `http.Handler`.
+* [`grace`](https://github.com/facebookgo/grace): reinicialização graciosa & implementação de produção de tempo de inatividade zero para servidores de Go.
+
+Se usas a Go 1.8, podes não precisar de usar esta biblioteca! Considere usar o método [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) embutido da `http.Server` para paragens graciosas. Consulte o exemplo [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) completo com a Gin:
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // servir conexões ou conexões de serviço
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // espere pelo sinal de interrupção para parar graciosamente o
+ // servidor com uma pausa de 5 segundos.
+ quit := make(chan os.Signal, 1)
+ // "kill" padrão (sem parâmetro) envia "syscanll.SIGTERM"
+ // "kill -2" é "syscall.SIGINT"
+ // "kill -9" é "syscall.SIGKILL" mas não pode ser capturado,
+ // então não precisas adicioná-lo
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // capturar ctx.Done(). pausa de 5 segundos.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/grouping-routes.md b/src/content/docs/pt/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..5d1c0d092
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Agrupamento de Rotas"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // grupo simples: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // grupo simples: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/html-rendering.md b/src/content/docs/pt/docs/examples/html-rendering.md
new file mode 100644
index 000000000..b36c22c3e
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/html-rendering.md
@@ -0,0 +1,151 @@
+---
+title: "Interpretação do HTML"
+
+---
+
+Usando `LoadHTMLGlob()` ou `LoadHTMLFiles()`:
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Usando modelos de marcação com o mesmo nome em diretórios diferentes:
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Interpretador de Modelo de Marcação Personalizado
+
+Tu podes também usar o teu próprio interpretador de modelo de marcação de HTML:
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Delimitadores Personalizados
+
+Tu podes usar delimitadores personalizados:
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Funções de Modelo de Marcação Personalizado
+
+Consulte os pormenores do [código de exemplo](https://github.com/gin-gonic/examples/tree/master/template):
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Resultado:
+
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/pt/docs/examples/http-method.md b/src/content/docs/pt/docs/examples/http-method.md
new file mode 100644
index 000000000..7a648f10f
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Usando o Método de HTTP"
+
+---
+
+```go
+func main() {
+ // criar um roteador de gin com intermediário padrão:
+ // intermediário registador e de recuperação (livre de avaria)
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // por padrão serve na :8080 a menos que uma
+ // variável de ambiente PORT fosse definida.
+ router.Run()
+ // router.Run(":3000") para uma porta definida manualmente
+}
+```
diff --git a/src/content/docs/pt/docs/examples/http2-server-push.md b/src/content/docs/pt/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..f2268ad0f
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "Impulso do Servidor de HTTP2"
+
+---
+
+`http.Pusher` é suportado apenas versão **1.8+** de Go. Consulte o [blogue da Golang](https://blog.golang.org/h2push) por informação detalhada:
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // usar pusher.Push() para impulsionar o servidor.
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // ouvir e servir no https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/index.md b/src/content/docs/pt/docs/examples/index.md
new file mode 100644
index 000000000..1fe74c9e2
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "Exemplos"
+
+sidebar:
+ order: 6
+---
+
+A seção lista o uso da API.
diff --git a/src/content/docs/pt/docs/examples/jsonp.md b/src/content/docs/pt/docs/examples/jsonp.md
new file mode 100644
index 000000000..adc58d020
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+Usando JSONP para pedir dados dum servidor num domínio diferente. Adicione a função de resposta ao corpo da resposta se a função de resposta do parâmetro da consulta existir:
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ // função de resposta é x
+ // resultará em: x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // ouvir e servir no 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/pt/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..d679aa0db
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Mapa como Sequência de Caracteres de Consulta ou Parâmetros de Formulário de Publicação"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/pt/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/pt/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..f0d86ce15
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,42 @@
+---
+title: "Vínculo de Várias Partes / URL Codificada"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // tu podes vincular formulário de várias partes com declaração
+ // de vínculo explícita: c.ShouldBindWith(&form, binding.Form)
+ // ou podes simplesmente usar auto-vinculação com método ShouldBind
+ var form LoginForm
+ // neste caso o vínculo apropriado será selecionado automaticamente
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Teste-o coom:
+
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/pt/docs/examples/multipart-urlencoded-form.md b/src/content/docs/pt/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..2914f0a4d
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Formulário de Várias Partes / URL Codificada"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/multiple-template.md b/src/content/docs/pt/docs/examples/multiple-template.md
new file mode 100644
index 000000000..2a8ad5edd
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Vários Modelos de Marcação"
+
+---
+
+A Gin permite por padrão usar apenas um `html.Template`. Consulte [um interpretador de vários modelos de marcação] para usares funcionalidades como `block template` de Go 1.6.
diff --git a/src/content/docs/pt/docs/examples/only-bind-query-string.md b/src/content/docs/pt/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..daffb70c7
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Vincular Apenas a Sequência de Caracteres de Consulta"
+
+---
+
+A função `ShouldBindQuery` apenas vincula os parâmetros de consulta e não os dados da publicação. Consulte a [informação detalhada](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017):
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/param-in-path.md b/src/content/docs/pt/docs/examples/param-in-path.md
new file mode 100644
index 000000000..316bbadce
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/param-in-path.md
@@ -0,0 +1,30 @@
+---
+title: "Parâmetros no Caminho"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // este manipulador corresponderá ao "/user/john"
+ // mas não corresponderá ao "/user/" ou ao "/user"
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // no entanto, este corresponderá o "/user/john/"
+ // e também "/user/john/send"
+ // se nenhuma outra rota corresponder ao "/user/john",
+ // redirecionará ao "/user/john"
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/pure-json.md b/src/content/docs/pt/docs/examples/pure-json.md
new file mode 100644
index 000000000..ea16e85ee
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/pure-json.md
@@ -0,0 +1,29 @@
+---
+title: "PureJSON"
+
+---
+
+Normalmente, a JSON substitui os caracteres de HTML especiais com suas entidades de unicode, por exemplo, `<` torna-se `\u003c`. Se quiseres codificar tais caracteres literalmente, podes usar PureJSON. Esta funcionalidade está indisponível na Go 1.6 para baixo:
+
+```go
+func main() {
+ r := gin.Default()
+
+ // servir as entidades de unicode
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // servir os caracteres literais
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // ouvir e servir no 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/query-and-post-form.md b/src/content/docs/pt/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..e82f52184
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Consulta e Formulário de Publicação"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/pt/docs/examples/querystring-param.md b/src/content/docs/pt/docs/examples/querystring-param.md
new file mode 100644
index 000000000..b2bd8a563
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/querystring-param.md
@@ -0,0 +1,22 @@
+---
+title: "Parâmetros da Sequência de Consulta"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // os parâmetros da sequência de caracteres de consulta
+ // são analisados usando objeto de requisição subjacente existente.
+ // a requisição responde à uma URL correspondendo a:
+ // /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // atalho para c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/redirects.md b/src/content/docs/pt/docs/examples/redirects.md
new file mode 100644
index 000000000..eb86cba11
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirecionamentos"
+
+---
+
+Emitir um redirecionamento de HTTP é fácil. Ambas localizações internas e externas são suportadas:
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Emitir um redirecionamento de HTTP a partir do `POST`. Consulte o problema: [#444](https://github.com/gin-gonic/gin/issues/444):
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Emitir um redirecionamento de roteador, use `HandleContext` como abaixo:
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/pt/docs/examples/rendering.md b/src/content/docs/pt/docs/examples/rendering.md
new file mode 100644
index 000000000..8dcc31c85
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/rendering.md
@@ -0,0 +1,55 @@
+---
+title: "Interpretação de XML/JSON/YAML/ProtoBuf"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // "gin.H" é um atalho para "map[string]interface{}"
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // também podes usar uma estrutura
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // nota que "msg.Name" torna-se "user" na JSON
+ // resultará em: {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // a definição específica do protobuf
+ // está escrita no ficheiro "testdata/protoexample"
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // nota que os dados tornam-se dados binários na resposta
+ // resultará em dados serializados de "protobuf" de "protoexample.Test"
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // ouvir e servir na 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/run-multiple-service.md b/src/content/docs/pt/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..5eba59d62
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Executar Vários Serviços"
+
+---
+
+Consulte a [questão](https://github.com/gin-gonic/gin/issues/346) e tente seguinte exemplo:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/secure-json.md b/src/content/docs/pt/docs/examples/secure-json.md
new file mode 100644
index 000000000..518d2df4b
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+Usando SecureJSON para impedir o sequestro do JSON. Por padrão adiciona `"while(1)"` no início do corpo da resposta se a dada estrutura for valores de arranjo:
+
+```go
+func main() {
+ r := gin.Default()
+
+ // podes também usar o teu próprio prefixo de JSON seguro
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // resultará em: while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // ouvir e servir no 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/security-headers.md b/src/content/docs/pt/docs/examples/security-headers.md
new file mode 100644
index 000000000..37f103360
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "Cabeçalhos de segurança"
+
+---
+
+É importante utilizar cabeçalhos de segurança para proteger a sua aplicação Web de vulnerabilidades de segurança comuns. Este exemplo mostra-lhe como adicionar cabeçalhos de segurança à sua aplicação Gin e também como evitar ataques relacionados com a injeção de cabeçalhos de anfitrião (SSRF, Open Redirection).
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+Pode testá-lo através de `curl`:
+
+```bash
+// Verificar cabeçalhos
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// Verificar a injeção do cabeçalho do anfitrião
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/pt/docs/examples/serving-data-from-reader.md b/src/content/docs/pt/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..5af74e461
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Servir os Dados a partir do Leitor"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/serving-static-files.md b/src/content/docs/pt/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..4c9ba2348
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Servir os Ficheiros Estáticos"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // ouvir e servir no 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/support-lets-encrypt.md b/src/content/docs/pt/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..6fe1fee9a
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Suportar Let's Encrypt"
+
+---
+
+Exemplo para servidores de HTTP LetsEncrypt de uma linha:
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // manipulador de ping
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+Exemplo para o gestor de certificado automático personalizado:
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // manipulador de ping
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/upload-file/index.md b/src/content/docs/pt/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..d6d11e9f5
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Carregar Ficheiros"
+
+---
+
+A seção lista o uso da API de carregamento de ficheiro.
diff --git a/src/content/docs/pt/docs/examples/upload-file/multiple-file.md b/src/content/docs/pt/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..6e37537d6
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,38 @@
+---
+title: "Vários Ficheiros"
+
+---
+
+Consulte o [código de exemplo](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple) detalhado.
+
+```go
+func main() {
+ router := gin.Default()
+ // definir um limite de memória mais baixa
+ // para formulários de várias partes (o padrão é 32MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // formulário de várias partes
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // carregar o ficheiro para um destino específico.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+Como testar com a `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/pt/docs/examples/upload-file/single-file.md b/src/content/docs/pt/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..0f32d1447
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/upload-file/single-file.md
@@ -0,0 +1,38 @@
+---
+title: "Único Ficheiro"
+
+---
+
+Consulte a questão [#774](https://github.com/gin-gonic/gin/issues/774) e [exemplo de código](https://github.com/gin-gonic/examples/tree/master/upload-file/single) detalhado.
+
+`file.Filename` **NÃO DEVERIA** ser confiado. Consulte [`Content-Disposition` na MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) e a questão [#1693](https://github.com/gin-gonic/gin/issues/1693).
+
+> O nome do ficheiro sempre é opcional e não deve ser usado cegamente pela aplicação: a informação do caminho deveria ser esvaziada, e a conversão para as regras do sistema de ficheiro do servidor deveria ser feita.
+
+```go
+func main() {
+ router := gin.Default()
+ // definir um limite de memória mais baixa
+ // para formulários de várias partes (o padrão é 32MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // único ficheiro
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // carregar o ficheiro para um destino específico.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+Como testar com a `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/pt/docs/examples/using-basicauth-middleware.md b/src/content/docs/pt/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..e58e16e50
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Usar o Intermediário de BasicAuth"
+
+---
+
+```go
+// simular alguns dados privados
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // grupo usando intermediário de "gin.BasicAuth()"
+ // "gin.Accounts" é um atalho para "map[string]string"
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // o destino /admin/secrets
+ // alcança "localhost:8080/admin/secrets"
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // receber utilizador, foi definido pelo intermediário de BasicAuth
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // ouvir e servir no 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/examples/using-middleware.md b/src/content/docs/pt/docs/examples/using-middleware.md
new file mode 100644
index 000000000..ff0db3bd2
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/using-middleware.md
@@ -0,0 +1,46 @@
+---
+title: "Usar Intermediário"
+
+---
+
+```go
+func main() {
+ // criar um roteador sem nenhum intermediário por padrão
+ r := gin.New()
+
+ // intermediário global
+ // intermediário registador escreverá os registos ao "gin.DefaultWriter",
+ // mesmo se definires com "GIN_MODE=release".
+ // por padrão "gin.DefaultWriter = os.Stdout"
+ r.Use(gin.Logger())
+
+ // intermediário de recuperação recupera de quaisquer pânicos e
+ // escreve um 500 se ouve um.
+ r.Use(gin.Recovery())
+
+ // intermediário por rota, podes adicionar tanto quanto desejares.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // grupo de autorização
+ // authorized := r.Group("/", AuthRequired())
+ // exatamente o mesmo que:
+ authorized := r.Group("/")
+ // intermediário por grupo! neste caso usamos o intermediário
+ // "AuthRequired()" criado de maneira personalizada só no
+ // grupo "authorized".
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // grupo encaixado
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // ouvir e servir no 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/pt/docs/examples/without-middleware.md b/src/content/docs/pt/docs/examples/without-middleware.md
new file mode 100644
index 000000000..f7a04231c
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Sem Intermediário por Padrão"
+
+---
+
+Use:
+
+```go
+r := gin.New()
+```
+
+Ao invés de:
+
+```go
+// predefine com o intermediário registador e de recuperação já em anexo.
+r := gin.Default()
+```
diff --git a/src/content/docs/pt/docs/examples/write-log.md b/src/content/docs/pt/docs/examples/write-log.md
new file mode 100644
index 000000000..1a3b4620b
--- /dev/null
+++ b/src/content/docs/pt/docs/examples/write-log.md
@@ -0,0 +1,27 @@
+---
+title: "Como Escrever Ficheiro de Registo"
+
+---
+
+```go
+func main() {
+ // desativar a cor da consola, não precisas de cor de consola quando
+ // escreves registos em um ficheiro.
+ gin.DisableConsoleColor()
+
+ // registando num ficheiro.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // use o seguinte código se precisares de escrever registos num ficheiro e
+ // imprimir na consola ao mesmo tempo.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/pt/docs/faq/index.md b/src/content/docs/pt/docs/faq/index.md
new file mode 100644
index 000000000..ad348f11f
--- /dev/null
+++ b/src/content/docs/pt/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: record some frequently asked question from GitHub Issue tab.
+
diff --git a/src/content/docs/pt/docs/features/index.md b/src/content/docs/pt/docs/features/index.md
new file mode 100644
index 000000000..0b33c56e5
--- /dev/null
+++ b/src/content/docs/pt/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "Características"
+
+sidebar:
+ order: 4
+---
+
+## Gin v1 estável apresenta:
+
+- Roteador de alocação zero.
+
+- Continua o roteador de HTTP e abstração mais rápida. Desde o roteamento à escrita.
+
+- Conjunto completo de testes unitários.
+
+- Testado em combate.
+
+- API imóvel, novos lançamentos não quebrarão o teu código.
diff --git a/src/content/docs/pt/docs/index.md b/src/content/docs/pt/docs/index.md
new file mode 100644
index 000000000..18d8af67d
--- /dev/null
+++ b/src/content/docs/pt/docs/index.md
@@ -0,0 +1,22 @@
+---
+title: "Documentação"
+linkTitle: "Documentação"
+sidebar:
+ order: 1
+---
+
+## O que é a Gin?
+
+A Gin é uma abstração de web escrita em Go (Golang). Ela apresenta uma API parecida com a Martini, mas com aumento de desempenho 40 vezes mais rápido do que a Martini. Se precisares de desempenho fantástico, sirva-te com algum Gin.
+
+## Como usar a Gin?
+
+Nós fornecemos [exemplos](https://github.com/gin-gonic/examples) de uso da API e listamos alguns [utilizadores de Gin](./users) conhecidos publicamente.
+
+## Como contribuir com a Gin?
+
+* Ajude as pessoas nos fóruns de discussão
+* Conte-nos as tuas histórias de sucesso usando a Gin
+* Conte-nos como podemos melhorar a Gin e ajude-nos a fazê-lo
+* Contribua para com um biblioteca existente
+
diff --git a/src/content/docs/pt/docs/introduction/index.md b/src/content/docs/pt/docs/introduction/index.md
new file mode 100644
index 000000000..1e17268ea
--- /dev/null
+++ b/src/content/docs/pt/docs/introduction/index.md
@@ -0,0 +1,47 @@
+---
+title: "Introdução"
+
+sidebar:
+ order: 1
+---
+
+A Gin é uma abstração de web escrita em Go (Golang). Ela apresenta uma API parecida com a Martini com desempenho muito melhor, acima de 40 vezes mais rápida graças ao [`httprouter`](https://github.com/julienschmidt/httprouter). Se precisares de desempenho e excelente produtividade, amarás a Gin.
+
+Nesta seção introduziremos o que a Gin é, quais problemas soluciona, e como pode ajudar o teu projeto.
+
+Ou, se estiveres pronto para usar a Gin no teu projeto, visite a [Introdução rápida](https://gin-gonic.com/docs/quickstart/).
+
+## Características
+
+### Rápida
+
+Roteamento baseado na árvore de Radix, pegada de memória pequena. Sem reflexão. Desempenho de API previsível.
+
+### Suporte à Intermediário
+
+Uma requisição de HTTP de chegada pode ser manipulada por uma série de intermediários e a ação final. Por exemplo: Registador, Autorização, GZIP e finalmente publicar uma mensagem na Base de Dados.
+
+### Livre de Avaria
+
+A Gin pode capturar um pânico ocorrido durante uma requisição de HTTP e recuperá-lo. Desta maneira, o teu servidor sempre estará disponível. Como exemplo - também é possível reportar este pânico para a Sentry!
+
+### Validação de JSON
+
+A Gin pode analisar e validar o JSON de uma requisição - por exemplo, verificando a existência de valores obrigatórios.
+
+### Agrupamento de Rotas
+
+Organiza melhor as tuas rotas. Autorização obrigatória vs não obrigatória, diferentes versões de API... Além destes, os grupos podem ser encaixados ilimitadamente sem degradar o desempenho.
+
+### Gestão de Erro
+
+A Gin fornece uma maneira conveniente de reunir todos os erros ocorridos durante uma requisição de HTTP. Eventualmente, um intermediário pode escrevê-los para um ficheiro de registo, para uma base de dados e envia-los através da rede.
+
+### Interpretação Embutida
+
+A Gin fornece uma API fácil de usar para interpretação de JSON, XML e HTML.
+
+### Extensível
+
+A criação de um intermediário é tão fácil, apenas consulte os códigos de exemplo.
+
diff --git a/src/content/docs/pt/docs/jsoniter/index.md b/src/content/docs/pt/docs/jsoniter/index.md
new file mode 100644
index 000000000..a4a5338b6
--- /dev/null
+++ b/src/content/docs/pt/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+### Construir com o [`jsoniter`](https://github.com/json-iterator/go)
+
+A Gin usa o módulo `encoding/json` como pacote de JSON padrão mas podes mudar para o [`jsoniter`](https://github.com/json-iterator/go) ao construir a partir de outros marcadores:
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/pt/docs/quickstart/index.md b/src/content/docs/pt/docs/quickstart/index.md
new file mode 100644
index 000000000..971235c88
--- /dev/null
+++ b/src/content/docs/pt/docs/quickstart/index.md
@@ -0,0 +1,88 @@
+---
+title: "Introdução Rápida"
+
+sidebar:
+ order: 2
+---
+
+Nesta introdução rápida, recolheremos entendimentos a partir de segmentos de código e aprenderemos a como:
+
+## Requisitos
+
+- Go 1.13 ou superior
+
+## Instalação
+
+Para instalar o pacote de Gin, precisas de instalar a Go e definir a tua área de trabalho de Go primeiro:
+
+1. Descarregue e instale-o:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. Importe-o no teu código:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (Opcional) Importe `net/http`. Isto é obrigatório para por exemplo se estiveres a usar constantes tais como `http.StatusOk`:
+
+```go
+import "net/http"
+```
+
+1. Crie a pasta do teu projeto e entre dentro dela com `cd`:
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. Copie um modelo de partida dentro do teu projeto:
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. Execute o teu projeto:
+
+```sh
+$ go run main.go
+```
+
+## Começar
+
+> Inseguro de como escrever e executar o código de Go? [Clique nesta ligação](https://golang.org/doc/code.html).
+
+Primeiro, crie um ficheiro chamado `example.go`:
+
+```sh
+# presuma os seguintes códigos no ficheiro `example.go`
+$ touch example.go
+```
+
+A seguir, coloque o seguinte código dentro do `example.go`:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // oiça e sirva na `0.0.0.0:8080`
+}
+```
+
+E, podes executar o código através de `go run example.go`:
+
+```sh
+# execute `example.go` e visite `0.0.0.0:8080/ping` no navegador
+$ go run example.go
+```
diff --git a/src/content/docs/pt/docs/testing/index.md b/src/content/docs/pt/docs/testing/index.md
new file mode 100644
index 000000000..23408d673
--- /dev/null
+++ b/src/content/docs/pt/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "Testagem"
+
+sidebar:
+ order: 7
+---
+
+## Como escrever um caso de teste para Gin?
+
+O pacote `net/http/httptest` é a maneira preferível para testagem de HTTP:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+O teste para exemplo de código acima:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/pt/docs/users/index.md b/src/content/docs/pt/docs/users/index.md
new file mode 100644
index 000000000..ca260bca7
--- /dev/null
+++ b/src/content/docs/pt/docs/users/index.md
@@ -0,0 +1,24 @@
+---
+title: "Utilizadores"
+
+sidebar:
+ order: 8
+---
+
+#### Uma lista projetos incríveis usando a abstração de web [Gin](https://github.com/gin-gonic/gin):
+
+* [gorush](https://github.com/appleboy/gorush): Um servidor de empurrar notificação escrito em Go.
+
+* [fnproject](https://github.com/fnproject/fn): O contentor nativo, plataforma sem servidor agnóstica da nuvem.
+
+* [photoprism](https://github.com/photoprism/photoprism): Gestão de fotografia pessoal alimentada pela Go e Google TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Porta de API radicalmente otimizada com intermediários.
+
+* [picfit](https://github.com/thoas/picfit): Um servidor de redimensionamento de imagem escrito em Go.
+
+* [gotify](https://github.com/gotify/server): Um servidor simples para transmissão e recebimento de mensagens em tempo real por tomada da web (web socket).
+
+* [cds](https://github.com/ovh/cds): Entrega Contínuas de Nível Empresarial e Plataforma de Código Aberto de Automação de DevOps.
+
+* [go-admin](https://github.com/go-admin-team/go-admin): É uma abstração de fundo central baseada na Go.
diff --git a/src/content/docs/pt/index.mdx b/src/content/docs/pt/index.mdx
new file mode 100644
index 000000000..045be261b
--- /dev/null
+++ b/src/content/docs/pt/index.mdx
@@ -0,0 +1,50 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: A mais rápida e completa abstração de web em Go. Transparente.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Aprenda mais
+ link: /pt/docs/
+ icon: right-arrow
+ - text: Descarregar
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## O que é a Gin?
+
+A Gin é uma abstração de web escrita em Golang. Ela apresenta uma API parecida com a Martini, mais com desempenho mais alto, 40 vezes mais rápida do que a Martini. Se precisas de desempenho e produtividade, amarás a Gin.
+
+
+
+ Árvore de roteamento baseada em Radix, pouco consumo de memória. Sem reflexão. Desempenho de API previsível.
+
+
+ Uma requisição futura de HTTP pode ser manipulada por uma cadeia de intermediários e pela ação final. Por exemplo: Registador, Autorização, GZIP e finalmente publicar uma mensagem na BD.
+
+
+ A Gin pode capturar um pânico que ocorreu durante uma requisição de HTTP e recuperá-lo. Deste maneira, o teu servidor estará sempre disponível. Também é possível informar este pânico ao Sentry por exemplo!
+
+
+ A Gin pode analisar e validar o JSON de uma requisição, verificando, por exemplo, a existência de valores obrigatórios.
+
+
+ Organiza melhor as tuas rotas. Autorização obrigatória vs não obrigatória, diferentes versões de API. Além disso, grupos podem ser encaixados infinitamente sem a degradação do desempenho.
+
+
+ A Gin fornece uma maneira conveniente de coletar todos os erros ocorridos durante uma requisição de HTTP. Eventualmente, o intermediário pode escrevê-los em um ficheiro de registo, em uma base de dados e enviá-los através da rede.
+
+
+ A Gin fornece uma API fácil de utilizar para interpretação de JSON, XML e HTML.
+
+
+ A criação de um novo intermediário é tão fácil, apenas consulte o código de exemplo.
+
+
diff --git a/src/content/docs/ru/blog/index.md b/src/content/docs/ru/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/ru/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/ru/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/ru/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/ru/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/ru/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/ru/blog/releases/release13.md b/src/content/docs/ru/blog/releases/release13.md
similarity index 100%
rename from content/ru/blog/releases/release13.md
rename to src/content/docs/ru/blog/releases/release13.md
diff --git a/content/ru/blog/releases/release14.md b/src/content/docs/ru/blog/releases/release14.md
similarity index 100%
rename from content/ru/blog/releases/release14.md
rename to src/content/docs/ru/blog/releases/release14.md
diff --git a/content/ru/blog/releases/release15.md b/src/content/docs/ru/blog/releases/release15.md
similarity index 100%
rename from content/ru/blog/releases/release15.md
rename to src/content/docs/ru/blog/releases/release15.md
diff --git a/content/ru/blog/releases/release16.md b/src/content/docs/ru/blog/releases/release16.md
similarity index 100%
rename from content/ru/blog/releases/release16.md
rename to src/content/docs/ru/blog/releases/release16.md
diff --git a/src/content/docs/ru/docs/benchmarks/index.md b/src/content/docs/ru/docs/benchmarks/index.md
new file mode 100644
index 000000000..64e565706
--- /dev/null
+++ b/src/content/docs/ru/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "Контрольные показатели"
+
+sidebar:
+ order: 3
+---
+
+Gin использует пользовательскую версию [HttpRouter](https://github.com/julienschmidt/httprouter).
+
+[Посмотреть все контрольные показатели](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): Общее количество повторений, достигнутое за постоянное время, большее количество означает более уверенный результат
+- (2): Длительность одного повторения (ns/op), меньше - лучше
+- (3): Память кучи (B/op), меньше - лучше
+- (4): Среднее количество выделений за повтор (allocs/op), ниже - лучше
diff --git a/src/content/docs/ru/docs/deployment/index.md b/src/content/docs/ru/docs/deployment/index.md
new file mode 100644
index 000000000..6d3537fb0
--- /dev/null
+++ b/src/content/docs/ru/docs/deployment/index.md
@@ -0,0 +1,32 @@
+---
+title: "Deployment"
+
+sidebar:
+ order: 6
+---
+
+Проекты Gin могут быть легко развернуты на любом облачном провайдере.
+
+## [Koyeb](https://www.koyeb.com)
+
+Koyeb - это удобная для разработчиков бессерверная платформа для глобального развертывания приложений с развертыванием на основе git, шифрованием TLS, встроенным автомасштабированием, глобальной пограничной сетью и встроенным сервисом mesh & discovery.
+
+Следуйте руководству Koyeb [Guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
+
+## [Qovery](https://www.qovery.com)
+
+Qovery предоставляет бесплатный облачный хостинг с базами данных, SSL, глобальной CDN и автоматическим развертыванием с помощью Git.
+
+Следуйте руководству Qovery, чтобы [развернуть свой проект Gin](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/).
+
+## [Render](https://render.com)
+
+Render - это современная облачная платформа, которая предлагает встроенную поддержку Go, полностью управляемый SSL, базы данных, деплой с нулевым временем простоя, HTTP/2 и поддержку websocket.
+
+Следуйте рекомендациям Render [руководство по развертыванию проектов Gin](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+В GAE есть два способа развертывания Go-приложений. Стандартная среда проще в использовании, но менее настраиваема и не допускает [syscalls](https://github.com/gin-gonic/gin/issues/1639) по соображениям безопасности. В гибком окружении можно запускать любые фреймворки и библиотеки.
+
+Узнать больше и выбрать предпочтительную среду можно на сайте [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/ru/docs/examples/ascii-json.md b/src/content/docs/ru/docs/examples/ascii-json.md
new file mode 100644
index 000000000..38f4c350a
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+черновик: false
+---
+
+Использование AsciiJSON для генерации ASCII-единственного JSON с экранированными не-ASCII символами.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/ru/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..0a1cfbf41
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Попытайтесь связать тело в разных структурах"
+
+---
+
+Обычные методы для связывания тела запроса (request body) потребляют `c.Request.Body` и их
+не могут быть вызваны несколько раз.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Always an error is occurred by this because c.Request.Body is EOF now.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+Для этого можно использовать `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This reads c.Request.Body and stores the result into the context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // At this time, it reuses body stored in the context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // And it can accepts other formats
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` сохраняет тело в контексте перед привязкой. Это
+небольшое влияние на производительность, поэтому не стоит использовать этот метод, если вы
+достаточно вызвать привязку сразу.
+* Эта возможность необходима только для некоторых форматов - `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. Для других форматов, `Query`, `Form`, `FormPost`, `FormMultipart`,
+могут быть вызваны `c.ShouldBind()` многократно без ущерба для
+производительности (см. [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/ru/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/ru/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..357a7d0be
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "Связывание запроса формы-данных с пользовательской структурой"
+черновик: false
+---
+
+Следующий пример с использованием пользовательской структуры:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Результаты при использовании `curl`:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/ru/docs/examples/bind-html-checkbox.md b/src/content/docs/ru/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..458be46fb
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,45 @@
+---
+title: "Привязка html-флажков"
+
+---
+
+Смотрите [подробную информацию](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+```html
+
+```
+
+Результат:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/content/ru/docs/examples/bind-query-or-post.md b/src/content/docs/ru/docs/examples/bind-query-or-post.md
similarity index 100%
rename from content/ru/docs/examples/bind-query-or-post.md
rename to src/content/docs/ru/docs/examples/bind-query-or-post.md
diff --git a/src/content/docs/ru/docs/examples/bind-single-binary-with-template.md b/src/content/docs/ru/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..23c2c8319
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,45 @@
+---
+title: "Создание единого бинарного файла с помощью шаблонов"
+
+---
+## Использование стороннего пакета
+
+Вы можете использовать сторонний пакет для сборки сервера в единый бинарник, содержащий шаблоны, используя [go-assets](https://github.com/jessevdk/go-assets).
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+Полный пример находится в каталоге [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01).
diff --git a/src/content/docs/ru/docs/examples/bind-uri.md b/src/content/docs/ru/docs/examples/bind-uri.md
new file mode 100644
index 000000000..9054fe811
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Связывание Uri"
+
+---
+
+Смотрите [подробную информацию](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err.Error()})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Тестирование:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/ru/docs/examples/binding-and-validation.md b/src/content/docs/ru/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..75b60ceca
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Связывание и проверка моделей"
+черновик: false
+---
+
+Чтобы привязать тело запроса к типу, используйте привязку к модели. В настоящее время мы поддерживаем привязку JSON, XML, YAML и стандартных значений формы (foo=bar&boo=baz).
+
+Для валидации Gin использует [**go-playground/validator/v10**](https://github.com/go-playground/validator). Ознакомьтесь с полной документацией по использованию тегов [здесь](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Обратите внимание, что вам необходимо установить соответствующий тег привязки для всех полей, которые вы хотите привязать. Например, при привязке из JSON установите `json: "fieldname"`.
+
+Кроме того, Gin предоставляет два набора методов для привязки:
+- **Type** - Must bind
+ - **Методы** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Поведение** - Эти методы используют `MustBindWith` под капотом. Если произошла ошибка связывания, запрос прерывается с помощью `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. При этом код состояния ответа принимает значение 400, а заголовок `Content-Type` устанавливается на `text/plain; charset=utf-8`. Обратите внимание, что если вы попытаетесь установить код ответа после этого, то это приведет к предупреждению `[GIN-debug] [WARNING] Заголовки уже были записаны. Хотелось отменить код статуса 400 на 422`. Если вы хотите получить больший контроль над поведением, используйте эквивалентный метод `ShouldBind`.
+- **Тип** - Should bind
+ - **Методы** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Поведение** - Эти методы используют `ShouldBindWith` под капотом. Если произошла ошибка связывания, возвращается ошибка, и разработчик обязан обработать запрос и ошибку соответствующим образом.
+
+При использовании Bind-метода Gin пытается определить связующее звено в зависимости от заголовка Content-Type. Если вы уверены, что именно вы связываете, вы можете использовать `MustBindWith` или `ShouldBindWith`.
+
+Вы также можете указать, что определенные поля являются обязательными. Если поле украшено `binding: "required"` и при привязке имеет пустое значение, будет возвращена ошибка.
+
+```go
+// Binding from JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Example for binding JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding a HTML form (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // This will infer what binder to use depending on the content-type header.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Пример запроса
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Пропустить валидацию
+
+При выполнении приведенного выше примера с помощью указанной выше команды `curl` возвращается ошибка. Потому что в примере используется `привязка: "required"` для `Password`. Если использовать `binding:"-"` для `Password`, то при повторном запуске приведенного выше примера ошибка не возникнет.
diff --git a/src/content/docs/ru/docs/examples/controlling-log-output-coloring.md b/src/content/docs/ru/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..7bbe1fe0c
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Управление раскраской вывода журнала"
+
+---
+
+По умолчанию логи, выводимые на консоль, должны быть окрашены в зависимости от обнаруженного TTY.
+
+Никогда не окрашивать журналы:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Всегда окрашивайте журналы в разные цвета:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/cookie.md b/src/content/docs/ru/docs/examples/cookie.md
new file mode 100644
index 000000000..dba1ce64c
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Установка и получение cookie"
+черновик: false
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/ru/docs/examples/custom-http-config.md b/src/content/docs/ru/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..209b6cb85
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "Пользовательская конфигурация HTTP"
+черновик: false
+---
+
+Используйте `http.ListenAndServe()` напрямую, например, так:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/ru/docs/examples/custom-log-format.md b/src/content/docs/ru/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..63d80fa6c
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "Пользовательский файл журнала"
+черновик: false
+---
+
+Например:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Образец вывода**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/ru/docs/examples/custom-middleware.md b/src/content/docs/ru/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..8ee5b41cc
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Custom Middleware"
+черновик: false
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Set example variable
+ c.Set("example", "12345")
+
+ // before request
+
+ c.Next()
+
+ // after request
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // access the status we are sending
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // it would print: "12345"
+ log.Println(example)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/custom-validators.md b/src/content/docs/ru/docs/examples/custom-validators.md
new file mode 100644
index 000000000..9d1abb931
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Пользовательские валидаторы"
+
+---
+
+Также можно зарегистрировать пользовательские валидаторы. Смотрите [пример кода](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking contains binded and validated data.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+[Валидации уровня структуры](https://github.com/go-playground/validator/releases/tag/v8.7) также могут быть зарегистрированы таким образом.
+Смотрите пример [struct-lvl-validation](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations), чтобы узнать больше.
diff --git a/src/content/docs/ru/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/ru/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..51ee703bb
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,45 @@
+---
+title: "Определить формат для журнала маршрутов"
+
+---
+
+
+По умолчанию журнал маршрутов имеет следующий вид:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+Если вы хотите записывать эту информацию в заданном формате (например, JSON, значения ключей или что-то еще), то вы можете определить этот формат с помощью `gin.DebugPrintRouteFunc`.
+В примере ниже мы ведем лог всех маршрутов с помощью стандартного пакета лога, но вы можете использовать другие инструменты лога, которые подходят для ваших нужд.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/ru/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/ru/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..1081c4025
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Гороутины внутри промежуточного ПО"
+черновик: false
+---
+
+При запуске новых Goroutines внутри промежуточного ПО или обработчика, вы **НЕ ДОЛЖНЫ** использовать оригинальный контекст внутри него, вы должны использовать копию, доступную только для чтения.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // create copy to be used inside the goroutine
+ cCp := c.Copy()
+ go func() {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // note that you are using the copied context "cCp", IMPORTANT
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // since we are NOT using a goroutine, we do not have to copy the context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/graceful-restart-or-stop.md b/src/content/docs/ru/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..af8d3bd2b
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,85 @@
+---
+title: "Благодатный перезапуск или остановка"
+черновик: false
+---
+
+Вы хотите произвести плавный перезапуск или остановку вашего веб-сервера?
+Есть несколько способов сделать это.
+
+Мы можем использовать [fvbock/endless](https://github.com/fvbock/endless) для замены стандартного `ListenAndServe`. Более подробную информацию см. в выпуске [#296](https://github.com/gin-gonic/gin/issues/296).
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+Альтернатива бесконечности:
+
+* [manners](https://github.com/braintree/manners): Вежливый HTTP-сервер Go, который изящно завершает работу.
+* [graceful](https://github.com/tylerb/graceful): Graceful - это пакет Go, позволяющий изящно завершить работу сервера http.Handler.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy для Go-серверов.
+
+Если вы используете Go 1.8, возможно, вам не понадобится эта библиотека! Лучше используйте встроенный метод http.Server [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) для изящного завершения работы. Посмотрите полный пример [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) с gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router.Handler(),
+ }
+
+ go func() {
+ // service connections
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Wait for interrupt signal to gracefully shutdown the server with
+ // a timeout of 5 seconds.
+ quit := make(chan os.Signal, 1)
+ // kill (no param) default send syscall.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // catching ctx.Done(). timeout of 5 seconds.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/grouping-routes.md b/src/content/docs/ru/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..582959c23
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Группировка маршрутов"
+черновик: false
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Simple group: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Simple group: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/html-rendering.md b/src/content/docs/ru/docs/examples/html-rendering.md
new file mode 100644
index 000000000..8e07402bc
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML-рендеринг"
+
+---
+
+Использование LoadHTMLGlob() или LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Использование шаблонов с одинаковыми именами в разных каталогах
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Пользовательский рендерер шаблонов
+
+Вы также можете использовать собственный рендерер html-шаблонов
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Пользовательские разделители
+
+Вы можете использовать пользовательские разделители
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Пользовательские функции шаблона
+
+Смотрите подробный [пример кода](https://github.com/gin-gonic/examples/tree/master/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/ru/docs/examples/http-method.md b/src/content/docs/ru/docs/examples/http-method.md
new file mode 100644
index 000000000..e0e72c2d2
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Использование метода HTTP"
+
+---
+
+```go
+func main() {
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // By default it serves on :8080 unless a
+ // PORT environment variable was defined.
+ router.Run()
+ // router.Run(":3000") for a hard coded port
+}
+```
diff --git a/src/content/docs/ru/docs/examples/http2-server-push.md b/src/content/docs/ru/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..4120c2ae8
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+черновик: false
+---
+
+http.Pusher поддерживается только **go1.8+**. Подробную информацию смотрите в [golang blog](https://blog.golang.org/h2push).
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // use pusher.Push() to do server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Listen and Serve in https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/index.md b/src/content/docs/ru/docs/examples/index.md
new file mode 100644
index 000000000..9e574e105
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/index.md
@@ -0,0 +1,7 @@
+---
+title: "Примеры"
+черновик: false
+вес: 6
+---
+
+Раздел содержит список использования api.
diff --git a/src/content/docs/ru/docs/examples/jsonp.md b/src/content/docs/ru/docs/examples/jsonp.md
new file mode 100644
index 000000000..38eb76beb
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+черновик: false
+---
+
+Использование JSONP для запроса данных с сервера в другом домене. Добавьте обратный вызов в тело ответа, если существует обратный вызов параметра запроса.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback is x
+ // Will output : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/ru/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..c964477bf
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Структура данных Map виде строки запроса или параметров постформы"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/ru/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/ru/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..c62b6195e
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Связка Multipart/Urlencoded"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // you can bind multipart form with explicit binding declaration:
+ // c.ShouldBindWith(&form, binding.Form)
+ // or you can simply use autobinding with ShouldBind method:
+ var form LoginForm
+ // in this case proper binding will be automatically selected
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Тестирование:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/ru/docs/examples/multipart-urlencoded-form.md b/src/content/docs/ru/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..61940f99f
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Форма Multipart/Urlencoded"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/multiple-template.md b/src/content/docs/ru/docs/examples/multiple-template.md
new file mode 100644
index 000000000..f451e4c00
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Несколько HTML темплейтов"
+черновик: false
+---
+
+Gin позволяет по умолчанию использовать только один html.Template. Проверьте [a multitemplate render](https://github.com/gin-contrib/multitemplate) для использования таких возможностей, как go 1.6 `block template`.
diff --git a/src/content/docs/ru/docs/examples/only-bind-query-string.md b/src/content/docs/ru/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..e156a6a9a
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Только связывание строки запроса"
+
+---
+
+Функция `ShouldBindQuery` связывает только параметры запроса, но не данные поста. См. [подробную информацию](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/param-in-path.md b/src/content/docs/ru/docs/examples/param-in-path.md
new file mode 100644
index 000000000..38f1abdaa
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Параметры в path"
+черновик: false
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // This handler will match /user/john but will not match /user/ or /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // However, this one will match /user/john/ and also /user/john/send
+ // If no other routers match /user/john, it will redirect to /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/pure-json.md b/src/content/docs/ru/docs/examples/pure-json.md
new file mode 100644
index 000000000..63dbc37c2
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/pure-json.md
@@ -0,0 +1,30 @@
+---
+title: "PureJSON"
+черновик: false
+---
+
+Обычно JSON заменяет специальные HTML-символы их юникодными сущностями, например, `<` становится `\u003c`. Если вы хотите кодировать такие символы буквально, вы можете использовать PureJSON.
+Эта функция недоступна в Go 1.6 и ниже.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/query-and-post-form.md b/src/content/docs/ru/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..07eb8fead
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Форма для запросов и сообщений"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/ru/docs/examples/querystring-param.md b/src/content/docs/ru/docs/examples/querystring-param.md
new file mode 100644
index 000000000..4aa91718c
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Параметры строки запроса"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Query string parameters are parsed using the existing underlying request object.
+ // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/redirects.md b/src/content/docs/ru/docs/examples/redirects.md
new file mode 100644
index 000000000..56b15e672
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Перенаправления"
+черновик: false
+---
+
+Создать HTTP-перенаправление очень просто. Поддерживаются как внутренние, так и внешние расположения.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Выдача HTTP-перенаправления из POST. См. выпуск: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Выдавая перенаправление Router, используйте `HandleContext`, как показано ниже.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/ru/docs/examples/rendering.md b/src/content/docs/ru/docs/examples/rendering.md
new file mode 100644
index 000000000..f93de6dc9
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "Рендеринг XML/JSON/YAML/ProtoBuf"
+черновик: false
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H is a shortcut for map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // You also can use a struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Note that msg.Name becomes "user" in the JSON
+ // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/run-multiple-service.md b/src/content/docs/ru/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..2232e067c
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Запустить несколько сервисов"
+черновик: false
+---
+
+Посмотрите [вопрос](https://github.com/gin-gonic/gin/issues/346) и попробуйте следующий пример:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/secure-json.md b/src/content/docs/ru/docs/examples/secure-json.md
new file mode 100644
index 000000000..1e97333ef
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+черновик: false
+---
+
+Использование SecureJSON для предотвращения перехвата json. По умолчанию добавляет `"while(1),"` в тело ответа, если заданная структура представляет собой массив значений.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // You can also use your own secure json prefix
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Will output : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/security-headers.md b/src/content/docs/ru/docs/examples/security-headers.md
new file mode 100644
index 000000000..6bf4aa6d9
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "Заголовки безопасности"
+черновик: false
+---
+
+Важно использовать заголовки безопасности, чтобы защитить ваше веб-приложение от распространенных уязвимостей. Этот пример показывает, как добавить заголовки безопасности в ваше приложение Gin, а также как избежать атак, связанных с инъекцией заголовков хоста (SSRF, Open Redirection).
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+Вы можете проверить его с помощью `curl`:
+
+```bash
+// Проверка заголовок
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// Проверка инъекции в заголовок хоста
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/ru/docs/examples/serving-data-from-reader.md b/src/content/docs/ru/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..2bb891b53
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Манипуляция данных от читателя"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/serving-static-files.md b/src/content/docs/ru/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..c6985e613
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Использование статических файлов"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/support-lets-encrypt.md b/src/content/docs/ru/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..6452bb654
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Поддержка Let's Encrypt"
+черновик: false
+---
+
+пример для 1-строчных HTTPS-серверов LetsEncrypt.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+пример для пользовательского менеджера автосертификации.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/upload-file/index.md b/src/content/docs/ru/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..dc2930ade
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Загрузить файлы"
+
+---
+
+Раздел содержит список использования api загрузки файлов.
diff --git a/src/content/docs/ru/docs/examples/upload-file/multiple-file.md b/src/content/docs/ru/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..e89e10f46
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Multiple files"
+
+---
+
+Смотрите подробности [пример кода](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+Как тестировать с помощью `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/ru/docs/examples/upload-file/single-file.md b/src/content/docs/ru/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..158d84160
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/upload-file/single-file.md
@@ -0,0 +1,36 @@
+---
+title: "Single file"
+
+---
+Ссылки на проблему [#774](https://github.com/gin-gonic/gin/issues/774) и деталь [пример кода](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **НЕ ДОЛЖНО** быть доверенным. См. [`Content-Disposition` на MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) и [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> Имя файла всегда необязательно и не должно использоваться приложением вслепую: информация о пути должна быть удалена, и должно быть выполнено преобразование к правилам файловой системы сервера.
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // single file
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+Как тестировать с помощью `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/ru/docs/examples/using-basicauth-middleware.md b/src/content/docs/ru/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..a1faa44e2
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Использование промежуточного ПО BasicAuth"
+черновик: false
+---
+
+```go
+// simulate some private data
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Group using gin.BasicAuth() middleware
+ // gin.Accounts is a shortcut for map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets endpoint
+ // hit "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // get user, it was set by the BasicAuth middleware
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/examples/using-middleware.md b/src/content/docs/ru/docs/examples/using-middleware.md
new file mode 100644
index 000000000..9f9a0b7ce
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Использование промежуточного ПО"
+черновик: false
+---
+
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.Recovery())
+
+ // Per route middleware, you can add as many as you desire.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Authorization group
+ // authorized := r.Group("/", AuthRequired())
+ // exactly the same as:
+ authorized := r.Group("/")
+ // per group middleware! in this case we use the custom created
+ // AuthRequired() middleware just in the "authorized" group.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // nested group
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/ru/docs/examples/without-middleware.md b/src/content/docs/ru/docs/examples/without-middleware.md
new file mode 100644
index 000000000..0cd958f42
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Без промежуточного ПО по умолчанию"
+
+---
+
+Используйте
+
+```go
+r := gin.New()
+```
+
+место
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
diff --git a/src/content/docs/ru/docs/examples/write-log.md b/src/content/docs/ru/docs/examples/write-log.md
new file mode 100644
index 000000000..2e04a57be
--- /dev/null
+++ b/src/content/docs/ru/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "Как записать файл журнала"
+
+---
+
+```go
+func main() {
+ // Disable Console Color, you don't need console color when writing the logs to file.
+ gin.DisableConsoleColor()
+
+ // Logging to a file.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Use the following code if you need to write the logs to file and console at the same time.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/ru/docs/faq/index.md b/src/content/docs/ru/docs/faq/index.md
new file mode 100644
index 000000000..9328e6b56
--- /dev/null
+++ b/src/content/docs/ru/docs/faq/index.md
@@ -0,0 +1,8 @@
+---
+title: "FAQ"
+черновик: false
+вес: 9
+---
+
+TODO: записать некоторые часто задаваемые вопросы из вкладки GitHub Issue.
+
diff --git a/src/content/docs/ru/docs/features/index.md b/src/content/docs/ru/docs/features/index.md
new file mode 100644
index 000000000..2f76e08aa
--- /dev/null
+++ b/src/content/docs/ru/docs/features/index.md
@@ -0,0 +1,17 @@
+---
+title: "Особенности"
+черновик: false
+вес: 4
+---
+
+## Стабильные возможности Gin v1:
+
+- Маршрутизатор с нулевым распределением.
+
+- По-прежнему самый быстрый http-маршрутизатор и фреймворк. От маршрутизации до написания.
+
+- Полный набор модульных тестов.
+
+- Проверено в бою.
+
+- API заморожен, новые релизы не сломают ваш код.
diff --git a/src/content/docs/ru/docs/index.md b/src/content/docs/ru/docs/index.md
new file mode 100644
index 000000000..8adac4d20
--- /dev/null
+++ b/src/content/docs/ru/docs/index.md
@@ -0,0 +1,24 @@
+---
+title: "Документация"
+linkTitle: "Документация"
+вес: 20
+menu:
+ main:
+ вес: 20
+---
+
+## Что такое Gin?
+
+Gin - это HTTP-веб-фреймворк, написанный на языке Go (Golang). В нем реализован API, похожий на Martini, но с производительностью в 40 раз выше, чем у Martini. Если вам нужна потрясающая производительность, купите себе Gin.
+
+## Как использовать Gin?
+
+Мы приводим [примеры] использования API (https://github.com/gin-gonic/examples) и список известных пользователей [Gin](./users).
+
+## Как внести свой вклад в развитие Gin?
+
+* Помогайте людям на дискуссионных форумах.
+* Расскажите нам о своих успехах в использовании Gin
+* Расскажите нам, как мы можем улучшить Gin, и помогите нам в этом.
+* Внести вклад в существующую библиотеку
+
diff --git a/src/content/docs/ru/docs/introduction/index.md b/src/content/docs/ru/docs/introduction/index.md
new file mode 100644
index 000000000..3fe50bf37
--- /dev/null
+++ b/src/content/docs/ru/docs/introduction/index.md
@@ -0,0 +1,49 @@
+---
+title: "Введение"
+черновик: false
+вес: 1
+---
+
+Gin - это веб-фреймворк, написанный на языке Go (Golang). В нем реализован мартини-подобный API с гораздо лучшей производительностью, до 40 раз быстрее благодаря [httprouter](https://github.com/julienschmidt/httprouter). Если вам нужна производительность и хорошая продуктивность, вам понравится Gin.
+
+В этом разделе мы расскажем о том, что такое Gin, какие проблемы он решает и как он может помочь вашему проекту.
+
+Если же вы уже готовы использовать Gin в своем проекте, посетите [Quickstart](https://gin-gonic.com/docs/quickstart/).
+
+## Особенности
+
+### Быстрый
+
+Маршрутизация на основе радиксного дерева, малый объем памяти. Никаких отражений. Предсказуемая производительность API.
+
+### Поддержка промежуточного ПО
+
+Входящий HTTP-запрос может быть обработан цепочкой промежуточных программ и завершен конечным действием.
+Например: Логгер, Авторизация, GZIP и, наконец, публикация сообщения в БД.
+
+### Защита от сбоев
+
+Gin может поймать панику, возникшую во время HTTP-запроса, и восстановить ее. Таким образом, ваш сервер будет всегда доступен. В качестве примера - можно также сообщить об этой панике в Sentry!
+
+Переведено с помощью DeepL.com (бесплатная версия)
+
+### Проверка JSON
+
+Gin может анализировать и проверять JSON-запрос - например, проверять наличие необходимых значений.
+
+### Группировка маршрутов
+
+Организуйте свои маршруты лучше. Требуемая и необязательная авторизация, разные версии API... Кроме того, группы могут быть неограниченно вложены друг в друга без снижения производительности.
+
+### Управление ошибками
+
+Gin предоставляет удобный способ сбора всех ошибок, возникших во время HTTP-запроса. В конечном итоге промежуточное ПО может записывать их в лог-файл, в базу данных или отправлять по сети.
+
+### Рендеринг встроенный
+
+Gin предоставляет простой в использовании API для рендеринга JSON, XML и HTML.
+
+### Расширяемость
+
+Создать новое промежуточное ПО очень просто, просто посмотрите примеры кодов.
+
diff --git a/src/content/docs/ru/docs/jsoniter/index.md b/src/content/docs/ru/docs/jsoniter/index.md
new file mode 100644
index 000000000..12896069a
--- /dev/null
+++ b/src/content/docs/ru/docs/jsoniter/index.md
@@ -0,0 +1,13 @@
+---
+title: "Jsoniter"
+черновик: false
+вес: 5
+---
+
+## Сборка с [jsoniter](https://github.com/json-iterator/go)
+
+Gin использует `encoding/json` как пакет json по умолчанию, но вы можете изменить его на [jsoniter](https://github.com/json-iterator/go), собирая из других тегов.
+
+``sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/ru/docs/quickstart/index.md b/src/content/docs/ru/docs/quickstart/index.md
new file mode 100644
index 000000000..301b2224e
--- /dev/null
+++ b/src/content/docs/ru/docs/quickstart/index.md
@@ -0,0 +1,87 @@
+---
+title: "Быстрый старт"
+черновик: false
+вес: 2
+---
+
+В этом кратком руководстве мы извлечем уроки из сегментов кода и узнаем, как:
+
+## Требования
+
+- Go 1.16 или выше
+
+## Установка
+
+Чтобы установить пакет Gin, необходимо сначала установить Go и настроить рабочее пространство Go.
+
+1. Скачайте и установите его:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. Импортируйте его в свой код:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (Необязательно) Импортируйте `net/http`. Это необходимо, например, при использовании таких констант, как `http.StatusOK`.
+
+```go
+import "net/http"
+```
+
+1. Создайте папку проекта и `cd` в ней
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. Скопируйте начальный шаблон в свой проект
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. Запустите свой проект
+
+```sh
+$ go run main.go
+```
+
+## Начало работы
+
+> Не знаете, как написать и выполнить код Go? [Нажмите здесь](https://golang.org/doc/code.html).
+
+Сначала создайте файл с именем `example.go`:
+
+```sh
+# assume the following codes in example.go file
+$ touch example.go
+```
+
+Затем поместите следующий код в файл `example.go`:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+И вы можете запустить код с помощью `go run example.go`:
+
+```sh
+# run example.go and visit 0.0.0.0:8080/ping on browser
+$ go run example.go
+```
diff --git a/src/content/docs/ru/docs/testing/index.md b/src/content/docs/ru/docs/testing/index.md
new file mode 100644
index 000000000..a7fbdc7d6
--- /dev/null
+++ b/src/content/docs/ru/docs/testing/index.md
@@ -0,0 +1,89 @@
+---
+title: "Тестирование"
+черновик: false
+вес: 7
+---
+
+## Как написать тестовый пример для Gin?
+
+Пакет `net/http/httptest` является предпочтительным способом для тестирования HTTP.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+Тест для примера кода, приведенного выше:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/ru/docs/users/index.md b/src/content/docs/ru/docs/users/index.md
new file mode 100644
index 000000000..4b3e43ce0
--- /dev/null
+++ b/src/content/docs/ru/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Users"
+
+sidebar:
+ order: 8
+---
+
+##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
+
+* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
+
+* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+
+* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+
+* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
+
+* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
+
+* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/src/content/docs/ru/index.mdx b/src/content/docs/ru/index.mdx
new file mode 100644
index 000000000..0b519b008
--- /dev/null
+++ b/src/content/docs/ru/index.mdx
@@ -0,0 +1,50 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Самый быстрый полнофункциональный веб-фреймворк для Go. Кристально чистый.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Подробнее
+ link: /ru/docs/
+ icon: right-arrow
+ - text: Скачать
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## Что такое Gin?
+
+Gin - это веб-фреймворк, написанный на языке Golang. В нем реализован API, похожий на Martini, но производительность в 40 раз выше, чем у Martini. Если вам нужна производительность и продуктивность, Gin вам понравится.
+
+
+
+ Маршрутизация на основе радиксного дерева, малый объем памяти. Никаких отражений. Предсказуемая производительность API.
+
+
+ Входящий HTTP-запрос может быть обработан цепочкой промежуточного ПО (Middleware) и конечным действием. Например: Логгер, авторизация, GZIP и, наконец, публикация сообщения в БД.
+
+
+ Gin может поймать панику, возникшую во время HTTP-запроса, и восстановить ее. Таким образом, ваш сервер будет всегда доступен. Также можно сообщить об этой панике, например, в Sentry!
+
+
+ Gin может анализировать и проверять JSON-запросы, например, на наличие необходимых значений.
+
+
+ Организуйте свои маршруты лучше. Требуется и не требуется авторизация, разные версии API. Кроме того, группы могут быть вложены бесконечно без снижения производительности.
+
+
+ Gin обеспечивает удобный способ сбора всех ошибок, возникших во время HTTP-запроса. В конечном итоге промежуточное ПО (Middleware) может записывать их в файл журнала, в базу данных и отправлять через сеть.
+
+
+ Gin предоставляет простой в использовании API для рендеринга JSON, XML и HTML.
+
+
+ Создать новое промежуточное программное обеспечение очень просто, просто посмотрите пример кода.
+
+
\ No newline at end of file
diff --git a/src/content/docs/tr/blog/index.md b/src/content/docs/tr/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/tr/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/tr/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/tr/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/tr/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/tr/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/tr/blog/releases/release13.md b/src/content/docs/tr/blog/releases/release13.md
similarity index 100%
rename from content/tr/blog/releases/release13.md
rename to src/content/docs/tr/blog/releases/release13.md
diff --git a/content/tr/blog/releases/release14.md b/src/content/docs/tr/blog/releases/release14.md
similarity index 100%
rename from content/tr/blog/releases/release14.md
rename to src/content/docs/tr/blog/releases/release14.md
diff --git a/content/tr/blog/releases/release15.md b/src/content/docs/tr/blog/releases/release15.md
similarity index 100%
rename from content/tr/blog/releases/release15.md
rename to src/content/docs/tr/blog/releases/release15.md
diff --git a/content/tr/blog/releases/release16.md b/src/content/docs/tr/blog/releases/release16.md
similarity index 100%
rename from content/tr/blog/releases/release16.md
rename to src/content/docs/tr/blog/releases/release16.md
diff --git a/src/content/docs/tr/docs/benchmarks/index.md b/src/content/docs/tr/docs/benchmarks/index.md
new file mode 100644
index 000000000..58af0d148
--- /dev/null
+++ b/src/content/docs/tr/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "Kalite Testleri"
+
+sidebar:
+ order: 3
+---
+
+Gin, [HttpRouter](https://github.com/julienschmidt/httprouter)'ın özel bir sürümünü kullanır
+
+[Tüm kalite testlerini görün](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Kalite Testi Adı | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1): Sabit sürede elde edilen Toplam Tekrar, daha yüksek, daha emin sonuç anlamına gelir
+- (2): Tek Tekrar Süresi (ns/op), daha düşük daha iyidir
+- (3): Heap Memory (B/op), daha düşük daha iyidir
+- (4): Tekrar Başına Ortalama Allocations (allocs/op), daha düşük daha iyidir
diff --git a/src/content/docs/tr/docs/deployment/index.md b/src/content/docs/tr/docs/deployment/index.md
new file mode 100644
index 000000000..feeb7277b
--- /dev/null
+++ b/src/content/docs/tr/docs/deployment/index.md
@@ -0,0 +1,32 @@
+---
+title: "Deploy etme"
+
+sidebar:
+ order: 6
+---
+
+Gin projeleri herhangi bir bulut sağlayıcısına kolayca deploy edilebilir.
+
+## [Koyeb](https://www.koyeb.com)
+
+Koyeb, git tabanlı, TLS şifreleme, yerel otomatik ölçeklendirme, küresel uç ağ ve yerleşik hizmet ağı ve keşfi ile uygulamaları küresel olarak dağıtmak/deploy etmek için geliştirici dostu sunucusuz bir platformdur.
+
+Koyeb'i takip edin [guide to deploy your Gin projects](https://www.koyeb.com/tutorials/deploy-go-gin-on-koyeb).
+
+## [Qovery](https://www.qovery.com)
+
+Qovery; veri tabanı, SSL'i, küresel CDN'i olan ve Git ile otomatik deploy için ücretsiz bulut ortamı sağlar.
+
+[Gin projenizi deploy etmek](https://docs.qovery.com/guides/tutorial/deploy-gin-with-postgresql/) için Qovery kılavuzunu izleyin.
+
+## [Render](https://render.com)
+
+Render; Go, tam yönetilebilen SSL, veritabanları, sıfır kesintili deploy, HTTP/2 ve websocket desteği için yerel destek sunan modern bir bulut platformudur.
+
+Render'ı takip edin [Gin projelerini dağıtma kılavuzu.](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE, Go uygulamalarını dağıtmanın iki yönteme sahiptir. Standart ortamın kullanımı daha kolaydır ancak daha az özelleştirilebilir ve güvenlik nedenleriyle [syscalls](https://github.com/gin-gonic/gin/issues/1639) gibi sistem çağrılarını önler.
+
+Daha fazla bilgi edinin ve tercih ettiğiniz ortamı şuradan seçin: [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/).
diff --git a/src/content/docs/tr/docs/examples/ascii-json.md b/src/content/docs/tr/docs/examples/ascii-json.md
new file mode 100644
index 000000000..7e2d2b0d0
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/tr/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..138179eea
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Try to bind body into different structs"
+
+---
+
+The normal methods for binding request body consumes `c.Request.Body` and they
+cannot be called multiple times.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Always an error is occurred by this because c.Request.Body is EOF now.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This reads c.Request.Body and stores the result into the context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // At this time, it reuses body stored in the context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // And it can accepts other formats
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` stores body into the context before binding. This has
+a slight impact to performance, so you should not use this method if you are
+enough to call binding at once.
+* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
+can be called by `c.ShouldBind()` multiple times without any damage to
+performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/tr/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/tr/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..92ab2f4b8
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,77 @@
+---
+title: "Bind form-data request with custom struct"
+
+---
+
+The follow example using custom struct:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Using the command `curl` command result:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
diff --git a/src/content/docs/tr/docs/examples/bind-html-checkbox.md b/src/content/docs/tr/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..4b1ee65ef
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Bind html checkboxes"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+result:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/tr/docs/examples/bind-query-or-post.md b/src/content/docs/tr/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..9912d908a
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "Bind query string or post data"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // If `GET`, only `Form` binding engine (`query`) used.
+ // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
+ // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Test it with:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/tr/docs/examples/bind-single-binary-with-template.md b/src/content/docs/tr/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..09e8b02fc
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,45 @@
+---
+title: "Build a single binary with templates"
+
+---
+## Use the third-party package
+
+You can use the third party package to build a server into a single binary containing templates by using [go-assets](https://github.com/jessevdk/go-assets).
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/src/content/docs/tr/docs/examples/bind-uri.md b/src/content/docs/tr/docs/examples/bind-uri.md
new file mode 100644
index 000000000..b2092e977
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Bind Uri"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+Test it with:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/tr/docs/examples/binding-and-validation.md b/src/content/docs/tr/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..40684022c
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Model binding and validation"
+
+---
+
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
+
+Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
+
+Also, Gin provides two sets of methods for binding:
+- **Type** - Must bind
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
+- **Type** - Should bind
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
+
+When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
+
+You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
+
+```go
+// Binding from JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Example for binding JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding a HTML form (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // This will infer what binder to use depending on the content-type header.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+### Sample request
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+### Skip validate
+
+When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/src/content/docs/tr/docs/examples/controlling-log-output-coloring.md b/src/content/docs/tr/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..c0973a85a
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,44 @@
+---
+title: "Controlling Log output coloring"
+
+---
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/cookie.md b/src/content/docs/tr/docs/examples/cookie.md
new file mode 100644
index 000000000..090e66354
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Set and get a cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/tr/docs/examples/custom-http-config.md b/src/content/docs/tr/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..42de78314
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "Custom HTTP configuration"
+
+---
+
+Use `http.ListenAndServe()` directly, like this:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/tr/docs/examples/custom-log-format.md b/src/content/docs/tr/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..6d6450341
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "Custom log file"
+
+---
+
+For example:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter middleware will write the logs to gin.DefaultWriter
+ // By default gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // your custom format
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**Sample Output**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/tr/docs/examples/custom-middleware.md b/src/content/docs/tr/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..8de8438b0
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Custom Middleware"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Set example variable
+ c.Set("example", "12345")
+
+ // before request
+
+ c.Next()
+
+ // after request
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // access the status we are sending
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // it would print: "12345"
+ log.Println(example)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/custom-validators.md b/src/content/docs/tr/docs/examples/custom-validators.md
new file mode 100644
index 000000000..114de29af
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "Custom validators"
+
+---
+
+It is also possible to register custom validators. See the [example code](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking contains binded and validated data.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2118-04-16&check_out=2118-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2118-03-10&check_out=2118-03-09"
+{"error":"Key: 'Booking.CheckOut' Error:Field validation for 'CheckOut' failed on the 'gtfield' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
+See the [struct-lvl-validation example](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations) to learn more.
diff --git a/src/content/docs/tr/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/tr/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..44bd991a9
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "Define format for the log of routes"
+
+---
+
+The default log of routes is:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
+In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/tr/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/tr/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..f3a6b10d6
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Goroutines inside a middleware"
+
+---
+
+When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // create copy to be used inside the goroutine
+ cCp := c.Copy()
+ go func() {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // note that you are using the copied context "cCp", IMPORTANT
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // since we are NOT using a goroutine, we do not have to copy the context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/graceful-restart-or-stop.md b/src/content/docs/tr/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..633ad5324
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,85 @@
+---
+title: "Graceful restart or stop"
+
+---
+
+Do you want to graceful restart or stop your web server?
+There are some ways this can be done.
+
+We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+An alternative to endless:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) example with gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "syscall"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // service connections
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Wait for interrupt signal to gracefully shutdown the server with
+ // a timeout of 5 seconds.
+ quit := make(chan os.Signal, 1)
+ // kill (no param) default send syscanll.SIGTERM
+ // kill -2 is syscall.SIGINT
+ // kill -9 is syscall. SIGKILL but can"t be catch, so don't need add it
+ signal.Notify(quit, syscall.SIGINT, syscall.SIGTERM)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ // catching ctx.Done(). timeout of 5 seconds.
+ select {
+ case <-ctx.Done():
+ log.Println("timeout of 5 seconds.")
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/grouping-routes.md b/src/content/docs/tr/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..c7f7a7245
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Grouping routes"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Simple group: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Simple group: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/html-rendering.md b/src/content/docs/tr/docs/examples/html-rendering.md
new file mode 100644
index 000000000..787248795
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML rendering"
+
+---
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Using templates with same name in different directories
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+### Custom Template renderer
+
+You can also use your own html template render
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+### Custom Delimiters
+
+You may use custom delims
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+### Custom Template Funcs
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/tr/docs/examples/http-method.md b/src/content/docs/tr/docs/examples/http-method.md
new file mode 100644
index 000000000..b8d41d696
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/http-method.md
@@ -0,0 +1,25 @@
+---
+title: "Using HTTP method"
+
+---
+
+```go
+func main() {
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // By default it serves on :8080 unless a
+ // PORT environment variable was defined.
+ router.Run()
+ // router.Run(":3000") for a hard coded port
+}
+```
diff --git a/src/content/docs/tr/docs/examples/http2-server-push.md b/src/content/docs/tr/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..192d22a45
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+
+---
+
+http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // use pusher.Push() to do server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Listen and Server in https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/index.md b/src/content/docs/tr/docs/examples/index.md
new file mode 100644
index 000000000..f6a04601e
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "Örnekler"
+
+sidebar:
+ order: 6
+---
+
+Bu bölüm, api kullanımını listeler.
diff --git a/src/content/docs/tr/docs/examples/jsonp.md b/src/content/docs/tr/docs/examples/jsonp.md
new file mode 100644
index 000000000..bc4439a44
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback is x
+ // Will output : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/tr/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..5ed88b0b5
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Map as querystring or postform parameters"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/tr/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/tr/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..73fee286a
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded binding"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // you can bind multipart form with explicit binding declaration:
+ // c.ShouldBindWith(&form, binding.Form)
+ // or you can simply use autobinding with ShouldBind method:
+ var form LoginForm
+ // in this case proper binding will be automatically selected
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Test it with:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/tr/docs/examples/multipart-urlencoded-form.md b/src/content/docs/tr/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..04eab2373
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded form"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/multiple-template.md b/src/content/docs/tr/docs/examples/multiple-template.md
new file mode 100644
index 000000000..28b58c213
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Multitemplate"
+
+---
+
+Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/src/content/docs/tr/docs/examples/only-bind-query-string.md b/src/content/docs/tr/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..bdd6c174e
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Only bind query string"
+
+---
+
+`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/param-in-path.md b/src/content/docs/tr/docs/examples/param-in-path.md
new file mode 100644
index 000000000..b0a4a3b68
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Parameters in path"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // This handler will match /user/john but will not match /user/ or /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // However, this one will match /user/john/ and also /user/john/send
+ // If no other routers match /user/john, it will redirect to /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/pure-json.md b/src/content/docs/tr/docs/examples/pure-json.md
new file mode 100644
index 000000000..5fbf8bfc1
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/pure-json.md
@@ -0,0 +1,30 @@
+---
+title: "PureJSON"
+
+---
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/query-and-post-form.md b/src/content/docs/tr/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..5c8e6d21e
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Query and post form"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/tr/docs/examples/querystring-param.md b/src/content/docs/tr/docs/examples/querystring-param.md
new file mode 100644
index 000000000..cba891746
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Query string parameters"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Query string parameters are parsed using the existing underlying request object.
+ // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/redirects.md b/src/content/docs/tr/docs/examples/redirects.md
new file mode 100644
index 000000000..e62a9952e
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirects"
+
+---
+
+Issuing a HTTP redirect is easy. Both internal and external locations are supported.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Issuing a Router redirect, use `HandleContext` like below.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/tr/docs/examples/rendering.md b/src/content/docs/tr/docs/examples/rendering.md
new file mode 100644
index 000000000..c9c705c65
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf rendering"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H is a shortcut for map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // You also can use a struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Note that msg.Name becomes "user" in the JSON
+ // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/run-multiple-service.md b/src/content/docs/tr/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..0dba2ab95
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Run multiple service"
+
+---
+
+See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "message": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/secure-json.md b/src/content/docs/tr/docs/examples/secure-json.md
new file mode 100644
index 000000000..82e63a4c4
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // You can also use your own secure json prefix
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Will output : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/security-headers.md b/src/content/docs/tr/docs/examples/security-headers.md
new file mode 100644
index 000000000..aa767aa02
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "Güvenlik Üst Bilgileri"
+
+---
+
+Web uygulamanızı yaygın güvenlik açıklarından korumak için güvenlik başlıklarını kullanmak önemlidir. Bu örnek, Gin uygulamanıza güvenlik başlıklarını nasıl ekleyeceğinizi ve ayrıca Host Header Injection ile ilgili saldırılardan (SSRF, Open Redirection) nasıl kaçınacağınızı gösterir.
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+You can test it via `curl`:
+
+```bash
+// Başlıkları Kontrol Edin
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// Ana Bilgisayar Başlık Enjeksiyonunu Kontrol Et
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/tr/docs/examples/serving-data-from-reader.md b/src/content/docs/tr/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..614db12ce
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Serving data from reader"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/serving-static-files.md b/src/content/docs/tr/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..bda67da07
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Serving static files"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/support-lets-encrypt.md b/src/content/docs/tr/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..841c1a7f9
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Support Let's Encrypt"
+
+---
+
+example for 1-line LetsEncrypt HTTPS servers.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+example for custom autocert manager.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/upload-file/index.md b/src/content/docs/tr/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..d0ff99e85
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Upload files"
+
+---
+
+The section lists upload file api usage.
diff --git a/src/content/docs/tr/docs/examples/upload-file/multiple-file.md b/src/content/docs/tr/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..185b7b5f6
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Multiple files"
+
+---
+
+See the detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/tr/docs/examples/upload-file/single-file.md b/src/content/docs/tr/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..5fe274dc7
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/upload-file/single-file.md
@@ -0,0 +1,37 @@
+---
+title: "Single file"
+
+---
+
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+`file.Filename` **SHOULD NOT** be trusted. See [`Content-Disposition` on MDN](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Disposition#Directives) and [#1693](https://github.com/gin-gonic/gin/issues/1693)
+
+> The filename is always optional and must not be used blindly by the application: path information should be stripped, and conversion to the server file system rules should be done.
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // single file
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/tr/docs/examples/using-basicauth-middleware.md b/src/content/docs/tr/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..cc68db4a0
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Using BasicAuth middleware"
+
+---
+
+```go
+// simulate some private data
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Group using gin.BasicAuth() middleware
+ // gin.Accounts is a shortcut for map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets endpoint
+ // hit "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // get user, it was set by the BasicAuth middleware
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/examples/using-middleware.md b/src/content/docs/tr/docs/examples/using-middleware.md
new file mode 100644
index 000000000..5fc4154db
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Using middleware"
+
+---
+
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.Recovery())
+
+ // Per route middleware, you can add as many as you desire.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Authorization group
+ // authorized := r.Group("/", AuthRequired())
+ // exactly the same as:
+ authorized := r.Group("/")
+ // per group middleware! in this case we use the custom created
+ // AuthRequired() middleware just in the "authorized" group.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // nested group
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/tr/docs/examples/without-middleware.md b/src/content/docs/tr/docs/examples/without-middleware.md
new file mode 100644
index 000000000..6ef54bda0
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Without middleware by default"
+
+---
+
+Use
+
+```go
+r := gin.New()
+```
+
+instead of
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
diff --git a/src/content/docs/tr/docs/examples/write-log.md b/src/content/docs/tr/docs/examples/write-log.md
new file mode 100644
index 000000000..759423de4
--- /dev/null
+++ b/src/content/docs/tr/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "How to write log file"
+
+---
+
+```go
+func main() {
+ // Disable Console Color, you don't need console color when writing the logs to file.
+ gin.DisableConsoleColor()
+
+ // Logging to a file.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Use the following code if you need to write the logs to file and console at the same time.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/tr/docs/faq/index.md b/src/content/docs/tr/docs/faq/index.md
new file mode 100644
index 000000000..ad348f11f
--- /dev/null
+++ b/src/content/docs/tr/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: record some frequently asked question from GitHub Issue tab.
+
diff --git a/src/content/docs/tr/docs/features/index.md b/src/content/docs/tr/docs/features/index.md
new file mode 100644
index 000000000..86a795f2b
--- /dev/null
+++ b/src/content/docs/tr/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "Özellikler"
+
+sidebar:
+ order: 4
+---
+
+## Gin v1 sabit özellikler:
+
+- Sıfır allocation router.
+
+- Routingden http isteklerini yanıtlamaya kadar hala en hızlı http router ve framework.
+
+- Eksiksiz unit testleri paketi.
+
+- Güçlü bir biçimde test edilmiş.
+
+- API donsa dahi, yeni sürümler kodunuzu bozmaz ve çalışmaya devam eder.
diff --git a/src/content/docs/tr/docs/index.md b/src/content/docs/tr/docs/index.md
new file mode 100644
index 000000000..b851e012f
--- /dev/null
+++ b/src/content/docs/tr/docs/index.md
@@ -0,0 +1,22 @@
+---
+title: "Dokümantasyon"
+linkTitle: "Dokümantasyon"
+sidebar:
+ order: 1
+---
+
+## Gin nedir?
+
+Gin, Go (Golang) ile yazılmış bir HTTP web çerçevesidir. Martini benzeri bir API'ye sahiptir, ancak performans açısından Martini'den 40 kata kadar daha hızlıdır. Çarpıcı bir performansa ihtiyacınız varsa, kendinize biraz Gin alın.
+
+## Gin'i nasıl kullanmalı?
+
+API kullanım [örnekleri](https://github.com/gin-gonic/examples) sunuyoruz ve bilinen bazı [Gin kullanıcılarını](./users) listeliyoruz.
+
+## Gin'e nasıl katkıda bulunmalı?
+
+* Tartışma forumlarında insanlara yardım edin
+* Gin kullanarak bize başarı hikayelerinizi anlatın
+* Bize Gin'i nasıl iyileştirebileceğimizi söyleyin ve bunu yapmamıza yardımcı olun
+* Mevcut bir kütüphaneye katkıda bulunun
+
diff --git a/src/content/docs/tr/docs/introduction/index.md b/src/content/docs/tr/docs/introduction/index.md
new file mode 100644
index 000000000..4d21ea37a
--- /dev/null
+++ b/src/content/docs/tr/docs/introduction/index.md
@@ -0,0 +1,48 @@
+---
+title: "Giriş"
+
+sidebar:
+ order: 1
+---
+
+Gin, Go (Golang) ile yazılmış bir web çerçevesidir. Martini benzeri bir API'ye sahiptir ama [httprouter](https://github.com/julienschmidt/httprouter) sayesinde 40 kata kadar daha hızlı, çok daha iyi performansa sahiptir. Performansa ve iyi üretkenliğe ihtiyacınız varsa, Gin'i seveceksiniz.
+
+Bu bölümde Gin'in ne olduğunu, hangi sorunları çözdüğünü ve projenize nasıl yardımcı olabileceğini inceleyeceğiz.
+
+Veya projenizde Gin'i kullanmaya hazırsanız [Hızlı Başlangıç](https://gin-gonic.com/tr/docs/quickstart/)'ı ziyaret edin.
+
+## Özellikler
+
+### Hızlı
+
+Radix ağacı tabanlı routing, küçük bellek ayak izi. Reflection yok. Öngörülebilir API performansı.
+
+### Middleware desteği
+
+Gelen bir HTTP isteği, bir middleware zinciri ve son eylem tarafından işlenebilir. Örneğin: Logger, Authorization, GZIP ve son olarak veritabanına bir mesaj gönderin.
+
+### Çökmeye Dirençli
+
+Gin, bir HTTP isteği sırasında oluşan bir paniği yakalayabilir ve düzeltebilir. Bu şekilde sunucunuz her zaman çalışacaktır. Ayrıca bir paniği Sentry'ye bildirmek de mümkündür.
+
+### JSON doğrulama
+
+Gin, bir isteğin JSON'ını ayrıştırabilir ve doğrulayabilir. Örneğin gerekli değerlerin varlığını kontrol edebilir.
+
+### Route gruplama
+
+Routelarınızı daha iyi düzenleyin. Authorization gerektiren veya gerektirmeyen, farklı API sürümlerini kolayca düzenleyin. Ayrıca, gruplar performansı düşürmeden sınırsız olarak iç içe yerleştirilebilir.
+
+### Hata yönetimi
+
+Gin, bir HTTP isteği sırasında meydana gelen tüm hataları toplamak için uygun bir yol sağlar. Sonunda, middleware bunları bir log dosyasına veya bir veritabanına yazabilir ve ağ üzerinden gönderebilir.
+
+
+### Hazır rendering
+
+Gin, JSON, XML ve HTML işleme için kullanımı kolay bir API sağlar.
+
+### Genişletilebilir
+
+Yeni middleware oluşturmak çok kolaydır, sadece örnek kodları inceleyin.
+
diff --git a/src/content/docs/tr/docs/jsoniter/index.md b/src/content/docs/tr/docs/jsoniter/index.md
new file mode 100644
index 000000000..75a568536
--- /dev/null
+++ b/src/content/docs/tr/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+## [jsoniter](https://github.com/json-iterator/go) ile oluşturun
+
+Gin, varsayılan json paketi olarak `encoding/json` kullanır, ancak diğer etiketlerden derleyerek varsayılanı [jsoniter](https://github.com/json-iterator/go) olarak değiştirebilirsiniz.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/tr/docs/quickstart/index.md b/src/content/docs/tr/docs/quickstart/index.md
new file mode 100644
index 000000000..ffa471f19
--- /dev/null
+++ b/src/content/docs/tr/docs/quickstart/index.md
@@ -0,0 +1,87 @@
+---
+title: "Hızlı Başlangıç"
+
+sidebar:
+ order: 2
+---
+
+Bu hızlı başlangıçta, kod parçacıklarından içgörüler toplayacağız ve aşağıda belirtilen adımları nasıl yapacağımızı öğreneceğiz:
+
+## Gereksinimler
+
+- Go 1.16 veya üzeri
+
+## Kurulum
+
+Gin paketini kurmak için önce Go'yu kurmanız ve Go çalışma alanınızı ayarlamanız gerekir.
+
+1. İndirin ve kurun:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. Kodunuzda import edin:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (İsteğe bağlı) `net/http` paketini import edin. Bu, `http.StatusOK` gibi statü belirten ifadeler kullanılıyorsa gereklidir.
+
+```go
+import "net/http"
+```
+
+1. Proje klasörünüzü oluşturun ve `cd` komutu ile içine girin
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. Projenizin içine bir başlangıç şablonu kopyalayın
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. Projenizi çalıştırın
+
+```sh
+$ go run main.go
+```
+
+## Başlarken
+> Go kodunu nasıl yazıp çalıştıracağınızdan emin değil misiniz? [Buraya tıklayın](https://golang.org/doc/code.html).
+
+İlk olarak, `example.go` adlı bir dosya oluşturun
+
+```sh
+# aşağıdaki kodları example.go dosyasında varsayalım
+$ touch example.go
+```
+
+Ardından, aşağıdaki kodu `example.go` dosyasının içine yerleştirin
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // 0.0.0.0:8080 adresini dinleyin ve servis edin
+}
+```
+
+Ve, kodu şu şekilde çalıştırabilirsiniz : `go run example.go`:
+
+```sh
+# example.go dosyasını çalıştırın ve tarayıcıda 0.0.0.0:8080/ping adresini ziyaret edin
+$ go run example.go
+```
diff --git a/src/content/docs/tr/docs/testing/index.md b/src/content/docs/tr/docs/testing/index.md
new file mode 100644
index 000000000..64893560a
--- /dev/null
+++ b/src/content/docs/tr/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "Test"
+
+sidebar:
+ order: 7
+---
+
+## Gin için nasıl test yazılır?
+
+`net/http/httptest` HTTP testi için tercih edilen pakettir.
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+Yukarıdaki kod örneği için test:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/tr/docs/users/index.md b/src/content/docs/tr/docs/users/index.md
new file mode 100644
index 000000000..e11409c54
--- /dev/null
+++ b/src/content/docs/tr/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "Kullanıcılar"
+
+sidebar:
+ order: 8
+---
+
+##### [Gin](https://github.com/gin-gonic/gin) web çerçevesini kullanan harika proje listeleri:
+
+* [gorush](https://github.com/appleboy/gorush): Go'da yazılmış bir anında iletme bildirim sunucusu.
+
+* [fnproject](https://github.com/fnproject/fn): Container native, buluttan bağımsız sunucusuz platform.
+
+* [photoprism](https://github.com/photoprism/photoprism): Go ve Google TensorFlow tarafından desteklenen kişisel fotoğraf yönetimi.
+
+* [krakend](https://github.com/devopsfaith/krakend): Middlewarelere sahip ultra performanslı API Gateway'i.
+
+* [picfit](https://github.com/thoas/picfit): Go'da yazılmış bir görüntü yeniden boyutlandırma sunucusu.
+
+* [gotify](https://github.com/gotify/server): Web soketi başına gerçek zamanlı olarak mesaj göndermek ve almak için basit bir sunucu.
+
+* [cds](https://github.com/ovh/cds): Kurumsal Düzeyde Continuous Delivery ve DevOps Otomasyonu Açık Kaynak Platformu.
diff --git a/src/content/docs/tr/index.mdx b/src/content/docs/tr/index.mdx
new file mode 100644
index 000000000..145e0882c
--- /dev/null
+++ b/src/content/docs/tr/index.mdx
@@ -0,0 +1,50 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Go ile yazılmış, en hızlı, tam teşekküllü ve kristal berraklığında bir web çerçevesi.
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: Daha Fazla Öğren
+ link: /tr/docs/
+ icon: right-arrow
+ - text: İndir
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## Gin nedir??
+
+Gin, Golang'da yazılmış bir web çerçevesidir. Martini benzeri bir API'ye sahiptir, ancak performans açısından Martini'den 40 kata kadar daha hızlıdır. Performans ve üretkenliğe ihtiyacınız varsa Gin'i seveceksiniz.
+
+
+
+ Radix ağacı tabanlı routing, küçük bellek ayak izi. Reflection yok. Öngörülebilir API performansı.
+
+
+ Gelen bir HTTP isteği, bir middleware zinciri ve son eylem tarafından işlenebilir. Örneğin: Logger, Authorization, GZIP ve son olarak veritabanına bir mesaj gönderin.
+
+
+ Gin, bir HTTP isteği sırasında oluşan bir paniği yakalayabilir ve düzeltebilir. Bu şekilde sunucunuz her zaman çalışacaktır. Ayrıca bir paniği Sentry'ye bildirmek de mümkündür.
+
+
+ Gin, bir isteğin JSON'ını ayrıştırabilir ve doğrulayabilir. Örneğin gerekli değerlerin varlığını kontrol edebilir.
+
+
+ Routelarınızı daha iyi düzenleyin. Authorization gerektiren veya gerektirmeyen, farklı API sürümlerini kolayca düzenleyin. Ayrıca, gruplar performansı düşürmeden sınırsız olarak iç içe yerleştirilebilir.
+
+
+ Gin, bir HTTP isteği sırasında meydana gelen tüm hataları toplamak için uygun bir yol sağlar. Sonunda, middleware bunları bir log dosyasına veya bir veritabanına yazabilir ve ağ üzerinden gönderebilir.
+
+
+ Gin, JSON, XML ve HTML işleme için kullanımı kolay bir API sağlar.
+
+
+ Yeni middleware oluşturmak çok kolaydır, sadece örnek kodları inceleyin.
+
+
\ No newline at end of file
diff --git a/src/content/docs/zh-cn/blog/index.md b/src/content/docs/zh-cn/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/zh-cn/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/zh-cn/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/zh-cn/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/zh-cn/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/zh-cn/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/zh-cn/blog/releases/release13.md b/src/content/docs/zh-cn/blog/releases/release13.md
similarity index 100%
rename from content/zh-cn/blog/releases/release13.md
rename to src/content/docs/zh-cn/blog/releases/release13.md
diff --git a/content/zh-cn/blog/releases/release14.md b/src/content/docs/zh-cn/blog/releases/release14.md
similarity index 100%
rename from content/zh-cn/blog/releases/release14.md
rename to src/content/docs/zh-cn/blog/releases/release14.md
diff --git a/content/zh-cn/blog/releases/release15.md b/src/content/docs/zh-cn/blog/releases/release15.md
similarity index 100%
rename from content/zh-cn/blog/releases/release15.md
rename to src/content/docs/zh-cn/blog/releases/release15.md
diff --git a/src/content/docs/zh-cn/docs/benchmarks/index.md b/src/content/docs/zh-cn/docs/benchmarks/index.md
new file mode 100644
index 000000000..70e53bc8c
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "基准测试"
+
+sidebar:
+ order: 3
+---
+
+Gin 使用了自定义版本的 [HttpRouter](https://github.com/julienschmidt/httprouter)
+
+[查看所有基准测试](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1):在一定的时间内实现的总调用数,越高越好
+- (2):单次操作耗时(ns/op),越低越好
+- (3):堆内存分配 (B/op), 越低越好
+- (4):每次操作的平均内存分配次数(allocs/op),越低越好
diff --git a/src/content/docs/zh-cn/docs/deployment/index.md b/src/content/docs/zh-cn/docs/deployment/index.md
new file mode 100644
index 000000000..896eed491
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/deployment/index.md
@@ -0,0 +1,20 @@
+---
+title: "部署"
+
+sidebar:
+ order: 6
+---
+
+Gin 项目可以轻松部署在任何云提供商上。
+
+## [Render](https://render.com)
+
+Render 是一个原生支持 Go 的现代化云平台,并支持全托管 SSL、数据库、不停机部署、HTTP/2 和 websocket。
+
+参考 Render [Gin 项目部署指南](https://render.com/docs/deploy-go-gin)。
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE 提供了两种方式部署 Go 应用。标准环境,简单易用但可定制性较低,且出于安全考虑禁止 [syscalls](https://github.com/gin-gonic/gin/issues/1639)。灵活环境,可以运行任何框架和库。
+
+前往 [Go on Google App Engine](https://cloud.google.com/appengine/docs/go/) 了解更多并选择你喜欢的环境。
diff --git a/src/content/docs/zh-cn/docs/examples/ascii-json.md b/src/content/docs/zh-cn/docs/examples/ascii-json.md
new file mode 100644
index 000000000..5694fb12d
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+使用 AsciiJSON 生成具有转义的非 ASCII 字符的 ASCII-only JSON。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // 输出 : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..1375acca2
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,56 @@
+---
+title: "将 request body 绑定到不同的结构体中"
+
+---
+
+一般通过调用 `c.Request.Body` 方法绑定数据,但不能多次调用这个方法。
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // c.ShouldBind 使用了 c.Request.Body,不可重用。
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // 因为现在 c.Request.Body 是 EOF,所以这里会报错。
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+要想多次绑定,可以使用 `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // 读取 c.Request.Body 并将结果存入上下文。
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // 这时, 复用存储在上下文中的 body。
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // 可以接受其他格式
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` 会在绑定之前将 body 存储到上下文中。 这会对性能造成轻微影响,如果调用一次就能完成绑定的话,那就不要用这个方法。
+* 只有某些格式需要此功能,如 `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`。 对于其他格式, 如 `Query`, `Form`, `FormPost`, `FormMultipart`
+可以多次调用 `c.ShouldBind()` 而不会造成任任何性能损失 (详见 [#1341](https://github.com/gin-gonic/gin/pull/1341))。
diff --git a/src/content/docs/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..872f6e3ca
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,95 @@
+---
+title: "绑定表单数据至自定义结构体"
+
+---
+
+以下示例使用自定义结构体:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+使用 `curl` 命令结果:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
+**注意**:不支持以下格式结构体:
+
+```go
+type StructX struct {
+ X struct {} `form:"name_x"` // 有 form
+}
+
+type StructY struct {
+ Y StructX `form:"name_y"` // 有 form
+}
+
+type StructZ struct {
+ Z *StructZ `form:"name_z"` // 有 form
+}
+```
+
+总之, 目前仅支持没有 form 的嵌套结构体。
+
diff --git a/src/content/docs/zh-cn/docs/examples/bind-html-checkbox.md b/src/content/docs/zh-cn/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..7507c4366
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "绑定 HTML 复选框"
+
+---
+
+参见[详细信息](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+结果:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/bind-query-or-post.md b/src/content/docs/zh-cn/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..3692e9834
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "绑定查询字符串或表单数据"
+
+---
+
+查看[详细信息](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292)。
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // 如果是 `GET` 请求,只使用 `Form` 绑定引擎(`query`)。
+ // 如果是 `POST` 请求,首先检查 `content-type` 是否为 `JSON` 或 `XML`,然后再使用 `Form`(`form-data`)。
+ // 查看更多:https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L88
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+测试:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/zh-cn/docs/examples/bind-single-binary-with-template.md b/src/content/docs/zh-cn/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..acbc1e514
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,44 @@
+---
+title: "静态资源嵌入"
+
+---
+
+你可以使用 [go-assets](https://github.com/jessevdk/go-assets) 将静态资源打包到可执行文件中。
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate 加载由 go-assets-builder 嵌入的模板
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+请参阅 [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) 目录中的完整示例。
diff --git a/src/content/docs/zh-cn/docs/examples/bind-uri.md b/src/content/docs/zh-cn/docs/examples/bind-uri.md
new file mode 100644
index 000000000..c22910673
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "绑定 Uri"
+
+---
+
+查看[详细信息](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err.Error()})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+测试:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/zh-cn/docs/examples/binding-and-validation.md b/src/content/docs/zh-cn/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..a4a0c1a8b
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/binding-and-validation.md
@@ -0,0 +1,119 @@
+---
+title: "模型绑定和验证"
+
+---
+
+要将请求体绑定到结构体中,使用模型绑定。 Gin目前支持JSON、XML、YAML和标准表单值的绑定(foo=bar&boo=baz)。
+
+Gin使用 [**go-playground/validator/v10**](https://github.com/go-playground/validator) 进行验证。 查看标签用法的全部[文档](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+使用时,需要在要绑定的所有字段上,设置相应的tag。 例如,使用 JSON 绑定时,设置字段标签为 `json:"fieldname"`。
+
+Gin提供了两类绑定方法:
+
+- **Type** - Must bind
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Behavior** - 这些方法属于 `MustBindWith` 的具体调用。 如果发生绑定错误,则请求终止,并触发 `c.AbortWithError(400, err).SetType(ErrorTypeBind)`。响应状态码被设置为 400 并且 `Content-Type` 被设置为 `text/plain; charset=utf-8`。 如果您在此之后尝试设置响应状态码,Gin会输出日志 `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`。 如果您希望更好地控制绑定,考虑使用 `ShouldBind` 等效方法。
+- **Type** - Should bind
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Behavior** - 这些方法属于 `ShouldBindWith` 的具体调用。 如果发生绑定错误,Gin 会返回错误并由开发者处理错误和请求。
+
+使用 Bind 方法时,Gin 会尝试根据 Content-Type 推断如何绑定。 如果你明确知道要绑定什么,可以使用 `MustBindWith` 或 `ShouldBindWith`。
+
+你也可以指定必须绑定的字段。 如果一个字段的 tag 加上了 `binding:"required"`,但绑定时是空值, Gin 会报错。
+
+```go
+// 绑定 JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // 绑定 JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // 绑定 XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // 绑定 HTML 表单 (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // 根据 Content-Type Header 推断使用哪个绑定器。
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ router.Run(":8080")
+}
+```
+
+#### 示例请求
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+#### 忽略验证
+
+使用上述的 `curl` 命令运行上面的示例时会返回错误。 因为示例中 `Password` 使用了 `binding:"required"`。 如果 `Password` 使用 `binding:"-"`, 再次运行上面的示例就不会返回错误。
diff --git a/src/content/docs/zh-cn/docs/examples/controlling-log-output-coloring.md b/src/content/docs/zh-cn/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..ce1edc126
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,45 @@
+---
+title: "控制日志输出颜色"
+
+---
+
+根据检测到的 TTY,控制台的日志输出默认是有颜色的。
+
+禁止日志颜色化:
+
+```go
+func main() {
+ // 禁止日志的颜色
+ gin.DisableConsoleColor()
+
+ // 用默认中间件创建一个 gin 路由:
+ // 日志和恢复(无崩溃)中间件
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+日志颜色化:
+
+```go
+func main() {
+ // 强制日志颜色化
+ gin.ForceConsoleColor()
+
+ // 用默认中间件创建一个 gin 路由:
+ // 日志和恢复(无崩溃)中间件
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/cookie.md b/src/content/docs/zh-cn/docs/examples/cookie.md
new file mode 100644
index 000000000..4a2b2b874
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "设置和获取 Cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/custom-http-config.md b/src/content/docs/zh-cn/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..1d43616d2
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "自定义 HTTP 配置"
+
+---
+
+直接使用 `http.ListenAndServe()`,如下所示:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+或
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/custom-log-format.md b/src/content/docs/zh-cn/docs/examples/custom-log-format.md
new file mode 100644
index 000000000..53b2a2269
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/custom-log-format.md
@@ -0,0 +1,38 @@
+---
+title: "自定义日志文件"
+
+---
+
+示例:
+
+```go
+func main() {
+ router := gin.New()
+ // LoggerWithFormatter 中间件会写入日志到 gin.DefaultWriter
+ // 默认 gin.DefaultWriter = os.Stdout
+ router.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
+ // 你的自定义格式
+ return fmt.Sprintf("%s - [%s] \"%s %s %s %d %s \"%s\" %s\"\n",
+ param.ClientIP,
+ param.TimeStamp.Format(time.RFC1123),
+ param.Method,
+ param.Path,
+ param.Request.Proto,
+ param.StatusCode,
+ param.Latency,
+ param.Request.UserAgent(),
+ param.ErrorMessage,
+ )
+ }))
+ router.Use(gin.Recovery())
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ router.Run(":8080")
+}
+```
+
+**输出**
+```
+::1 - [Fri, 07 Dec 2018 17:04:38 JST] "GET /ping HTTP/1.1 200 122.767µs "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36" "
+```
diff --git a/src/content/docs/zh-cn/docs/examples/custom-middleware.md b/src/content/docs/zh-cn/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..c16a2c7fb
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "自定义中间件"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // 设置 example 变量
+ c.Set("example", "12345")
+
+ // 请求前
+
+ c.Next()
+
+ // 请求后
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // 获取发送的 status
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // 打印:"12345"
+ log.Println(example)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/custom-validators.md b/src/content/docs/zh-cn/docs/examples/custom-validators.md
new file mode 100644
index 000000000..b16f8fa9d
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/custom-validators.md
@@ -0,0 +1,67 @@
+---
+title: "自定义验证器"
+
+---
+
+注册自定义验证器,查看[示例代码](https://github.com/gin-gonic/examples/tree/master/struct-lvl-validations).
+
+```go
+package main
+
+import (
+ "net/http"
+ "reflect"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking 包含绑定和验证的数据。
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+var bookableDate validator.Func = func(fl validator.FieldLevel) bool {
+ date, ok := fl.Field().Interface().(time.Time)
+ if ok {
+ today := time.Now()
+ if today.After(date) {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
+{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
+```
+
+[结构体级别的验证器](https://github.com/go-playground/validator/releases/tag/v8.7) 也可以通过其他的方式注册。更多信息请参阅 [struct-lvl-validation 示例](examples/struct-lvl-validations)。
diff --git a/src/content/docs/zh-cn/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/zh-cn/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..5a0ba67ea
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "定义路由日志的格式"
+
+---
+
+默认的路由日志格式:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+如果你想要以指定的格式(例如 JSON,key values 或其他格式)记录信息,则可以使用 `gin.DebugPrintRouteFunc` 指定格式。
+在下面的示例中,我们使用标准日志包记录所有路由,但你可以使用其他满足你需求的日志工具。
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run()
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/zh-cn/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..0a6eba2a5
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "在中间件中使用 Goroutine"
+
+---
+
+当在中间件或 handler 中启动新的 Goroutine 时,**不能**使用原始的上下文,必须使用只读副本。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // 创建在 goroutine 中使用的副本
+ cCp := c.Copy()
+ go func() {
+ // 用 time.Sleep() 模拟一个长任务。
+ time.Sleep(5 * time.Second)
+
+ // 请注意您使用的是复制的上下文 "cCp",这一点很重要
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // 用 time.Sleep() 模拟一个长任务。
+ time.Sleep(5 * time.Second)
+
+ // 因为没有使用 goroutine,不需要拷贝上下文
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/graceful-restart-or-stop.md b/src/content/docs/zh-cn/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..fb5ddb8ed
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,74 @@
+---
+title: "优雅地重启或停止"
+
+---
+
+你想优雅地重启或停止 web 服务器吗?有一些方法可以做到这一点。
+
+我们可以使用 [fvbock/endless](https://github.com/fvbock/endless) 来替换默认的 `ListenAndServe`。更多详细信息,请参阅 issue [#296](https://github.com/gin-gonic/gin/issues/296)。
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+替代方案:
+
+* [manners](https://github.com/braintree/manners):可以优雅关机的 Go Http 服务器。
+* [graceful](https://github.com/tylerb/graceful):Graceful 是一个 Go 扩展包,可以优雅地关闭 http.Handler 服务器。
+* [grace](https://github.com/facebookgo/grace):Go 服务器平滑重启和零停机时间部署。
+
+如果你使用的是 Go 1.8,可以不需要这些库!考虑使用 http.Server 内置的 [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) 方法优雅地关机. 请参阅 gin 完整的 [graceful-shutdown](https://github.com/gin-gonic/examples/tree/master/graceful-shutdown) 示例。
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // 服务连接
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // 等待中断信号以优雅地关闭服务器(设置 5 秒的超时时间)
+ quit := make(chan os.Signal, 1)
+ signal.Notify(quit, os.Interrupt)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/grouping-routes.md b/src/content/docs/zh-cn/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..d0b1d8600
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "路由组"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // 简单的路由组: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // 简单的路由组: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/html-rendering.md b/src/content/docs/zh-cn/docs/examples/html-rendering.md
new file mode 100644
index 000000000..875fa1efe
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML 渲染"
+
+---
+
+使用 LoadHTMLGlob() 或者 LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+使用不同目录下名称相同的模板
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+#### 自定义模板渲染器
+
+你可以使用自定义的 html 模板渲染
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+#### 自定义分隔符
+
+你可以使用自定义分隔
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+#### 自定义模板功能
+
+查看详细[示例代码](https://github.com/gin-gonic/examples/tree/master/template)。
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+结果:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/zh-cn/docs/examples/http-method.md b/src/content/docs/zh-cn/docs/examples/http-method.md
new file mode 100644
index 000000000..1960d38b4
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/http-method.md
@@ -0,0 +1,26 @@
+---
+title: "使用 HTTP 方法"
+
+---
+
+```go
+func main() {
+ // 禁用控制台颜色
+ // gin.DisableConsoleColor()
+
+ // 使用默认中间件(logger 和 recovery 中间件)创建 gin 路由
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // 默认在 8080 端口启动服务,除非定义了一个 PORT 的环境变量。
+ router.Run()
+ // router.Run(":3000") hardcode 端口号
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/http2-server-push.md b/src/content/docs/zh-cn/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..272211993
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server 推送"
+
+---
+
+http.Pusher 仅支持 **go1.8+**。 更多信息,请查阅 [golang blog](https://blog.golang.org/h2push)。
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // 使用 pusher.Push() 做服务器推送
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // 监听并在 https://127.0.0.1:8080 上启动服务
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/index.md b/src/content/docs/zh-cn/docs/examples/index.md
new file mode 100644
index 000000000..74b3c6615
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "示例"
+
+sidebar:
+ order: 6
+---
+
+该节列出了 api 的用法。
diff --git a/src/content/docs/zh-cn/docs/examples/jsonp.md b/src/content/docs/zh-cn/docs/examples/jsonp.md
new file mode 100644
index 000000000..2bd6ca098
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+使用 JSONP 向不同域的服务器请求数据。如果查询参数存在回调,则将回调添加到响应体中。
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ // /JSONP?callback=x
+ // 将输出:x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/zh-cn/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..39846852c
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "映射查询字符串或表单参数"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..d90bfb9c7
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded 绑定"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // 你可以使用显式绑定声明绑定 multipart form:
+ // c.ShouldBindWith(&form, binding.Form)
+ // 或者简单地使用 ShouldBind 方法自动绑定:
+ var form LoginForm
+ // 在这种情况下,将自动选择合适的绑定
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+测试:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-form.md b/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..fab25a289
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded 表单"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/multiple-template.md b/src/content/docs/zh-cn/docs/examples/multiple-template.md
new file mode 100644
index 000000000..0a5ca8721
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "多模板"
+
+---
+
+Gin 默认允许只使用一个 html 模板。 查看[多模板渲染](https://github.com/gin-contrib/multitemplate) 以使用 go 1.6 `block template` 等功能。
diff --git a/src/content/docs/zh-cn/docs/examples/only-bind-query-string.md b/src/content/docs/zh-cn/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..091811510
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "只绑定 url 查询字符串"
+
+---
+
+`ShouldBindQuery` 函数只绑定 url 查询参数而忽略 post 数据。参阅[详细信息](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/param-in-path.md b/src/content/docs/zh-cn/docs/examples/param-in-path.md
new file mode 100644
index 000000000..f1e1ebfd4
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "路由参数"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // 此 handler 将匹配 /user/john 但不会匹配 /user/ 或者 /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // 此 handler 将匹配 /user/john/ 和 /user/john/send
+ // 如果没有其他路由匹配 /user/john,它将重定向到 /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/pure-json.md b/src/content/docs/zh-cn/docs/examples/pure-json.md
new file mode 100644
index 000000000..edd1042d8
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/pure-json.md
@@ -0,0 +1,29 @@
+---
+title: "PureJSON"
+
+---
+
+通常,JSON 使用 unicode 替换特殊 HTML 字符,例如 < 变为 \ u003c。如果要按字面对这些字符进行编码,则可以使用 PureJSON。Go 1.6 及更低版本无法使用此功能。
+
+```go
+func main() {
+ r := gin.Default()
+
+ // 提供 unicode 实体
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // 提供字面字符
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/query-and-post-form.md b/src/content/docs/zh-cn/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..3262d599b
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Query 和 post form"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/zh-cn/docs/examples/querystring-param.md b/src/content/docs/zh-cn/docs/examples/querystring-param.md
new file mode 100644
index 000000000..d56d57ff6
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "查询字符串参数"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // 使用现有的基础请求对象解析查询字符串参数。
+ // 示例 URL: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // c.Request.URL.Query().Get("lastname") 的一种快捷方式
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/redirects.md b/src/content/docs/zh-cn/docs/examples/redirects.md
new file mode 100644
index 000000000..a675dfb50
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "重定向"
+
+---
+
+HTTP 重定向很容易。 内部、外部重定向均支持。
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+通过 POST 方法进行 HTTP 重定向。请参考 issue:[#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+路由重定向,使用 `HandleContext`:
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/zh-cn/docs/examples/rendering.md b/src/content/docs/zh-cn/docs/examples/rendering.md
new file mode 100644
index 000000000..f7d432cb6
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf 渲染"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H 是 map[string]interface{} 的一种快捷方式
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // 你也可以使用一个结构体
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // 注意 msg.Name 在 JSON 中变成了 "user"
+ // 将输出:{"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // protobuf 的具体定义写在 testdata/protoexample 文件中。
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // 请注意,数据在响应中变为二进制数据
+ // 将输出被 protoexample.Test protobuf 序列化了的数据
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/run-multiple-service.md b/src/content/docs/zh-cn/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..f36cd7bbc
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "运行多个服务"
+
+---
+
+请参阅 [issues](https://github.com/gin-gonic/gin/issues/346) 并尝试以下示例:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/secure-json.md b/src/content/docs/zh-cn/docs/examples/secure-json.md
new file mode 100644
index 000000000..bb3fb627d
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+使用 SecureJSON 防止 json 劫持。如果给定的结构是数组值,则默认预置 `"while(1),"` 到响应体。
+
+```go
+func main() {
+ r := gin.Default()
+
+ // 你也可以使用自己的 SecureJSON 前缀
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // 将输出:while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/security-headers.md b/src/content/docs/zh-cn/docs/examples/security-headers.md
new file mode 100644
index 000000000..7d5bebf39
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "安全页眉"
+
+---
+
+使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+您可以通过 `curl` 进行测试。
+
+```bash
+// 检查页眉
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// 检查主机标头注入
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/zh-cn/docs/examples/serving-data-from-reader.md b/src/content/docs/zh-cn/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..0687affbf
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "从 reader 读取数据"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/serving-static-files.md b/src/content/docs/zh-cn/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..d4144fe8d
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "静态文件服务"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/support-lets-encrypt.md b/src/content/docs/zh-cn/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..a23659754
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "支持 Let's Encrypt"
+
+---
+
+一行代码支持 LetsEncrypt HTTPS servers 示例。
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+自定义 autocert manager 示例。
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/upload-file/index.md b/src/content/docs/zh-cn/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..2891e15f3
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "上传文件"
+
+---
+
+本节列出了上传图片的 api 用法。
diff --git a/src/content/docs/zh-cn/docs/examples/upload-file/multiple-file.md b/src/content/docs/zh-cn/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..0c1662d2c
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,38 @@
+---
+title: "多文件"
+
+---
+
+查看详细[示例代码](https://github.com/gin-gonic/examples/tree/master/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // 上传文件至指定目录
+ dst := "./" + file.Filename
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+如何使用 `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/zh-cn/docs/examples/upload-file/single-file.md b/src/content/docs/zh-cn/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..c76477921
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/upload-file/single-file.md
@@ -0,0 +1,34 @@
+---
+title: "单文件"
+
+---
+
+参考 issue [#774](https://github.com/gin-gonic/gin/issues/774) 和详细[示例代码](https://github.com/gin-gonic/examples/tree/master/upload-file/single).
+
+```go
+func main() {
+ router := gin.Default()
+ // 为 multipart forms 设置较低的内存限制 (默认是 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // 单文件
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ dst := "./" + file.Filename
+ // 上传文件至指定的完整文件路径
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+如何使用 `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/zh-cn/docs/examples/using-basicauth-middleware.md b/src/content/docs/zh-cn/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..97d25144d
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "使用 BasicAuth 中间件"
+
+---
+
+```go
+// 模拟一些私人数据
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // 路由组使用 gin.BasicAuth() 中间件
+ // gin.Accounts 是 map[string]string 的一种快捷方式
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets 端点
+ // 触发 "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // 获取用户,它是由 BasicAuth 中间件设置的
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/examples/using-middleware.md b/src/content/docs/zh-cn/docs/examples/using-middleware.md
new file mode 100644
index 000000000..ae4043d4e
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "使用中间件"
+
+---
+
+```go
+func main() {
+ // 新建一个没有任何默认中间件的路由
+ r := gin.New()
+
+ // 全局中间件
+ // Logger 中间件将日志写入 gin.DefaultWriter,即使你将 GIN_MODE 设置为 release。
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery 中间件会 recover 任何 panic。如果有 panic 的话,会写入 500。
+ r.Use(gin.Recovery())
+
+ // 你可以为每个路由添加任意数量的中间件。
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // 认证路由组
+ // authorized := r.Group("/", AuthRequired())
+ // 和使用以下两行代码的效果完全一样:
+ authorized := r.Group("/")
+ // 路由组中间件! 在此例中,我们在 "authorized" 路由组中使用自定义创建的
+ // AuthRequired() 中间件
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // 嵌套路由组
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // 监听并在 0.0.0.0:8080 上启动服务
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-cn/docs/examples/without-middleware.md b/src/content/docs/zh-cn/docs/examples/without-middleware.md
new file mode 100644
index 000000000..792b7c135
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "不使用默认的中间件"
+
+---
+
+使用
+
+```go
+r := gin.New()
+```
+
+代替
+
+```go
+// Default 使用 Logger 和 Recovery 中间件
+r := gin.Default()
+```
diff --git a/src/content/docs/zh-cn/docs/examples/write-log.md b/src/content/docs/zh-cn/docs/examples/write-log.md
new file mode 100644
index 000000000..59a260269
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "如何记录日志"
+
+---
+
+```go
+func main() {
+ // 禁用控制台颜色,将日志写入文件时不需要控制台颜色。
+ gin.DisableConsoleColor()
+
+ // 记录到文件。
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // 如果需要同时将日志写入文件和控制台,请使用以下代码。
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-cn/docs/faq/index.md b/src/content/docs/zh-cn/docs/faq/index.md
new file mode 100644
index 000000000..feac4626c
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO:记录 GitHub Issue 中的一些常见问题。
+
diff --git a/src/content/docs/zh-cn/docs/features/index.md b/src/content/docs/zh-cn/docs/features/index.md
new file mode 100644
index 000000000..ddf4d7826
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "特性"
+
+sidebar:
+ order: 4
+---
+
+##### Gin v1 稳定的特性:
+
+- 零分配路由。
+
+- 仍然是最快的 http 路由器和框架。
+
+- 完整的单元测试支持。
+
+- 实战考验。
+
+- API 冻结,新版本的发布不会破坏你的代码。
diff --git a/src/content/docs/zh-cn/docs/index.md b/src/content/docs/zh-cn/docs/index.md
new file mode 100644
index 000000000..f80e90657
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/index.md
@@ -0,0 +1,22 @@
+---
+title: "文档"
+linkTitle: "文档"
+sidebar:
+ order: 1
+---
+
+## Gin 是什么?
+
+Gin 是一个用 Go (Golang) 编写的 HTTP Web 框架。 它具有类似 Martini 的 API,但性能比 Martini 快 40 倍。如果你需要极好的性能,使用 Gin 吧。
+
+## 如何使用 Gin?
+
+我们提供了一些 API 的使用[示例](https://gin-gonic.com/zh-cn/docs/examples/) 并罗列了一些众所周知的 [Gin 用户](./users).
+
+## 如何为 Gin 做贡献?
+
+* 在社区帮助其他人
+* 告诉我们你使用 Gin 的成功案例
+* 告诉我们如何改善 Gin 并帮助我们实现它
+* 为已有的库做贡献
+
diff --git a/src/content/docs/zh-cn/docs/introduction/index.md b/src/content/docs/zh-cn/docs/introduction/index.md
new file mode 100644
index 000000000..e8938ffcb
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/introduction/index.md
@@ -0,0 +1,46 @@
+---
+title: "介绍"
+
+sidebar:
+ order: 1
+---
+Gin 是一个用 Go (Golang) 编写的 Web 框架。 它具有类似 martini 的 API,性能要好得多,多亏了 [httprouter](https://github.com/julienschmidt/httprouter),速度提高了 40 倍。 如果您需要性能和良好的生产力,您一定会喜欢 Gin。
+
+在本节中,我们将介绍 Gin 是什么,它解决了哪些问题,以及它如何帮助你的项目。
+
+或者, 如果你已经准备在项目中使用 Gin,请访问[快速入门](https://gin-gonic.com/zh-cn/docs/quickstart/).
+
+## 特性
+
+### 快速
+
+基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
+
+### 支持中间件
+
+传入的 HTTP 请求可以由一系列中间件和最终操作来处理。
+例如:Logger,Authorization,GZIP,最终操作 DB。
+
+### Crash 处理
+
+Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!
+
+### JSON 验证
+
+Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
+
+### 路由组
+
+更好地组织路由。是否需要授权,不同的 API 版本...... 此外,这些组可以无限制地嵌套而不会降低性能。
+
+### 错误管理
+
+Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
+
+### 内置渲染
+
+Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
+
+### 可扩展性
+
+新建一个中间件非常简单,去查看[示例代码](https://gin-gonic.com/zh-cn/docs/examples/using-middleware/)吧。
diff --git a/src/content/docs/zh-cn/docs/jsoniter/index.md b/src/content/docs/zh-cn/docs/jsoniter/index.md
new file mode 100644
index 000000000..3d4e88d84
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+#### 使用 [jsoniter](https://github.com/json-iterator/go) 编译
+
+Gin 使用 `encoding/json` 作为默认的 json 包,但是你可以在编译中使用标签将其修改为 [jsoniter](https://github.com/json-iterator/go)。
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/zh-cn/docs/quickstart/index.md b/src/content/docs/zh-cn/docs/quickstart/index.md
new file mode 100644
index 000000000..ae770aff3
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/quickstart/index.md
@@ -0,0 +1,85 @@
+---
+title: "快速入门"
+
+sidebar:
+ order: 2
+---
+
+## 要求
+
+- Go 1.16 及以上版本
+
+## 安装
+
+要安装 Gin 软件包,需要先安装 Go 并设置 Go 工作区。
+
+1.下载并安装 gin:
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2.将 gin 引入到代码中:
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3.(可选)如果使用诸如 `http.StatusOK` 之类的常量,则需要引入 `net/http` 包:
+
+```go
+import "net/http"
+```
+
+1. 创建你的项目文件夹并 `cd` 进去
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+```
+
+2. 拷贝一个初始模板到你的项目里
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+3. 运行你的项目
+
+```sh
+$ go run main.go
+```
+
+## 开始
+
+> 不确定如何编写和执行 Go 代码? [点击这里](https://golang.org/doc/code.html).
+
+首先,创建一个名为 `example.go` 的文件
+
+```sh
+$ touch example.go
+```
+
+接下来, 将如下的代码写入 `example.go` 中:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // 监听并在 0.0.0.0:8080 上启动服务
+}
+```
+
+然后, 执行 `go run example.go` 命令来运行代码:
+
+```sh
+# 运行 example.go 并且在浏览器中访问 HOST_IP:8080/ping
+$ go run example.go
+```
diff --git a/src/content/docs/zh-cn/docs/testing/index.md b/src/content/docs/zh-cn/docs/testing/index.md
new file mode 100644
index 000000000..feff75e91
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/testing/index.md
@@ -0,0 +1,93 @@
+---
+title: "测试"
+
+sidebar:
+ order: 7
+---
+
+##### 怎样编写 Gin 的测试用例
+
+HTTP 测试首选 `net/http/httptest` 包。
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+上面这段代码的测试用例:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
+
+
+
diff --git a/src/content/docs/zh-cn/docs/users/index.md b/src/content/docs/zh-cn/docs/users/index.md
new file mode 100644
index 000000000..4269424ec
--- /dev/null
+++ b/src/content/docs/zh-cn/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "用户"
+
+sidebar:
+ order: 8
+---
+
+##### 使用 [Gin](https://github.com/gin-gonic/gin) web 框架的知名项目:
+
+* [gorush](https://github.com/appleboy/gorush):Go 编写的通知推送服务器。
+
+* [fnproject](https://github.com/fnproject/fn):原生容器,云 serverless 平台。
+
+* [photoprism](https://github.com/photoprism/photoprism):由 Go 和 Google TensorFlow 提供支持的个人照片管理工具。
+
+* [krakend](https://github.com/devopsfaith/krakend):拥有中间件的超高性能 API 网关。
+
+* [picfit](https://github.com/thoas/picfit):Go 编写的图像尺寸调整服务器。
+
+* [gotify](https://github.com/gotify/server):使用实时 web socket 做消息收发的简单服务器。
+
+* [cds](https://github.com/ovh/cds):企业级持续交付和 DevOps 自动化开源平台。
diff --git a/src/content/docs/zh-cn/index.mdx b/src/content/docs/zh-cn/index.mdx
new file mode 100644
index 000000000..bde3f0a3c
--- /dev/null
+++ b/src/content/docs/zh-cn/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Go语言最快的全功能Web框架。晶莹剔透。
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: 了解更多
+ link: /zh-cn/docs/
+ icon: right-arrow
+ - text: 下载
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## 什么是Gin?
+
+Gin是一个使用Go语言开发的Web框架。 它提供类似Martini的API,但性能更佳,速度提升高达40倍。 如果你是性能和高效的追求者, 你会爱上 Gin。
+
+
+
+ 基于 Radix 树的路由,小内存占用。没有反射。可预测的 API 性能。
+
+
+ 传入的 HTTP 请求可以由一系列中间件和最终操作来处理。例如:Logger,Authorization,GZIP,最终操作 DB。
+
+
+ Gin 可以 catch 一个发生在 HTTP 请求中的 panic 并 recover 它。这样,你的服务器将始终可用。例如,你可以向 Sentry 报告这个 panic!
+
+
+ Gin 可以解析并验证请求的 JSON,例如检查所需值的存在。
+
+
+ Gin帮助您更好地组织您的路由,例如,按照需要授权和不需要授权和不同API版本进行分组。此外,路由分组可以无限嵌套而不降低性能。
+
+
+ Gin 提供了一种方便的方法来收集 HTTP 请求期间发生的所有错误。最终,中间件可以将它们写入日志文件,数据库并通过网络发送。
+
+
+ Gin 为 JSON,XML 和 HTML 渲染提供了易于使用的 API。
+
+
+ 新建一个中间件非常简单,去查看[示例代码](https://gin-gonic.com/zh-cn/docs/examples/using-middleware/)吧。
+
+
+
\ No newline at end of file
diff --git a/src/content/docs/zh-tw/blog/index.md b/src/content/docs/zh-tw/blog/index.md
new file mode 100644
index 000000000..07fd81571
--- /dev/null
+++ b/src/content/docs/zh-tw/blog/index.md
@@ -0,0 +1,12 @@
+---
+title: "Blog"
+linkTitle: "Blog"
+sidebar:
+ order: 30
+---
+
+
+This is the **blog** section. It has two categories: News and Releases.
+
+Files in these directories will be listed in reverse chronological order.
+
diff --git a/content/zh-tw/blog/news/how-to-build-one-effective-middleware.md b/src/content/docs/zh-tw/blog/news/how-to-build-one-effective-middleware.md
similarity index 100%
rename from content/zh-tw/blog/news/how-to-build-one-effective-middleware.md
rename to src/content/docs/zh-tw/blog/news/how-to-build-one-effective-middleware.md
diff --git a/content/zh-tw/blog/releases/release13.md b/src/content/docs/zh-tw/blog/releases/release13.md
similarity index 100%
rename from content/zh-tw/blog/releases/release13.md
rename to src/content/docs/zh-tw/blog/releases/release13.md
diff --git a/content/zh-tw/blog/releases/release14.md b/src/content/docs/zh-tw/blog/releases/release14.md
similarity index 100%
rename from content/zh-tw/blog/releases/release14.md
rename to src/content/docs/zh-tw/blog/releases/release14.md
diff --git a/content/zh-tw/blog/releases/release15.md b/src/content/docs/zh-tw/blog/releases/release15.md
similarity index 100%
rename from content/zh-tw/blog/releases/release15.md
rename to src/content/docs/zh-tw/blog/releases/release15.md
diff --git a/src/content/docs/zh-tw/docs/benchmarks/index.md b/src/content/docs/zh-tw/docs/benchmarks/index.md
new file mode 100644
index 000000000..1cbdba620
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/benchmarks/index.md
@@ -0,0 +1,48 @@
+---
+title: "效能評估"
+
+sidebar:
+ order: 3
+---
+
+Gin 使用自訂版本的 [HttpRouter](https://github.com/julienschmidt/httprouter)
+
+[查看所有效能評估](https://github.com/gin-gonic/gin/blob/master/BENCHMARKS.md)
+
+| Benchmark name | (1) | (2) | (3) | (4) |
+| ------------------------------ | ---------:| ---------------:| ------------:| ---------------:|
+| BenchmarkGin_GithubAll | **43550** | **27364 ns/op** | **0 B/op** | **0 allocs/op** |
+| BenchmarkAce_GithubAll | 40543 | 29670 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkAero_GithubAll | 57632 | 20648 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkBear_GithubAll | 9234 | 216179 ns/op | 86448 B/op | 943 allocs/op |
+| BenchmarkBeego_GithubAll | 7407 | 243496 ns/op | 71456 B/op | 609 allocs/op |
+| BenchmarkBone_GithubAll | 420 | 2922835 ns/op | 720160 B/op | 8620 allocs/op |
+| BenchmarkChi_GithubAll | 7620 | 238331 ns/op | 87696 B/op | 609 allocs/op |
+| BenchmarkDenco_GithubAll | 18355 | 64494 ns/op | 20224 B/op | 167 allocs/op |
+| BenchmarkEcho_GithubAll | 31251 | 38479 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkGocraftWeb_GithubAll | 4117 | 300062 ns/op | 131656 B/op | 1686 allocs/op |
+| BenchmarkGoji_GithubAll | 3274 | 416158 ns/op | 56112 B/op | 334 allocs/op |
+| BenchmarkGojiv2_GithubAll | 1402 | 870518 ns/op | 352720 B/op | 4321 allocs/op |
+| BenchmarkGoJsonRest_GithubAll | 2976 | 401507 ns/op | 134371 B/op | 2737 allocs/op |
+| BenchmarkGoRestful_GithubAll | 410 | 2913158 ns/op | 910144 B/op | 2938 allocs/op |
+| BenchmarkGorillaMux_GithubAll | 346 | 3384987 ns/op | 251650 B/op | 1994 allocs/op |
+| BenchmarkGowwwRouter_GithubAll | 10000 | 143025 ns/op | 72144 B/op | 501 allocs/op |
+| BenchmarkHttpRouter_GithubAll | 55938 | 21360 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkHttpTreeMux_GithubAll | 10000 | 153944 ns/op | 65856 B/op | 671 allocs/op |
+| BenchmarkKocha_GithubAll | 10000 | 106315 ns/op | 23304 B/op | 843 allocs/op |
+| BenchmarkLARS_GithubAll | 47779 | 25084 ns/op | 0 B/op | 0 allocs/op |
+| BenchmarkMacaron_GithubAll | 3266 | 371907 ns/op | 149409 B/op | 1624 allocs/op |
+| BenchmarkMartini_GithubAll | 331 | 3444706 ns/op | 226551 B/op | 2325 allocs/op |
+| BenchmarkPat_GithubAll | 273 | 4381818 ns/op | 1483152 B/op | 26963 allocs/op |
+| BenchmarkPossum_GithubAll | 10000 | 164367 ns/op | 84448 B/op | 609 allocs/op |
+| BenchmarkR2router_GithubAll | 10000 | 160220 ns/op | 77328 B/op | 979 allocs/op |
+| BenchmarkRivet_GithubAll | 14625 | 82453 ns/op | 16272 B/op | 167 allocs/op |
+| BenchmarkTango_GithubAll | 6255 | 279611 ns/op | 63826 B/op | 1618 allocs/op |
+| BenchmarkTigerTonic_GithubAll | 2008 | 687874 ns/op | 193856 B/op | 4474 allocs/op |
+| BenchmarkTraffic_GithubAll | 355 | 3478508 ns/op | 820744 B/op | 14114 allocs/op |
+| BenchmarkVulcan_GithubAll | 6885 | 193333 ns/op | 19894 B/op | 609 allocs/op |
+
+- (1)在固定時間內達到的重複執行次數,數值越高代表對結果越有信心
+- (2)單次執行所需時間(ns/op),數值越低越好
+- (3)使用的 Heap 記憶體(B/op),數值越低越好
+- (4)每次執行的平均配置次數(allocs/op),數值越低越好
diff --git a/src/content/docs/zh-tw/docs/deployment/index.md b/src/content/docs/zh-tw/docs/deployment/index.md
new file mode 100644
index 000000000..e9dc87004
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/deployment/index.md
@@ -0,0 +1,20 @@
+---
+title: "部署"
+
+sidebar:
+ order: 6
+---
+
+Gin 專案可以輕鬆部署到任意雲主機商。
+
+## [Render](https://render.com)
+
+Render 是一個原生支援 Go 語言的現代化雲平台,並支持管理 SSL、資料庫、不停機部署、HTTP/2 和 websocket。
+
+請參考 Render 文件[部署 Gin 專案](https://render.com/docs/deploy-go-gin).
+
+## [Google App Engine](https://cloud.google.com/appengine/)
+
+GAE 提供兩種方式部署 Go 應用。標準環境簡單使用但是比較客製化,且出於安全考量禁止使用 [syscalls](https://github.com/gin-gonic/gin/issues/1639)。在靈活的還輕可以運行任何框架跟套件。
+
+前往 [Google App Engine](https://cloud.google.com/appengine/docs/go/) 了解更多並選擇您喜歡的環境。
diff --git a/src/content/docs/zh-tw/docs/examples/ascii-json.md b/src/content/docs/zh-tw/docs/examples/ascii-json.md
new file mode 100644
index 000000000..7e2d2b0d0
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/ascii-json.md
@@ -0,0 +1,25 @@
+---
+title: "AsciiJSON"
+
+---
+
+Using AsciiJSON to Generates ASCII-only JSON with escaped non-ASCII characters.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "lang": "GO语言",
+ "tag": "
",
+ }
+
+ // will output : {"lang":"GO\u8bed\u8a00","tag":"\u003cbr\u003e"}
+ c.AsciiJSON(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md b/src/content/docs/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md
new file mode 100644
index 000000000..138179eea
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-body-into-dirrerent-structs.md
@@ -0,0 +1,61 @@
+---
+title: "Try to bind body into different structs"
+
+---
+
+The normal methods for binding request body consumes `c.Request.Body` and they
+cannot be called multiple times.
+
+```go
+type formA struct {
+ Foo string `json:"foo" xml:"foo" binding:"required"`
+}
+
+type formB struct {
+ Bar string `json:"bar" xml:"bar" binding:"required"`
+}
+
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This c.ShouldBind consumes c.Request.Body and it cannot be reused.
+ if errA := c.ShouldBind(&objA); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // Always an error is occurred by this because c.Request.Body is EOF now.
+ } else if errB := c.ShouldBind(&objB); errB == nil {
+ c.String(http.StatusOK, `the body should be formB`)
+ } else {
+ ...
+ }
+}
+```
+
+For this, you can use `c.ShouldBindBodyWith`.
+
+```go
+func SomeHandler(c *gin.Context) {
+ objA := formA{}
+ objB := formB{}
+ // This reads c.Request.Body and stores the result into the context.
+ if errA := c.ShouldBindBodyWith(&objA, binding.JSON); errA == nil {
+ c.String(http.StatusOK, `the body should be formA`)
+ // At this time, it reuses body stored in the context.
+ } else if errB := c.ShouldBindBodyWith(&objB, binding.JSON); errB == nil {
+ c.String(http.StatusOK, `the body should be formB JSON`)
+ // And it can accepts other formats
+ } else if errB2 := c.ShouldBindBodyWith(&objB, binding.XML); errB2 == nil {
+ c.String(http.StatusOK, `the body should be formB XML`)
+ } else {
+ ...
+ }
+}
+```
+
+* `c.ShouldBindBodyWith` stores body into the context before binding. This has
+a slight impact to performance, so you should not use this method if you are
+enough to call binding at once.
+* This feature is only needed for some formats -- `JSON`, `XML`, `MsgPack`,
+`ProtoBuf`. For other formats, `Query`, `Form`, `FormPost`, `FormMultipart`,
+can be called by `c.ShouldBind()` multiple times without any damage to
+performance (See [#1341](https://github.com/gin-gonic/gin/pull/1341)).
+
diff --git a/src/content/docs/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md b/src/content/docs/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md
new file mode 100644
index 000000000..73f522675
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-form-data-request-with-custom-struct.md
@@ -0,0 +1,95 @@
+---
+title: "Bind form-data request with custom struct"
+
+---
+
+The follow example using custom struct:
+
+```go
+type StructA struct {
+ FieldA string `form:"field_a"`
+}
+
+type StructB struct {
+ NestedStruct StructA
+ FieldB string `form:"field_b"`
+}
+
+type StructC struct {
+ NestedStructPointer *StructA
+ FieldC string `form:"field_c"`
+}
+
+type StructD struct {
+ NestedAnonyStruct struct {
+ FieldX string `form:"field_x"`
+ }
+ FieldD string `form:"field_d"`
+}
+
+func GetDataB(c *gin.Context) {
+ var b StructB
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStruct,
+ "b": b.FieldB,
+ })
+}
+
+func GetDataC(c *gin.Context) {
+ var b StructC
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "a": b.NestedStructPointer,
+ "c": b.FieldC,
+ })
+}
+
+func GetDataD(c *gin.Context) {
+ var b StructD
+ c.Bind(&b)
+ c.JSON(200, gin.H{
+ "x": b.NestedAnonyStruct,
+ "d": b.FieldD,
+ })
+}
+
+func main() {
+ r := gin.Default()
+ r.GET("/getb", GetDataB)
+ r.GET("/getc", GetDataC)
+ r.GET("/getd", GetDataD)
+
+ r.Run()
+}
+```
+
+Using the command `curl` command result:
+
+```
+$ curl "http://localhost:8080/getb?field_a=hello&field_b=world"
+{"a":{"FieldA":"hello"},"b":"world"}
+$ curl "http://localhost:8080/getc?field_a=hello&field_c=world"
+{"a":{"FieldA":"hello"},"c":"world"}
+$ curl "http://localhost:8080/getd?field_x=hello&field_d=world"
+{"d":"world","x":{"FieldX":"hello"}}
+```
+
+**NOTE**: NOT support the follow style struct:
+
+```go
+type StructX struct {
+ X struct {} `form:"name_x"` // HERE have form
+}
+
+type StructY struct {
+ Y StructX `form:"name_y"` // HERE have form
+}
+
+type StructZ struct {
+ Z *StructZ `form:"name_z"` // HERE have form
+}
+```
+
+In a word, only support nested custom struct which have no `form` now.
+
diff --git a/src/content/docs/zh-tw/docs/examples/bind-html-checkbox.md b/src/content/docs/zh-tw/docs/examples/bind-html-checkbox.md
new file mode 100644
index 000000000..4b1ee65ef
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-html-checkbox.md
@@ -0,0 +1,49 @@
+---
+title: "Bind html checkboxes"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/129#issuecomment-124260092)
+
+main.go
+
+```go
+...
+
+type myForm struct {
+ Colors []string `form:"colors[]"`
+}
+
+...
+
+func formHandler(c *gin.Context) {
+ var fakeForm myForm
+ c.ShouldBind(&fakeForm)
+ c.JSON(200, gin.H{"color": fakeForm.Colors})
+}
+
+...
+
+```
+
+form.html
+
+```html
+
+```
+
+result:
+
+```sh
+{"color":["red","green","blue"]}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/bind-query-or-post.md b/src/content/docs/zh-tw/docs/examples/bind-query-or-post.md
new file mode 100644
index 000000000..9912d908a
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-query-or-post.md
@@ -0,0 +1,48 @@
+---
+title: "Bind query string or post data"
+
+---
+
+See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-264681292).
+
+```go
+package main
+
+import (
+ "log"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+ Birthday time.Time `form:"birthday" time_format:"2006-01-02" time_utc:"1"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ // If `GET`, only `Form` binding engine (`query`) used.
+ // If `POST`, first checks the `content-type` for `JSON` or `XML`, then uses `Form` (`form-data`).
+ // See more at https://github.com/gin-gonic/gin/blob/master/binding/binding.go#L48
+ if c.ShouldBind(&person) == nil {
+ log.Println(person.Name)
+ log.Println(person.Address)
+ log.Println(person.Birthday)
+ }
+
+ c.String(200, "Success")
+}
+```
+
+Test it with:
+```sh
+$ curl -X GET "localhost:8085/testing?name=appleboy&address=xyz&birthday=1992-03-15"
+```
diff --git a/src/content/docs/zh-tw/docs/examples/bind-single-binary-with-template.md b/src/content/docs/zh-tw/docs/examples/bind-single-binary-with-template.md
new file mode 100644
index 000000000..3f79dc8ac
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-single-binary-with-template.md
@@ -0,0 +1,46 @@
+---
+title: "Build a single binary with templates"
+
+---
+
+You can build a server into a single binary containing templates by using [go-assets][].
+
+[go-assets]: https://github.com/jessevdk/go-assets
+
+```go
+func main() {
+ r := gin.New()
+
+ t, err := loadTemplate()
+ if err != nil {
+ panic(err)
+ }
+ r.SetHTMLTemplate(t)
+
+ r.GET("/", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "/html/index.tmpl", nil)
+ })
+ r.Run(":8080")
+}
+
+// loadTemplate loads templates embedded by go-assets-builder
+func loadTemplate() (*template.Template, error) {
+ t := template.New("")
+ for name, file := range Assets.Files {
+ if file.IsDir() || !strings.HasSuffix(name, ".tmpl") {
+ continue
+ }
+ h, err := ioutil.ReadAll(file)
+ if err != nil {
+ return nil, err
+ }
+ t, err = t.New(name).Parse(string(h))
+ if err != nil {
+ return nil, err
+ }
+ }
+ return t, nil
+}
+```
+
+See a complete example in the [assets-in-binary/example01](https://github.com/gin-gonic/examples/tree/master/assets-in-binary/example01) directory.
diff --git a/src/content/docs/zh-tw/docs/examples/bind-uri.md b/src/content/docs/zh-tw/docs/examples/bind-uri.md
new file mode 100644
index 000000000..e4f1257ce
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/bind-uri.md
@@ -0,0 +1,37 @@
+---
+title: "Bind Uri"
+
+---
+
+查看[詳細訊息](https://github.com/gin-gonic/gin/issues/846).
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type Person struct {
+ ID string `uri:"id" binding:"required,uuid"`
+ Name string `uri:"name" binding:"required"`
+}
+
+func main() {
+ route := gin.Default()
+ route.GET("/:name/:id", func(c *gin.Context) {
+ var person Person
+ if err := c.ShouldBindUri(&person); err != nil {
+ c.JSON(400, gin.H{"msg": err})
+ return
+ }
+ c.JSON(200, gin.H{"name": person.Name, "uuid": person.ID})
+ })
+ route.Run(":8088")
+}
+```
+
+測試:
+
+```sh
+$ curl -v localhost:8088/thinkerou/987fbc97-4bed-5078-9f07-9141ba07c9f3
+$ curl -v localhost:8088/thinkerou/not-uuid
+```
diff --git a/src/content/docs/zh-tw/docs/examples/binding-and-validation.md b/src/content/docs/zh-tw/docs/examples/binding-and-validation.md
new file mode 100644
index 000000000..2de4465da
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/binding-and-validation.md
@@ -0,0 +1,118 @@
+---
+title: "Model binding and validation"
+
+---
+
+To bind a request body into a type, use model binding. We currently support binding of JSON, XML, YAML and standard form values (foo=bar&boo=baz).
+
+Gin uses [**go-playground/validator/v10**](https://github.com/go-playground/validator) for validation. Check the full docs on tags usage [here](https://pkg.go.dev/github.com/go-playground/validator/v10#hdr-Baked_In_Validators_and_Tags).
+
+Note that you need to set the corresponding binding tag on all fields you want to bind. For example, when binding from JSON, set `json:"fieldname"`.
+
+Also, Gin provides two sets of methods for binding:
+- **Type** - Must bind
+ - **Methods** - `Bind`, `BindJSON`, `BindXML`, `BindQuery`, `BindYAML`
+ - **Behavior** - These methods use `MustBindWith` under the hood. If there is a binding error, the request is aborted with `c.AbortWithError(400, err).SetType(ErrorTypeBind)`. This sets the response status code to 400 and the `Content-Type` header is set to `text/plain; charset=utf-8`. Note that if you try to set the response code after this, it will result in a warning `[GIN-debug] [WARNING] Headers were already written. Wanted to override status code 400 with 422`. If you wish to have greater control over the behavior, consider using the `ShouldBind` equivalent method.
+- **Type** - Should bind
+ - **Methods** - `ShouldBind`, `ShouldBindJSON`, `ShouldBindXML`, `ShouldBindQuery`, `ShouldBindYAML`
+ - **Behavior** - These methods use `ShouldBindWith` under the hood. If there is a binding error, the error is returned and it is the developer's responsibility to handle the request and error appropriately.
+
+When using the Bind-method, Gin tries to infer the binder depending on the Content-Type header. If you are sure what you are binding, you can use `MustBindWith` or `ShouldBindWith`.
+
+You can also specify that specific fields are required. If a field is decorated with `binding:"required"` and has a empty value when binding, an error will be returned.
+
+```go
+// Binding from JSON
+type Login struct {
+ User string `form:"user" json:"user" xml:"user" binding:"required"`
+ Password string `form:"password" json:"password" xml:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+
+ // Example for binding JSON ({"user": "manu", "password": "123"})
+ router.POST("/loginJSON", func(c *gin.Context) {
+ var json Login
+ if err := c.ShouldBindJSON(&json); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if json.User != "manu" || json.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding XML (
+ //
+ //
+ // manu
+ // 123
+ // )
+ router.POST("/loginXML", func(c *gin.Context) {
+ var xml Login
+ if err := c.ShouldBindXML(&xml); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if xml.User != "manu" || xml.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Example for binding a HTML form (user=manu&password=123)
+ router.POST("/loginForm", func(c *gin.Context) {
+ var form Login
+ // This will infer what binder to use depending on the content-type header.
+ if err := c.ShouldBind(&form); err != nil {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ return
+ }
+
+ if form.User != "manu" || form.Password != "123" {
+ c.JSON(http.StatusUnauthorized, gin.H{"status": "unauthorized"})
+ return
+ }
+
+ c.JSON(http.StatusOK, gin.H{"status": "you are logged in"})
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
+
+#### Sample request
+
+```sh
+$ curl -v -X POST \
+ http://localhost:8080/loginJSON \
+ -H 'content-type: application/json' \
+ -d '{ "user": "manu" }'
+> POST /loginJSON HTTP/1.1
+> Host: localhost:8080
+> User-Agent: curl/7.51.0
+> Accept: */*
+> content-type: application/json
+> Content-Length: 18
+>
+* upload completely sent off: 18 out of 18 bytes
+< HTTP/1.1 400 Bad Request
+< Content-Type: application/json; charset=utf-8
+< Date: Fri, 04 Aug 2017 03:51:31 GMT
+< Content-Length: 100
+<
+{"error":"Key: 'Login.Password' Error:Field validation for 'Password' failed on the 'required' tag"}
+```
+
+#### Skip validate
+
+When running the above example using the above the `curl` command, it returns error. Because the example use `binding:"required"` for `Password`. If use `binding:"-"` for `Password`, then it will not return error when running the above example again.
diff --git a/src/content/docs/zh-tw/docs/examples/controlling-log-output-coloring.md b/src/content/docs/zh-tw/docs/examples/controlling-log-output-coloring.md
new file mode 100644
index 000000000..8d0e834c8
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/controlling-log-output-coloring.md
@@ -0,0 +1,45 @@
+---
+title: "Controlling Log output coloring"
+
+---
+
+By default, logs output on console should be colorized depending on the detected TTY.
+
+Never colorize logs:
+
+```go
+func main() {
+ // Disable log's color
+ gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
+Always colorize logs:
+
+```go
+func main() {
+ // Force log's color
+ gin.ForceConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/cookie.md b/src/content/docs/zh-tw/docs/examples/cookie.md
new file mode 100644
index 000000000..090e66354
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/cookie.md
@@ -0,0 +1,31 @@
+---
+title: "Set and get a cookie"
+
+---
+
+```go
+import (
+ "fmt"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+
+ router := gin.Default()
+
+ router.GET("/cookie", func(c *gin.Context) {
+
+ cookie, err := c.Cookie("gin_cookie")
+
+ if err != nil {
+ cookie = "NotSet"
+ c.SetCookie("gin_cookie", "test", 3600, "/", "localhost", false, true)
+ }
+
+ fmt.Printf("Cookie value: %s \n", cookie)
+ })
+
+ router.Run()
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/custom-http-config.md b/src/content/docs/zh-tw/docs/examples/custom-http-config.md
new file mode 100644
index 000000000..42de78314
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/custom-http-config.md
@@ -0,0 +1,33 @@
+---
+title: "Custom HTTP configuration"
+
+---
+
+Use `http.ListenAndServe()` directly, like this:
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+ http.ListenAndServe(":8080", router)
+}
+```
+or
+
+```go
+import "net/http"
+
+func main() {
+ router := gin.Default()
+
+ s := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ ReadTimeout: 10 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ MaxHeaderBytes: 1 << 20,
+ }
+ s.ListenAndServe()
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/custom-middleware.md b/src/content/docs/zh-tw/docs/examples/custom-middleware.md
new file mode 100644
index 000000000..8de8438b0
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/custom-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Custom Middleware"
+
+---
+
+```go
+func Logger() gin.HandlerFunc {
+ return func(c *gin.Context) {
+ t := time.Now()
+
+ // Set example variable
+ c.Set("example", "12345")
+
+ // before request
+
+ c.Next()
+
+ // after request
+ latency := time.Since(t)
+ log.Print(latency)
+
+ // access the status we are sending
+ status := c.Writer.Status()
+ log.Println(status)
+ }
+}
+
+func main() {
+ r := gin.New()
+ r.Use(Logger())
+
+ r.GET("/test", func(c *gin.Context) {
+ example := c.MustGet("example").(string)
+
+ // it would print: "12345"
+ log.Println(example)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/custom-validators.md b/src/content/docs/zh-tw/docs/examples/custom-validators.md
new file mode 100644
index 000000000..c95126f7e
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/custom-validators.md
@@ -0,0 +1,70 @@
+---
+title: "Custom validators"
+
+---
+
+It is also possible to register custom validators. See the [example code](examples/custom-validation/server.go).
+
+```go
+package main
+
+import (
+ "net/http"
+ "reflect"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "github.com/gin-gonic/gin/binding"
+ "github.com/go-playground/validator/v10"
+)
+
+// Booking contains binded and validated data.
+type Booking struct {
+ CheckIn time.Time `form:"check_in" binding:"required,bookabledate" time_format:"2006-01-02"`
+ CheckOut time.Time `form:"check_out" binding:"required,gtfield=CheckIn,bookabledate" time_format:"2006-01-02"`
+}
+
+func bookableDate(
+ v *validator.Validate, topStruct reflect.Value, currentStructOrField reflect.Value,
+ field reflect.Value, fieldType reflect.Type, fieldKind reflect.Kind, param string,
+) bool {
+ if date, ok := field.Interface().(time.Time); ok {
+ today := time.Now()
+ if today.Year() > date.Year() || today.YearDay() > date.YearDay() {
+ return false
+ }
+ }
+ return true
+}
+
+func main() {
+ route := gin.Default()
+
+ if v, ok := binding.Validator.Engine().(*validator.Validate); ok {
+ v.RegisterValidation("bookabledate", bookableDate)
+ }
+
+ route.GET("/bookable", getBookable)
+ route.Run(":8085")
+}
+
+func getBookable(c *gin.Context) {
+ var b Booking
+ if err := c.ShouldBindWith(&b, binding.Query); err == nil {
+ c.JSON(http.StatusOK, gin.H{"message": "Booking dates are valid!"})
+ } else {
+ c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
+ }
+}
+```
+
+```sh
+$ curl "localhost:8085/bookable?check_in=2018-04-16&check_out=2018-04-17"
+{"message":"Booking dates are valid!"}
+
+$ curl "localhost:8085/bookable?check_in=2018-03-08&check_out=2018-03-09"
+{"error":"Key: 'Booking.CheckIn' Error:Field validation for 'CheckIn' failed on the 'bookabledate' tag"}
+```
+
+[Struct level validations](https://github.com/go-playground/validator/releases/tag/v8.7) can also be registered this way.
+See the [struct-lvl-validation example](examples/struct-lvl-validations) to learn more.
diff --git a/src/content/docs/zh-tw/docs/examples/define-format-for-the-log-of-routes.md b/src/content/docs/zh-tw/docs/examples/define-format-for-the-log-of-routes.md
new file mode 100644
index 000000000..44bd991a9
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/define-format-for-the-log-of-routes.md
@@ -0,0 +1,44 @@
+---
+title: "Define format for the log of routes"
+
+---
+
+The default log of routes is:
+```
+[GIN-debug] POST /foo --> main.main.func1 (3 handlers)
+[GIN-debug] GET /bar --> main.main.func2 (3 handlers)
+[GIN-debug] GET /status --> main.main.func3 (3 handlers)
+```
+
+If you want to log this information in given format (e.g. JSON, key values or something else), then you can define this format with `gin.DebugPrintRouteFunc`.
+In the example below, we log all routes with standard log package but you can use another log tools that suits of your needs.
+```go
+import (
+ "log"
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+ gin.DebugPrintRouteFunc = func(httpMethod, absolutePath, handlerName string, nuHandlers int) {
+ log.Printf("endpoint %v %v %v %v\n", httpMethod, absolutePath, handlerName, nuHandlers)
+ }
+
+ r.POST("/foo", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "foo")
+ })
+
+ r.GET("/bar", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "bar")
+ })
+
+ r.GET("/status", func(c *gin.Context) {
+ c.JSON(http.StatusOK, "ok")
+ })
+
+ // Listen and Server in http://0.0.0.0:8080
+ r.Run()
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/goroutines-inside-a-middleware.md b/src/content/docs/zh-tw/docs/examples/goroutines-inside-a-middleware.md
new file mode 100644
index 000000000..f3a6b10d6
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/goroutines-inside-a-middleware.md
@@ -0,0 +1,35 @@
+---
+title: "Goroutines inside a middleware"
+
+---
+
+When starting new Goroutines inside a middleware or handler, you **SHOULD NOT** use the original context inside it, you have to use a read-only copy.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/long_async", func(c *gin.Context) {
+ // create copy to be used inside the goroutine
+ cCp := c.Copy()
+ go func() {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // note that you are using the copied context "cCp", IMPORTANT
+ log.Println("Done! in path " + cCp.Request.URL.Path)
+ }()
+ })
+
+ r.GET("/long_sync", func(c *gin.Context) {
+ // simulate a long task with time.Sleep(). 5 seconds
+ time.Sleep(5 * time.Second)
+
+ // since we are NOT using a goroutine, we do not have to copy the context
+ log.Println("Done! in path " + c.Request.URL.Path)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/graceful-restart-or-stop.md b/src/content/docs/zh-tw/docs/examples/graceful-restart-or-stop.md
new file mode 100644
index 000000000..2d4b7f650
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/graceful-restart-or-stop.md
@@ -0,0 +1,76 @@
+---
+title: "Graceful restart or stop"
+
+---
+
+Do you want to graceful restart or stop your web server?
+There are some ways this can be done.
+
+We can use [fvbock/endless](https://github.com/fvbock/endless) to replace the default `ListenAndServe`. Refer issue [#296](https://github.com/gin-gonic/gin/issues/296) for more details.
+
+```go
+router := gin.Default()
+router.GET("/", handler)
+// [...]
+endless.ListenAndServe(":4242", router)
+```
+
+An alternative to endless:
+
+* [manners](https://github.com/braintree/manners): A polite Go HTTP server that shuts down gracefully.
+* [graceful](https://github.com/tylerb/graceful): Graceful is a Go package enabling graceful shutdown of an http.Handler server.
+* [grace](https://github.com/facebookgo/grace): Graceful restart & zero downtime deploy for Go servers.
+
+If you are using Go 1.8, you may not need to use this library! Consider using http.Server's built-in [Shutdown()](https://golang.org/pkg/net/http/#Server.Shutdown) method for graceful shutdowns. See the full [graceful-shutdown](./examples/graceful-shutdown) example with gin.
+
+```go
+// +build go1.8
+
+package main
+
+import (
+ "context"
+ "log"
+ "net/http"
+ "os"
+ "os/signal"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ router := gin.Default()
+ router.GET("/", func(c *gin.Context) {
+ time.Sleep(5 * time.Second)
+ c.String(http.StatusOK, "Welcome Gin Server")
+ })
+
+ srv := &http.Server{
+ Addr: ":8080",
+ Handler: router,
+ }
+
+ go func() {
+ // service connections
+ if err := srv.ListenAndServe(); err != nil && err != http.ErrServerClosed {
+ log.Fatalf("listen: %s\n", err)
+ }
+ }()
+
+ // Wait for interrupt signal to gracefully shutdown the server with
+ // a timeout of 5 seconds.
+ quit := make(chan os.Signal, 1)
+ signal.Notify(quit, os.Interrupt)
+ <-quit
+ log.Println("Shutdown Server ...")
+
+ ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
+ defer cancel()
+ if err := srv.Shutdown(ctx); err != nil {
+ log.Fatal("Server Shutdown:", err)
+ }
+ log.Println("Server exiting")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/grouping-routes.md b/src/content/docs/zh-tw/docs/examples/grouping-routes.md
new file mode 100644
index 000000000..c7f7a7245
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/grouping-routes.md
@@ -0,0 +1,28 @@
+---
+title: "Grouping routes"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Simple group: v1
+ v1 := router.Group("/v1")
+ {
+ v1.POST("/login", loginEndpoint)
+ v1.POST("/submit", submitEndpoint)
+ v1.POST("/read", readEndpoint)
+ }
+
+ // Simple group: v2
+ v2 := router.Group("/v2")
+ {
+ v2.POST("/login", loginEndpoint)
+ v2.POST("/submit", submitEndpoint)
+ v2.POST("/read", readEndpoint)
+ }
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/html-rendering.md b/src/content/docs/zh-tw/docs/examples/html-rendering.md
new file mode 100644
index 000000000..a73658af3
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/html-rendering.md
@@ -0,0 +1,150 @@
+---
+title: "HTML rendering"
+
+---
+
+Using LoadHTMLGlob() or LoadHTMLFiles()
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/*")
+ //router.LoadHTMLFiles("templates/template1.html", "templates/template2.html")
+ router.GET("/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "index.tmpl", gin.H{
+ "title": "Main website",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/index.tmpl
+
+```html
+
+
+ {{ .title }}
+
+
+```
+
+Using templates with same name in different directories
+
+```go
+func main() {
+ router := gin.Default()
+ router.LoadHTMLGlob("templates/**/*")
+ router.GET("/posts/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "posts/index.tmpl", gin.H{
+ "title": "Posts",
+ })
+ })
+ router.GET("/users/index", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "users/index.tmpl", gin.H{
+ "title": "Users",
+ })
+ })
+ router.Run(":8080")
+}
+```
+
+templates/posts/index.tmpl
+
+```html
+{{ define "posts/index.tmpl" }}
+
+ {{ .title }}
+
+Using posts/index.tmpl
+
+{{ end }}
+```
+
+templates/users/index.tmpl
+
+```html
+{{ define "users/index.tmpl" }}
+
+ {{ .title }}
+
+Using users/index.tmpl
+
+{{ end }}
+```
+
+#### Custom Template renderer
+
+You can also use your own html template render
+
+```go
+import "html/template"
+
+func main() {
+ router := gin.Default()
+ html := template.Must(template.ParseFiles("file1", "file2"))
+ router.SetHTMLTemplate(html)
+ router.Run(":8080")
+}
+```
+
+#### Custom Delimiters
+
+You may use custom delims
+
+```go
+ r := gin.Default()
+ r.Delims("{[{", "}]}")
+ r.LoadHTMLGlob("/path/to/templates")
+```
+
+#### Custom Template Funcs
+
+See the detail [example code](examples/template).
+
+main.go
+
+```go
+import (
+ "fmt"
+ "html/template"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+)
+
+func formatAsDate(t time.Time) string {
+ year, month, day := t.Date()
+ return fmt.Sprintf("%d/%02d/%02d", year, month, day)
+}
+
+func main() {
+ router := gin.Default()
+ router.Delims("{[{", "}]}")
+ router.SetFuncMap(template.FuncMap{
+ "formatAsDate": formatAsDate,
+ })
+ router.LoadHTMLFiles("./testdata/template/raw.tmpl")
+
+ router.GET("/raw", func(c *gin.Context) {
+ c.HTML(http.StatusOK, "raw.tmpl", map[string]interface{}{
+ "now": time.Date(2017, 07, 01, 0, 0, 0, 0, time.UTC),
+ })
+ })
+
+ router.Run(":8080")
+}
+
+```
+
+raw.tmpl
+
+```sh
+Date: {[{.now | formatAsDate}]}
+```
+
+Result:
+```sh
+Date: 2017/07/01
+```
diff --git a/src/content/docs/zh-tw/docs/examples/http-method.md b/src/content/docs/zh-tw/docs/examples/http-method.md
new file mode 100644
index 000000000..f55d155ee
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/http-method.md
@@ -0,0 +1,28 @@
+---
+title: "Using HTTP method"
+
+---
+
+```go
+func main() {
+ // Disable Console Color
+ // gin.DisableConsoleColor()
+
+ // Creates a gin router with default middleware:
+ // logger and recovery (crash-free) middleware
+ router := gin.Default()
+
+ router.GET("/someGet", getting)
+ router.POST("/somePost", posting)
+ router.PUT("/somePut", putting)
+ router.DELETE("/someDelete", deleting)
+ router.PATCH("/somePatch", patching)
+ router.HEAD("/someHead", head)
+ router.OPTIONS("/someOptions", options)
+
+ // By default it serves on :8080 unless a
+ // PORT environment variable was defined.
+ router.Run()
+ // router.Run(":3000") for a hard coded port
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/http2-server-push.md b/src/content/docs/zh-tw/docs/examples/http2-server-push.md
new file mode 100644
index 000000000..192d22a45
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/http2-server-push.md
@@ -0,0 +1,51 @@
+---
+title: "HTTP2 server push"
+
+---
+
+http.Pusher is supported only **go1.8+**. See the [golang blog](https://blog.golang.org/h2push) for detail information.
+
+```go
+package main
+
+import (
+ "html/template"
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+var html = template.Must(template.New("https").Parse(`
+
+
+ Https Test
+
+
+
+ Welcome, Ginner!
+
+
+`))
+
+func main() {
+ r := gin.Default()
+ r.Static("/assets", "./assets")
+ r.SetHTMLTemplate(html)
+
+ r.GET("/", func(c *gin.Context) {
+ if pusher := c.Writer.Pusher(); pusher != nil {
+ // use pusher.Push() to do server push
+ if err := pusher.Push("/assets/app.js", nil); err != nil {
+ log.Printf("Failed to push: %v", err)
+ }
+ }
+ c.HTML(200, "https", gin.H{
+ "status": "success",
+ })
+ })
+
+ // Listen and Server in https://127.0.0.1:8080
+ r.RunTLS(":8080", "./testdata/server.pem", "./testdata/server.key")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/index.md b/src/content/docs/zh-tw/docs/examples/index.md
new file mode 100644
index 000000000..02ff94794
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/index.md
@@ -0,0 +1,8 @@
+---
+title: "範例"
+
+sidebar:
+ order: 6
+---
+
+這個章節列出一些 API 使用方法。
diff --git a/src/content/docs/zh-tw/docs/examples/jsonp.md b/src/content/docs/zh-tw/docs/examples/jsonp.md
new file mode 100644
index 000000000..bc4439a44
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/jsonp.md
@@ -0,0 +1,25 @@
+---
+title: "JSONP"
+
+---
+
+Using JSONP to request data from a server in a different domain. Add callback to response body if the query parameter callback exists.
+
+```go
+func main() {
+ r := gin.Default()
+
+ r.GET("/JSONP?callback=x", func(c *gin.Context) {
+ data := map[string]interface{}{
+ "foo": "bar",
+ }
+
+ //callback is x
+ // Will output : x({\"foo\":\"bar\"})
+ c.JSONP(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/map-as-querystring-or-postform.md b/src/content/docs/zh-tw/docs/examples/map-as-querystring-or-postform.md
new file mode 100644
index 000000000..5ed88b0b5
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/map-as-querystring-or-postform.md
@@ -0,0 +1,31 @@
+---
+title: "Map as querystring or postform parameters"
+
+---
+
+```sh
+POST /post?ids[a]=1234&ids[b]=hello HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+names[first]=thinkerou&names[second]=tianou
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ ids := c.QueryMap("ids")
+ names := c.PostFormMap("names")
+
+ fmt.Printf("ids: %v; names: %v", ids, names)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+ids: map[b:hello a:1234], names: map[second:tianou first:thinkerou]
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-binding.md b/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-binding.md
new file mode 100644
index 000000000..73fee286a
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-binding.md
@@ -0,0 +1,41 @@
+---
+title: "Multipart/Urlencoded binding"
+
+---
+
+```go
+package main
+
+import (
+ "github.com/gin-gonic/gin"
+)
+
+type LoginForm struct {
+ User string `form:"user" binding:"required"`
+ Password string `form:"password" binding:"required"`
+}
+
+func main() {
+ router := gin.Default()
+ router.POST("/login", func(c *gin.Context) {
+ // you can bind multipart form with explicit binding declaration:
+ // c.ShouldBindWith(&form, binding.Form)
+ // or you can simply use autobinding with ShouldBind method:
+ var form LoginForm
+ // in this case proper binding will be automatically selected
+ if c.ShouldBind(&form) == nil {
+ if form.User == "user" && form.Password == "password" {
+ c.JSON(200, gin.H{"status": "you are logged in"})
+ } else {
+ c.JSON(401, gin.H{"status": "unauthorized"})
+ }
+ }
+ })
+ router.Run(":8080")
+}
+```
+
+Test it with:
+```sh
+$ curl -v --form user=user --form password=password http://localhost:8080/login
+```
diff --git a/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-form.md b/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-form.md
new file mode 100644
index 000000000..04eab2373
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/multipart-urlencoded-form.md
@@ -0,0 +1,23 @@
+---
+title: "Multipart/Urlencoded form"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/form_post", func(c *gin.Context) {
+ message := c.PostForm("message")
+ nick := c.DefaultPostForm("nick", "anonymous")
+
+ c.JSON(200, gin.H{
+ "status": "posted",
+ "message": message,
+ "nick": nick,
+ })
+ })
+ router.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/multiple-template.md b/src/content/docs/zh-tw/docs/examples/multiple-template.md
new file mode 100644
index 000000000..28b58c213
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/multiple-template.md
@@ -0,0 +1,6 @@
+---
+title: "Multitemplate"
+
+---
+
+Gin allow by default use only one html.Template. Check [a multitemplate render](https://github.com/gin-contrib/multitemplate) for using features like go 1.6 `block template`.
diff --git a/src/content/docs/zh-tw/docs/examples/only-bind-query-string.md b/src/content/docs/zh-tw/docs/examples/only-bind-query-string.md
new file mode 100644
index 000000000..bdd6c174e
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/only-bind-query-string.md
@@ -0,0 +1,37 @@
+---
+title: "Only bind query string"
+
+---
+
+`ShouldBindQuery` function only binds the query params and not the post data. See the [detail information](https://github.com/gin-gonic/gin/issues/742#issuecomment-315953017).
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/gin"
+)
+
+type Person struct {
+ Name string `form:"name"`
+ Address string `form:"address"`
+}
+
+func main() {
+ route := gin.Default()
+ route.Any("/testing", startPage)
+ route.Run(":8085")
+}
+
+func startPage(c *gin.Context) {
+ var person Person
+ if c.ShouldBindQuery(&person) == nil {
+ log.Println("====== Only Bind By Query String ======")
+ log.Println(person.Name)
+ log.Println(person.Address)
+ }
+ c.String(200, "Success")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/param-in-path.md b/src/content/docs/zh-tw/docs/examples/param-in-path.md
new file mode 100644
index 000000000..b0a4a3b68
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/param-in-path.md
@@ -0,0 +1,27 @@
+---
+title: "Parameters in path"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // This handler will match /user/john but will not match /user/ or /user
+ router.GET("/user/:name", func(c *gin.Context) {
+ name := c.Param("name")
+ c.String(http.StatusOK, "Hello %s", name)
+ })
+
+ // However, this one will match /user/john/ and also /user/john/send
+ // If no other routers match /user/john, it will redirect to /user/john/
+ router.GET("/user/:name/*action", func(c *gin.Context) {
+ name := c.Param("name")
+ action := c.Param("action")
+ message := name + " is " + action
+ c.String(http.StatusOK, message)
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/pure-json.md b/src/content/docs/zh-tw/docs/examples/pure-json.md
new file mode 100644
index 000000000..5fbf8bfc1
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/pure-json.md
@@ -0,0 +1,30 @@
+---
+title: "PureJSON"
+
+---
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // Serves unicode entities
+ r.GET("/json", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // Serves literal characters
+ r.GET("/purejson", func(c *gin.Context) {
+ c.PureJSON(200, gin.H{
+ "html": "Hello, world!",
+ })
+ })
+
+ // listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/query-and-post-form.md b/src/content/docs/zh-tw/docs/examples/query-and-post-form.md
new file mode 100644
index 000000000..5c8e6d21e
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/query-and-post-form.md
@@ -0,0 +1,32 @@
+---
+title: "Query and post form"
+
+---
+
+```sh
+POST /post?id=1234&page=1 HTTP/1.1
+Content-Type: application/x-www-form-urlencoded
+
+name=manu&message=this_is_great
+```
+
+```go
+func main() {
+ router := gin.Default()
+
+ router.POST("/post", func(c *gin.Context) {
+
+ id := c.Query("id")
+ page := c.DefaultQuery("page", "0")
+ name := c.PostForm("name")
+ message := c.PostForm("message")
+
+ fmt.Printf("id: %s; page: %s; name: %s; message: %s", id, page, name, message)
+ })
+ router.Run(":8080")
+}
+```
+
+```sh
+id: 1234; page: 1; name: manu; message: this_is_great
+```
diff --git a/src/content/docs/zh-tw/docs/examples/querystring-param.md b/src/content/docs/zh-tw/docs/examples/querystring-param.md
new file mode 100644
index 000000000..cba891746
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/querystring-param.md
@@ -0,0 +1,20 @@
+---
+title: "Query string parameters"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+
+ // Query string parameters are parsed using the existing underlying request object.
+ // The request responds to a url matching: /welcome?firstname=Jane&lastname=Doe
+ router.GET("/welcome", func(c *gin.Context) {
+ firstname := c.DefaultQuery("firstname", "Guest")
+ lastname := c.Query("lastname") // shortcut for c.Request.URL.Query().Get("lastname")
+
+ c.String(http.StatusOK, "Hello %s %s", firstname, lastname)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/redirects.md b/src/content/docs/zh-tw/docs/examples/redirects.md
new file mode 100644
index 000000000..e62a9952e
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/redirects.md
@@ -0,0 +1,32 @@
+---
+title: "Redirects"
+
+---
+
+Issuing a HTTP redirect is easy. Both internal and external locations are supported.
+
+```go
+r.GET("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusMovedPermanently, "http://www.google.com/")
+})
+```
+
+Issuing a HTTP redirect from POST. Refer to issue: [#444](https://github.com/gin-gonic/gin/issues/444)
+
+```go
+r.POST("/test", func(c *gin.Context) {
+ c.Redirect(http.StatusFound, "/foo")
+})
+```
+
+Issuing a Router redirect, use `HandleContext` like below.
+
+``` go
+r.GET("/test", func(c *gin.Context) {
+ c.Request.URL.Path = "/test2"
+ r.HandleContext(c)
+})
+r.GET("/test2", func(c *gin.Context) {
+ c.JSON(200, gin.H{"hello": "world"})
+})
+```
diff --git a/src/content/docs/zh-tw/docs/examples/rendering.md b/src/content/docs/zh-tw/docs/examples/rendering.md
new file mode 100644
index 000000000..c9c705c65
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/rendering.md
@@ -0,0 +1,54 @@
+---
+title: "XML/JSON/YAML/ProtoBuf rendering"
+
+---
+
+```go
+func main() {
+ r := gin.Default()
+
+ // gin.H is a shortcut for map[string]interface{}
+ r.GET("/someJSON", func(c *gin.Context) {
+ c.JSON(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/moreJSON", func(c *gin.Context) {
+ // You also can use a struct
+ var msg struct {
+ Name string `json:"user"`
+ Message string
+ Number int
+ }
+ msg.Name = "Lena"
+ msg.Message = "hey"
+ msg.Number = 123
+ // Note that msg.Name becomes "user" in the JSON
+ // Will output : {"user": "Lena", "Message": "hey", "Number": 123}
+ c.JSON(http.StatusOK, msg)
+ })
+
+ r.GET("/someXML", func(c *gin.Context) {
+ c.XML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someYAML", func(c *gin.Context) {
+ c.YAML(http.StatusOK, gin.H{"message": "hey", "status": http.StatusOK})
+ })
+
+ r.GET("/someProtoBuf", func(c *gin.Context) {
+ reps := []int64{int64(1), int64(2)}
+ label := "test"
+ // The specific definition of protobuf is written in the testdata/protoexample file.
+ data := &protoexample.Test{
+ Label: &label,
+ Reps: reps,
+ }
+ // Note that data becomes binary data in the response
+ // Will output protoexample.Test protobuf serialized data
+ c.ProtoBuf(http.StatusOK, data)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/run-multiple-service.md b/src/content/docs/zh-tw/docs/examples/run-multiple-service.md
new file mode 100644
index 000000000..dd7e30efd
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/run-multiple-service.md
@@ -0,0 +1,84 @@
+---
+title: "Run multiple service"
+
+---
+
+See the [question](https://github.com/gin-gonic/gin/issues/346) and try the following example:
+
+```go
+package main
+
+import (
+ "log"
+ "net/http"
+ "time"
+
+ "github.com/gin-gonic/gin"
+ "golang.org/x/sync/errgroup"
+)
+
+var (
+ g errgroup.Group
+)
+
+func router01() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 01",
+ },
+ )
+ })
+
+ return e
+}
+
+func router02() http.Handler {
+ e := gin.New()
+ e.Use(gin.Recovery())
+ e.GET("/", func(c *gin.Context) {
+ c.JSON(
+ http.StatusOK,
+ gin.H{
+ "code": http.StatusOK,
+ "error": "Welcome server 02",
+ },
+ )
+ })
+
+ return e
+}
+
+func main() {
+ server01 := &http.Server{
+ Addr: ":8080",
+ Handler: router01(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ server02 := &http.Server{
+ Addr: ":8081",
+ Handler: router02(),
+ ReadTimeout: 5 * time.Second,
+ WriteTimeout: 10 * time.Second,
+ }
+
+ g.Go(func() error {
+ return server01.ListenAndServe()
+ })
+
+ g.Go(func() error {
+ return server02.ListenAndServe()
+ })
+
+ if err := g.Wait(); err != nil {
+ log.Fatal(err)
+ }
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/secure-json.md b/src/content/docs/zh-tw/docs/examples/secure-json.md
new file mode 100644
index 000000000..82e63a4c4
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/secure-json.md
@@ -0,0 +1,25 @@
+---
+title: "SecureJSON"
+
+---
+
+Using SecureJSON to prevent json hijacking. Default prepends `"while(1),"` to response body if the given struct is array values.
+
+```go
+func main() {
+ r := gin.Default()
+
+ // You can also use your own secure json prefix
+ // r.SecureJsonPrefix(")]}',\n")
+
+ r.GET("/someJSON", func(c *gin.Context) {
+ names := []string{"lena", "austin", "foo"}
+
+ // Will output : while(1);["lena","austin","foo"]
+ c.SecureJSON(http.StatusOK, names)
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/security-headers.md b/src/content/docs/zh-tw/docs/examples/security-headers.md
new file mode 100644
index 000000000..7d5bebf39
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/security-headers.md
@@ -0,0 +1,75 @@
+---
+title: "安全页眉"
+
+---
+
+使用安全标头保护网络应用程序免受常见安全漏洞的攻击非常重要。本示例将向您展示如何在 Gin 应用程序中添加安全标头,以及如何避免与主机标头注入相关的攻击(SSRF、开放重定向)。
+
+```go
+package main
+
+import (
+ "net/http"
+
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ expectedHost := "localhost:8080"
+
+ // Setup Security Headers
+ r.Use(func(c *gin.Context) {
+ if c.Request.Host != expectedHost {
+ c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"error": "Invalid host header"})
+ return
+ }
+ c.Header("X-Frame-Options", "DENY")
+ c.Header("Content-Security-Policy", "default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';")
+ c.Header("X-XSS-Protection", "1; mode=block")
+ c.Header("Strict-Transport-Security", "max-age=31536000; includeSubDomains; preload")
+ c.Header("Referrer-Policy", "strict-origin")
+ c.Header("X-Content-Type-Options", "nosniff")
+ c.Header("Permissions-Policy", "geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()")
+ c.Next()
+ })
+
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+您可以通过 `curl` 进行测试。
+
+```bash
+// 检查页眉
+
+curl localhost:8080/ping -I
+
+HTTP/1.1 404 Not Found
+Content-Security-Policy: default-src 'self'; connect-src *; font-src *; script-src-elem * 'unsafe-inline'; img-src * data:; style-src * 'unsafe-inline';
+Content-Type: text/plain
+Permissions-Policy: geolocation=(),midi=(),sync-xhr=(),microphone=(),camera=(),magnetometer=(),gyroscope=(),fullscreen=(self),payment=()
+Referrer-Policy: strict-origin
+Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
+X-Content-Type-Options: nosniff
+X-Frame-Options: DENY
+X-Xss-Protection: 1; mode=block
+Date: Sat, 30 Mar 2024 08:20:44 GMT
+Content-Length: 18
+
+// 检查主机标头注入
+
+curl localhost:8080/ping -I -H "Host:neti.ee"
+
+HTTP/1.1 400 Bad Request
+Content-Type: application/json; charset=utf-8
+Date: Sat, 30 Mar 2024 08:21:09 GMT
+Content-Length: 31
+```
\ No newline at end of file
diff --git a/src/content/docs/zh-tw/docs/examples/serving-data-from-reader.md b/src/content/docs/zh-tw/docs/examples/serving-data-from-reader.md
new file mode 100644
index 000000000..614db12ce
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/serving-data-from-reader.md
@@ -0,0 +1,28 @@
+---
+title: "Serving data from reader"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.GET("/someDataFromReader", func(c *gin.Context) {
+ response, err := http.Get("https://raw.githubusercontent.com/gin-gonic/logo/master/color.png")
+ if err != nil || response.StatusCode != http.StatusOK {
+ c.Status(http.StatusServiceUnavailable)
+ return
+ }
+
+ reader := response.Body
+ contentLength := response.ContentLength
+ contentType := response.Header.Get("Content-Type")
+
+ extraHeaders := map[string]string{
+ "Content-Disposition": `attachment; filename="gopher.png"`,
+ }
+
+ c.DataFromReader(http.StatusOK, contentLength, contentType, reader, extraHeaders)
+ })
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/serving-static-files.md b/src/content/docs/zh-tw/docs/examples/serving-static-files.md
new file mode 100644
index 000000000..bda67da07
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/serving-static-files.md
@@ -0,0 +1,16 @@
+---
+title: "Serving static files"
+
+---
+
+```go
+func main() {
+ router := gin.Default()
+ router.Static("/assets", "./assets")
+ router.StaticFS("/more_static", http.Dir("my_file_system"))
+ router.StaticFile("/favicon.ico", "./resources/favicon.ico")
+
+ // Listen and serve on 0.0.0.0:8080
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/support-lets-encrypt.md b/src/content/docs/zh-tw/docs/examples/support-lets-encrypt.md
new file mode 100644
index 000000000..841c1a7f9
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/support-lets-encrypt.md
@@ -0,0 +1,60 @@
+---
+title: "Support Let's Encrypt"
+
+---
+
+example for 1-line LetsEncrypt HTTPS servers.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ log.Fatal(autotls.Run(r, "example1.com", "example2.com"))
+}
+```
+
+example for custom autocert manager.
+
+```go
+package main
+
+import (
+ "log"
+
+ "github.com/gin-gonic/autotls"
+ "github.com/gin-gonic/gin"
+ "golang.org/x/crypto/acme/autocert"
+)
+
+func main() {
+ r := gin.Default()
+
+ // Ping handler
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ m := autocert.Manager{
+ Prompt: autocert.AcceptTOS,
+ HostPolicy: autocert.HostWhitelist("example1.com", "example2.com"),
+ Cache: autocert.DirCache("/var/www/.cache"),
+ }
+
+ log.Fatal(autotls.RunWithManager(r, &m))
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/upload-file/index.md b/src/content/docs/zh-tw/docs/examples/upload-file/index.md
new file mode 100644
index 000000000..d0ff99e85
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/upload-file/index.md
@@ -0,0 +1,6 @@
+---
+title: "Upload files"
+
+---
+
+The section lists upload file api usage.
diff --git a/src/content/docs/zh-tw/docs/examples/upload-file/multiple-file.md b/src/content/docs/zh-tw/docs/examples/upload-file/multiple-file.md
new file mode 100644
index 000000000..45760fa2d
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/upload-file/multiple-file.md
@@ -0,0 +1,37 @@
+---
+title: "Multiple files"
+
+---
+
+See the detail [example code](examples/upload-file/multiple).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // Multipart form
+ form, _ := c.MultipartForm()
+ files := form.File["upload[]"]
+
+ for _, file := range files {
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+ }
+ c.String(http.StatusOK, fmt.Sprintf("%d files uploaded!", len(files)))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "upload[]=@/Users/appleboy/test1.zip" \
+ -F "upload[]=@/Users/appleboy/test2.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/zh-tw/docs/examples/upload-file/single-file.md b/src/content/docs/zh-tw/docs/examples/upload-file/single-file.md
new file mode 100644
index 000000000..cd7bd8fa8
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/upload-file/single-file.md
@@ -0,0 +1,33 @@
+---
+title: "Single file"
+
+---
+
+References issue [#774](https://github.com/gin-gonic/gin/issues/774) and detail [example code](examples/upload-file/single).
+
+```go
+func main() {
+ router := gin.Default()
+ // Set a lower memory limit for multipart forms (default is 32 MiB)
+ router.MaxMultipartMemory = 8 << 20 // 8 MiB
+ router.POST("/upload", func(c *gin.Context) {
+ // single file
+ file, _ := c.FormFile("file")
+ log.Println(file.Filename)
+
+ // Upload the file to specific dst.
+ c.SaveUploadedFile(file, dst)
+
+ c.String(http.StatusOK, fmt.Sprintf("'%s' uploaded!", file.Filename))
+ })
+ router.Run(":8080")
+}
+```
+
+How to `curl`:
+
+```sh
+curl -X POST http://localhost:8080/upload \
+ -F "file=@/Users/appleboy/test.zip" \
+ -H "Content-Type: multipart/form-data"
+```
diff --git a/src/content/docs/zh-tw/docs/examples/using-basicauth-middleware.md b/src/content/docs/zh-tw/docs/examples/using-basicauth-middleware.md
new file mode 100644
index 000000000..cc68db4a0
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/using-basicauth-middleware.md
@@ -0,0 +1,41 @@
+---
+title: "Using BasicAuth middleware"
+
+---
+
+```go
+// simulate some private data
+var secrets = gin.H{
+ "foo": gin.H{"email": "foo@bar.com", "phone": "123433"},
+ "austin": gin.H{"email": "austin@example.com", "phone": "666"},
+ "lena": gin.H{"email": "lena@guapa.com", "phone": "523443"},
+}
+
+func main() {
+ r := gin.Default()
+
+ // Group using gin.BasicAuth() middleware
+ // gin.Accounts is a shortcut for map[string]string
+ authorized := r.Group("/admin", gin.BasicAuth(gin.Accounts{
+ "foo": "bar",
+ "austin": "1234",
+ "lena": "hello2",
+ "manu": "4321",
+ }))
+
+ // /admin/secrets endpoint
+ // hit "localhost:8080/admin/secrets
+ authorized.GET("/secrets", func(c *gin.Context) {
+ // get user, it was set by the BasicAuth middleware
+ user := c.MustGet(gin.AuthUserKey).(string)
+ if secret, ok := secrets[user]; ok {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": secret})
+ } else {
+ c.JSON(http.StatusOK, gin.H{"user": user, "secret": "NO SECRET :("})
+ }
+ })
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/examples/using-middleware.md b/src/content/docs/zh-tw/docs/examples/using-middleware.md
new file mode 100644
index 000000000..5fc4154db
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/using-middleware.md
@@ -0,0 +1,43 @@
+---
+title: "Using middleware"
+
+---
+
+```go
+func main() {
+ // Creates a router without any middleware by default
+ r := gin.New()
+
+ // Global middleware
+ // Logger middleware will write the logs to gin.DefaultWriter even if you set with GIN_MODE=release.
+ // By default gin.DefaultWriter = os.Stdout
+ r.Use(gin.Logger())
+
+ // Recovery middleware recovers from any panics and writes a 500 if there was one.
+ r.Use(gin.Recovery())
+
+ // Per route middleware, you can add as many as you desire.
+ r.GET("/benchmark", MyBenchLogger(), benchEndpoint)
+
+ // Authorization group
+ // authorized := r.Group("/", AuthRequired())
+ // exactly the same as:
+ authorized := r.Group("/")
+ // per group middleware! in this case we use the custom created
+ // AuthRequired() middleware just in the "authorized" group.
+ authorized.Use(AuthRequired())
+ {
+ authorized.POST("/login", loginEndpoint)
+ authorized.POST("/submit", submitEndpoint)
+ authorized.POST("/read", readEndpoint)
+
+ // nested group
+ testing := authorized.Group("testing")
+ testing.GET("/analytics", analyticsEndpoint)
+ }
+
+ // Listen and serve on 0.0.0.0:8080
+ r.Run(":8080")
+}
+```
+
diff --git a/src/content/docs/zh-tw/docs/examples/without-middleware.md b/src/content/docs/zh-tw/docs/examples/without-middleware.md
new file mode 100644
index 000000000..6ef54bda0
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/without-middleware.md
@@ -0,0 +1,17 @@
+---
+title: "Without middleware by default"
+
+---
+
+Use
+
+```go
+r := gin.New()
+```
+
+instead of
+
+```go
+// Default With the Logger and Recovery middleware already attached
+r := gin.Default()
+```
diff --git a/src/content/docs/zh-tw/docs/examples/write-log.md b/src/content/docs/zh-tw/docs/examples/write-log.md
new file mode 100644
index 000000000..759423de4
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/examples/write-log.md
@@ -0,0 +1,25 @@
+---
+title: "How to write log file"
+
+---
+
+```go
+func main() {
+ // Disable Console Color, you don't need console color when writing the logs to file.
+ gin.DisableConsoleColor()
+
+ // Logging to a file.
+ f, _ := os.Create("gin.log")
+ gin.DefaultWriter = io.MultiWriter(f)
+
+ // Use the following code if you need to write the logs to file and console at the same time.
+ // gin.DefaultWriter = io.MultiWriter(f, os.Stdout)
+
+ router := gin.Default()
+ router.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+
+ router.Run(":8080")
+}
+```
diff --git a/src/content/docs/zh-tw/docs/faq/index.md b/src/content/docs/zh-tw/docs/faq/index.md
new file mode 100644
index 000000000..ad348f11f
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/faq/index.md
@@ -0,0 +1,9 @@
+---
+title: "FAQ"
+
+sidebar:
+ order: 9
+---
+
+TODO: record some frequently asked question from GitHub Issue tab.
+
diff --git a/src/content/docs/zh-tw/docs/features/index.md b/src/content/docs/zh-tw/docs/features/index.md
new file mode 100644
index 000000000..c471f7f44
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/features/index.md
@@ -0,0 +1,18 @@
+---
+title: "特色"
+
+sidebar:
+ order: 4
+---
+
+##### Gin v1 穩定功能
+
+- 零配置的路由器。
+
+- 仍然是最快的 HTTP 路由器和 Web 框架。從路由到紀錄。
+
+- 完整的單元測試套件。
+
+- 經過實戰測試。
+
+- API frozen。新版本發布不會破壞你的程式碼。
diff --git a/src/content/docs/zh-tw/docs/index.md b/src/content/docs/zh-tw/docs/index.md
new file mode 100644
index 000000000..4fd882caf
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/index.md
@@ -0,0 +1,21 @@
+---
+title: "文件"
+linkTitle: "文件"
+sidebar:
+ order: 1
+---
+
+## Gin 是什麼?
+
+Gin 是一個使用 Go (Golang) 寫的 HTTP Web 框架。它提供類似 Martini 的 API,但擁有更好的效能——速度快上了 40 倍。如果你需要震撼性的效能,給自己來點 Gin 吧。
+
+## 如何使用 Gin?
+
+我們提供了一些 API 使用 [範例](https://github.com/gin-gonic/examples) 並列出一些知名的 [Gin 使用者](./users).
+
+## 如何對 Gin 做出貢獻?
+
+* 在論壇上幫助人們
+* 告訴我們你使用 Gin 的成功故事
+* 告訴我們如何可以改進 Gin 並且幫助我們達成
+* 貢獻現有程式庫
diff --git a/src/content/docs/zh-tw/docs/introduction/index.md b/src/content/docs/zh-tw/docs/introduction/index.md
new file mode 100644
index 000000000..2ff71a640
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/introduction/index.md
@@ -0,0 +1,46 @@
+---
+title: "介紹"
+
+sidebar:
+ order: 1
+---
+
+Gin 是一個使用 Go (Golang) 寫的 Web 框架。它提供類似 Martini 的 API,但擁有更好的效能,感謝 [httprouter](https://github.com/julienschmidt/httprouter),速度快上了 40 倍。如果你需要效能和高生產力,你將會愛上 Gin。
+
+在這個章節當中,我們會介紹什麼是 Gin,它解決了什麼問題,還有他如何幫助你的專案。
+
+或者,如果你已經準備好要在你的專案中使用 Gin,請前往 [快速入門](/quickstart)。
+
+## 特色
+
+### 快速
+
+以 Radix tree 為基礎的路由,記憶體使用量小。沒有使用 reflection。可預測的 API 效能。
+
+### 支援 Middleware
+
+傳入的請求可以由一系列的 Middleware 和最終行為來處理。例如:Logger、Authorization、GZIP,最後送訊息到資料庫。
+
+### Crash-free
+
+Gin 可以攔截發生在 HTTP 請求期間的 panic 並回復它。這樣的話,伺服器將永遠是可用狀態。舉例來說,它可以選擇回報 panic 給 Sentry。
+
+### JSON 驗證
+
+Gin 可以剖析和驗證請求裡的 JSON,例如檢查必要值。
+
+### 路由群組
+
+更好地組織你的路由。需不需要授權或不同的 API 版本。此外,這些群組可以無限制地巢狀嵌套而不會降低效能。
+
+### 錯誤管理
+
+Gin 提供了一種方便的方法來收集 HTTP 請求期間發生的所有錯誤。 最後, Middleware 可以將它們寫入日誌檔案、寫入資料庫,並透過網路傳送。
+
+### 內建渲染
+
+Gin 提供易使用的 API 來渲染 JSON、XML 和 HTML。
+
+### 可擴展性
+
+建立新的 Middleware 很簡單,直接查看範例程式碼即可。
diff --git a/src/content/docs/zh-tw/docs/jsoniter/index.md b/src/content/docs/zh-tw/docs/jsoniter/index.md
new file mode 100644
index 000000000..abc91fd95
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/jsoniter/index.md
@@ -0,0 +1,14 @@
+---
+title: "Jsoniter"
+
+sidebar:
+ order: 5
+---
+
+#### Build with [jsoniter](https://github.com/json-iterator/go)
+
+Gin uses `encoding/json` as default json package but you can change to [jsoniter](https://github.com/json-iterator/go) by build from other tags.
+
+```sh
+$ go build -tags=jsoniter .
+```
diff --git a/src/content/docs/zh-tw/docs/quickstart/index.md b/src/content/docs/zh-tw/docs/quickstart/index.md
new file mode 100644
index 000000000..166cfc4fe
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/quickstart/index.md
@@ -0,0 +1,105 @@
+---
+title: "快速入門"
+
+sidebar:
+ order: 2
+---
+
+- [需求](#需求)
+- [安裝](#安裝)
+- [開始使用](#開始使用)
+
+## 需求
+
+- Go 1.16 及更新版本
+
+## 安裝
+
+安裝 Gin 套件前, 你需要先安裝 Go 和準備好你的工作環境。
+
+1. 下載並安裝
+
+```sh
+$ go get -u github.com/gin-gonic/gin
+```
+
+2. 在程式碼當中匯入套件
+
+```go
+import "github.com/gin-gonic/gin"
+```
+
+3. (可選的)如果你想要使用像是 `http.StatusOK` 的常數,你會需要匯入 `net/http` 套件
+
+```go
+import "net/http"
+```
+
+### 使用 vendor 工具像是 [Govendor](https://github.com/kardianos/govendor)
+
+1. `go get` govendor
+
+```sh
+$ go get github.com/kardianos/govendor
+```
+
+2. 新增你的專案資料夾並 `cd` 進入
+
+```sh
+$ mkdir -p $GOPATH/src/github.com/myusername/project && cd "$_"
+ ```
+
+3. Vendor init 專案並加入 gin
+
+```sh
+$ govendor init
+$ govendor fetch github.com/gin-gonic/gin@v1.3
+```
+
+4. 複製範本到你的專案
+
+```sh
+$ curl https://raw.githubusercontent.com/gin-gonic/examples/master/basic/main.go > main.go
+```
+
+5. 執行你的專案
+
+```sh
+$ go run main.go
+```
+
+## 開始使用
+
+> 不確定如何寫和執行 Go 程式碼? [Click here](https://golang.org/doc/code.html).
+
+第一步,新增一個檔案 `example.go`:
+
+```sh
+# assume the following codes in example.go file
+$ touch example.go
+```
+
+接下來,將下列程式碼放進 `example.go`:
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+func main() {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.JSON(200, gin.H{
+ "message": "pong",
+ })
+ })
+ r.Run() // listen and serve on 0.0.0.0:8080
+}
+```
+
+然後,你可以透過 `go run example.go` 來執行這個程式碼:
+
+```shell
+# run example.go and visit 0.0.0.0:8080/ping on browser
+$ go run example.go
+```
diff --git a/src/content/docs/zh-tw/docs/testing/index.md b/src/content/docs/zh-tw/docs/testing/index.md
new file mode 100644
index 000000000..eab2f8d7e
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/testing/index.md
@@ -0,0 +1,90 @@
+---
+title: "測試"
+
+sidebar:
+ order: 7
+---
+
+##### 如何為 Gin 寫測試案例?
+
+傾向使用 `net/http/httptest` 套件來做 HTTP 測試。
+
+```go
+package main
+
+import "github.com/gin-gonic/gin"
+
+type User struct {
+ Username string `json:"username"`
+ Gender string `json:"gender"`
+}
+
+func setupRouter() *gin.Engine {
+ r := gin.Default()
+ r.GET("/ping", func(c *gin.Context) {
+ c.String(200, "pong")
+ })
+ return r
+}
+
+func postUser(r *gin.Engine) *gin.Engine {
+ r.POST("/user/add", func(c *gin.Context) {
+ var user User
+ c.BindJSON(&user)
+ c.JSON(200, user)
+ })
+ return r
+}
+
+func main() {
+ r := setupRouter()
+ r = postUser(r)
+ r.Run(":8080")
+}
+```
+
+為上面程式碼所寫的測試:
+
+```go
+package main
+
+import (
+ "net/http"
+ "net/http/httptest"
+ "testing"
+
+ "github.com/stretchr/testify/assert"
+)
+
+func TestPingRoute(t *testing.T) {
+ router := setupRouter()
+
+ w := httptest.NewRecorder()
+ req, _ := http.NewRequest("GET", "/ping", nil)
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ assert.Equal(t, "pong", w.Body.String())
+}
+
+// Test for POST /user/add
+func TestPostUser(t *testing.T) {
+ router := setupRouter()
+ router = postUser(router)
+
+ w := httptest.NewRecorder()
+
+ // Create an example user for testing
+ exampleUser := User{
+ Username: "test_name",
+ Gender: "male",
+ }
+ userJson, _ := json.Marshal(exampleUser)
+ req, _ := http.NewRequest("POST", "/user/add", strings.NewReader(string(userJson)))
+ router.ServeHTTP(w, req)
+
+ assert.Equal(t, 200, w.Code)
+ // Compare the response body with the json data of exampleUser
+ assert.Equal(t, string(userJson), w.Body.String())
+}
+```
diff --git a/src/content/docs/zh-tw/docs/users/index.md b/src/content/docs/zh-tw/docs/users/index.md
new file mode 100644
index 000000000..18c9123be
--- /dev/null
+++ b/src/content/docs/zh-tw/docs/users/index.md
@@ -0,0 +1,22 @@
+---
+title: "使用者"
+
+sidebar:
+ order: 8
+---
+
+##### Awesome project lists using [Gin](https://github.com/gin-gonic/gin) web framework:
+
+* [gorush](https://github.com/appleboy/gorush): A push notification server written in Go.
+
+* [fnproject](https://github.com/fnproject/fn): The container native, cloud agnostic serverless platform.
+
+* [photoprism](https://github.com/photoprism/photoprism): Personal photo management powered by Go and Google TensorFlow.
+
+* [krakend](https://github.com/devopsfaith/krakend): Ultra performant API Gateway with middlewares.
+
+* [picfit](https://github.com/thoas/picfit): An image resizing server written in Go.
+
+* [gotify](https://github.com/gotify/server): A simple server for sending and receiving messages in real-time per web socket.
+
+* [cds](https://github.com/ovh/cds): Enterprise-Grade Continuous Delivery & DevOps Automation Open Source Platform.
diff --git a/src/content/docs/zh-tw/index.mdx b/src/content/docs/zh-tw/index.mdx
new file mode 100644
index 000000000..40ccd24a3
--- /dev/null
+++ b/src/content/docs/zh-tw/index.mdx
@@ -0,0 +1,51 @@
+---
+title: Gin Web Framework
+description: The fastest full-featured web framework for Go. Crystal clear.
+template: splash
+hero:
+ tagline: Go語言最快的全功能Web框架。晶瑩剔透。
+ image:
+ file: ../../../assets/gin.png
+ actions:
+ - text: 了解更多
+ link: /zh-tw/docs/
+ icon: right-arrow
+ - text: 下載
+ link: https://github.com/gin-gonic/gin/releases
+ icon: external
+ variant: minimal
+---
+
+import { Card, CardGrid } from '@astrojs/starlight/components';
+
+## 什麼是Gin?
+
+Gin是一個使用Go語言開發的Web框架。 它提供類似Martini的API,但性能更佳,速度提升高達40倍。 如果你是性能和高效的追求者, 你會愛上 Gin。
+
+
+
+ 基於 Radix 樹的路由,小內存佔用。沒有反射。可預測的 API 性能。
+
+
+ 傳入的 HTTP 請求可以由一系列中間件和最終操作來處理。例如:Logger,Authorization,GZIP,最終操作 DB。
+
+
+ Gin 可以 catch 一個發生在 HTTP 請求中的 panic 並 recover 它。這樣,你的服務器將始終可用。例如,你可以向 Sentry 報告這個 panic!
+
+
+ Gin 可以解析並驗證請求的 JSON,例如檢查所需值的存在。
+
+
+ Gin幫助您更好地組織您的路由,例如,按照需要授權和不需要授權和不同API版本進行分組。此外,路由分組可以無限嵌套而不降低性能。
+
+
+ Gin 提供了一種方便的方法來收集 HTTP 請求期間發生的所有錯誤。最終,中間件可以將它們寫入日誌文件,數據庫並通過網絡發送。
+
+
+ Gin 為 JSON,XML 和 HTML 渲染提供了易於使用的 API。
+
+
+ 新建一個中間件非常簡單,去查看[示例代碼](https://gin-gonic.com/zh-tw/docs/examples/using-middleware/)吧。
+
+
+
\ No newline at end of file
diff --git a/src/env.d.ts b/src/env.d.ts
new file mode 100644
index 000000000..acef35f17
--- /dev/null
+++ b/src/env.d.ts
@@ -0,0 +1,2 @@
+///
+///
diff --git a/src/styles/custom.css b/src/styles/custom.css
new file mode 100644
index 000000000..871592f50
--- /dev/null
+++ b/src/styles/custom.css
@@ -0,0 +1,37 @@
+/*
+
+Add styles or override variables from the theme here.
+
+*/
+
+:root,
+::backdrop {
+ /* Colors (dark mode) */
+
+ --gin-blue: hsl(215, 69%, 52%);
+
+ --sl-hue-blue: 215;
+ --sl-color-blue-low: hsl(var(--sl-hue-blue), 54%, 20%);
+ --sl-color-blue: hsl(var(--sl-hue-blue), 100%, 60%);
+ --sl-color-blue-high: hsl(var(--sl-hue-blue), 100%, 87%);
+
+ --sl-color-accent-low: hsl(204, 54%, 20%);
+ --sl-color-accent: hsl(204, 100%, 60%);
+ --sl-color-accent-high: hsl(204, 100%, 85%);
+
+ --sl-line-height: 1.75;
+ --sl-line-height-headings: 1.2;
+}
+
+:root[data-theme='light'],
+[data-theme='light'] ::backdrop {
+ /* Colours (light mode) */
+
+ --sl-color-blue-high: hsl(var(--sl-hue-blue), 80%, 30%);
+ --sl-color-blue: hsl(var(--sl-hue-blue), 90%, 60%);
+ --sl-color-blue-low: hsl(var(--sl-hue-blue), 88%, 90%);
+
+ --sl-color-accent-high: hsl(215, 80%, 30%);
+ --sl-color-accent: hsl(215, 90%, 60%);
+ --sl-color-accent-low: hsl(215, 88%, 90%);
+}
\ No newline at end of file
diff --git a/tsconfig.json b/tsconfig.json
new file mode 100644
index 000000000..77da9dd00
--- /dev/null
+++ b/tsconfig.json
@@ -0,0 +1,3 @@
+{
+ "extends": "astro/tsconfigs/strict"
+}
\ No newline at end of file