...
1 package middleware
2
3 import (
4 "bytes"
5 "fmt"
6 "html/template"
7 "net/http"
8 "path"
9 )
10
11
12 type RedocOpts struct {
13
14 BasePath string
15
16
17 Path string
18
19
20
21
22 SpecURL string
23
24
25 Title string
26
27
28 Template string
29
30
31
32
33 RedocURL string
34 }
35
36
37 func (r *RedocOpts) EnsureDefaults() {
38 common := toCommonUIOptions(r)
39 common.EnsureDefaults()
40 fromCommonToAnyOptions(common, r)
41
42
43 if r.RedocURL == "" {
44 r.RedocURL = redocLatest
45 }
46 if r.Template == "" {
47 r.Template = redocTemplate
48 }
49 }
50
51
52
53
54 func Redoc(opts RedocOpts, next http.Handler) http.Handler {
55 opts.EnsureDefaults()
56
57 pth := path.Join(opts.BasePath, opts.Path)
58 tmpl := template.Must(template.New("redoc").Parse(opts.Template))
59 assets := bytes.NewBuffer(nil)
60 if err := tmpl.Execute(assets, opts); err != nil {
61 panic(fmt.Errorf("cannot execute template: %w", err))
62 }
63
64 return serveUI(pth, assets.Bytes(), next)
65 }
66
67 const (
68 redocLatest = "https://cdn.jsdelivr.net/npm/redoc/bundles/redoc.standalone.js"
69 redocTemplate = `<!DOCTYPE html>
70 <html>
71 <head>
72 <title>{{ .Title }}</title>
73 <!-- needed for adaptive design -->
74 <meta charset="utf-8"/>
75 <meta name="viewport" content="width=device-width, initial-scale=1">
76 <link href="https://fonts.googleapis.com/css?family=Montserrat:300,400,700|Roboto:300,400,700" rel="stylesheet">
77
78 <!--
79 ReDoc doesn't change outer page styles
80 -->
81 <style>
82 body {
83 margin: 0;
84 padding: 0;
85 }
86 </style>
87 </head>
88 <body>
89 <redoc spec-url='{{ .SpecURL }}'></redoc>
90 <script src="{{ .RedocURL }}"> </script>
91 </body>
92 </html>
93 `
94 )
95
View as plain text