- commit
- 13c145a
- parent
- cfd74b9
- author
- Eric Bower
- date
- 2022-08-01 20:02:02 +0000 UTC
refactor: abstract api functions into shared I also updated the custom domain logic to apply to all services. Each service has its own special TXT string, e.g. `_prose`, `_lists`, `_pastes` which is based on `cfg.Space`.
7 files changed,
+169,
-259
+21,
-95
1@@ -4,7 +4,6 @@ import (
2 "bytes"
3 "fmt"
4 "html/template"
5- "io/ioutil"
6 "net/http"
7 "net/url"
8 "strconv"
9@@ -19,10 +18,6 @@ import (
10 "golang.org/x/exp/slices"
11 )
12
13-type PageData struct {
14- Site shared.SitePageData
15-}
16-
17 type PostItemData struct {
18 URL template.URL
19 BlogURL template.URL
20@@ -74,50 +69,6 @@ type TransparencyPageData struct {
21 Analytics *db.Analytics
22 }
23
24-func isRequestTrackable(r *http.Request) bool {
25- return true
26-}
27-
28-func renderTemplate(cfg *shared.ConfigSite, templates []string) (*template.Template, error) {
29- files := make([]string, len(templates))
30- copy(files, templates)
31- files = append(
32- files,
33- cfg.StaticPath("html/footer.partial.tmpl"),
34- cfg.StaticPath("html/marketing-footer.partial.tmpl"),
35- cfg.StaticPath("html/base.layout.tmpl"),
36- )
37-
38- ts, err := template.ParseFiles(files...)
39- if err != nil {
40- return nil, err
41- }
42- return ts, nil
43-}
44-
45-func createPageHandler(fname string) http.HandlerFunc {
46- return func(w http.ResponseWriter, r *http.Request) {
47- logger := shared.GetLogger(r)
48- cfg := shared.GetCfg(r)
49- ts, err := renderTemplate(cfg, []string{cfg.StaticPath(fname)})
50-
51- if err != nil {
52- logger.Error(err)
53- http.Error(w, err.Error(), http.StatusInternalServerError)
54- return
55- }
56-
57- data := PageData{
58- Site: *cfg.GetSiteData(),
59- }
60- err = ts.Execute(w, data)
61- if err != nil {
62- logger.Error(err)
63- http.Error(w, err.Error(), http.StatusInternalServerError)
64- }
65- }
66-}
67-
68 type HeaderTxt struct {
69 Title string
70 Bio string
71@@ -131,18 +82,12 @@ type ReadmeTxt struct {
72 Items []*pkg.ListItem
73 }
74
75-func GetUsernameFromRequest(r *http.Request) string {
76- subdomain := shared.GetSubdomain(r)
77- cfg := shared.GetCfg(r)
78-
79- if !cfg.IsSubdomains() || subdomain == "" {
80- return shared.GetField(r, 0)
81- }
82- return subdomain
83+func isRequestTrackable(r *http.Request) bool {
84+ return true
85 }
86
87 func blogHandler(w http.ResponseWriter, r *http.Request) {
88- username := GetUsernameFromRequest(r)
89+ username := shared.GetUsernameFromRequest(r)
90 dbpool := shared.GetDB(r)
91 logger := shared.GetLogger(r)
92 cfg := shared.GetCfg(r)
93@@ -166,7 +111,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
94 onSubdomain := cfg.IsSubdomains() && strings.Contains(hostDomain, appDomain)
95 withUserName := (!onSubdomain && hostDomain == appDomain) || !cfg.IsCustomdomains()
96
97- ts, err := renderTemplate(cfg, []string{
98+ ts, err := shared.RenderTemplate(cfg, []string{
99 cfg.StaticPath("html/blog.page.tmpl"),
100 cfg.StaticPath("html/list.partial.tmpl"),
101 })
102@@ -251,7 +196,7 @@ func GetBlogName(username string) string {
103 }
104
105 func postHandler(w http.ResponseWriter, r *http.Request) {
106- username := GetUsernameFromRequest(r)
107+ username := shared.GetUsernameFromRequest(r)
108 subdomain := shared.GetSubdomain(r)
109 cfg := shared.GetCfg(r)
110
111@@ -339,7 +284,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
112 }
113 }
114
115- ts, err := renderTemplate(cfg, []string{
116+ ts, err := shared.RenderTemplate(cfg, []string{
117 cfg.StaticPath("html/post.page.tmpl"),
118 cfg.StaticPath("html/list.partial.tmpl"),
119 })
120@@ -402,7 +347,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
121 return
122 }
123
124- ts, err := renderTemplate(cfg, []string{
125+ ts, err := shared.RenderTemplate(cfg, []string{
126 cfg.StaticPath("html/read.page.tmpl"),
127 })
128
129@@ -448,7 +393,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
130 }
131
132 func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
133- username := GetUsernameFromRequest(r)
134+ username := shared.GetUsernameFromRequest(r)
135 dbpool := shared.GetDB(r)
136 logger := shared.GetLogger(r)
137 cfg := shared.GetCfg(r)
138@@ -619,47 +564,28 @@ func rssHandler(w http.ResponseWriter, r *http.Request) {
139 }
140 }
141
142-func serveFile(file string, contentType string) http.HandlerFunc {
143- return func(w http.ResponseWriter, r *http.Request) {
144- logger := shared.GetLogger(r)
145- cfg := shared.GetCfg(r)
146-
147- contents, err := ioutil.ReadFile(cfg.StaticPath(fmt.Sprintf("public/%s", file)))
148- if err != nil {
149- logger.Error(err)
150- http.Error(w, "file not found", 404)
151- }
152-
153- w.Header().Add("Content-Type", contentType)
154-
155- _, err = w.Write(contents)
156- if err != nil {
157- logger.Error(err)
158- }
159- }
160-}
161-
162 func createStaticRoutes() []shared.Route {
163 return []shared.Route{
164- shared.NewRoute("GET", "/main.css", serveFile("main.css", "text/css")),
165- shared.NewRoute("GET", "/card.png", serveFile("card.png", "image/png")),
166- shared.NewRoute("GET", "/favicon-16x16.png", serveFile("favicon-16x16.png", "image/png")),
167- shared.NewRoute("GET", "/favicon-32x32.png", serveFile("favicon-32x32.png", "image/png")),
168- shared.NewRoute("GET", "/apple-touch-icon.png", serveFile("apple-touch-icon.png", "image/png")),
169- shared.NewRoute("GET", "/favicon.ico", serveFile("favicon.ico", "image/x-icon")),
170- shared.NewRoute("GET", "/robots.txt", serveFile("robots.txt", "text/plain")),
171+ shared.NewRoute("GET", "/main.css", shared.ServeFile("main.css", "text/css")),
172+ shared.NewRoute("GET", "/card.png", shared.ServeFile("card.png", "image/png")),
173+ shared.NewRoute("GET", "/favicon-16x16.png", shared.ServeFile("favicon-16x16.png", "image/png")),
174+ shared.NewRoute("GET", "/favicon-32x32.png", shared.ServeFile("favicon-32x32.png", "image/png")),
175+ shared.NewRoute("GET", "/apple-touch-icon.png", shared.ServeFile("apple-touch-icon.png", "image/png")),
176+ shared.NewRoute("GET", "/favicon.ico", shared.ServeFile("favicon.ico", "image/x-icon")),
177+ shared.NewRoute("GET", "/robots.txt", shared.ServeFile("robots.txt", "text/plain")),
178 }
179 }
180
181 func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
182 routes := []shared.Route{
183- shared.NewRoute("GET", "/", createPageHandler("html/marketing.page.tmpl")),
184- shared.NewRoute("GET", "/spec", createPageHandler("html/spec.page.tmpl")),
185- shared.NewRoute("GET", "/ops", createPageHandler("html/ops.page.tmpl")),
186- shared.NewRoute("GET", "/privacy", createPageHandler("html/privacy.page.tmpl")),
187- shared.NewRoute("GET", "/help", createPageHandler("html/help.page.tmpl")),
188+ shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
189+ shared.NewRoute("GET", "/spec", shared.CreatePageHandler("html/spec.page.tmpl")),
190+ shared.NewRoute("GET", "/ops", shared.CreatePageHandler("html/ops.page.tmpl")),
191+ shared.NewRoute("GET", "/privacy", shared.CreatePageHandler("html/privacy.page.tmpl")),
192+ shared.NewRoute("GET", "/help", shared.CreatePageHandler("html/help.page.tmpl")),
193 shared.NewRoute("GET", "/transparency", transparencyHandler),
194 shared.NewRoute("GET", "/read", readHandler),
195+ shared.NewRoute("GET", "/check", shared.CheckHandler),
196 }
197
198 routes = append(
+1,
-1
1@@ -53,7 +53,7 @@ func createPageHandler(fname string) gemini.HandlerFunc {
2 return
3 }
4
5- data := lists.PageData{
6+ data := shared.PageData{
7 Site: *cfg.GetSiteData(),
8 }
9 err = ts.Execute(w, data)
+11,
-60
1@@ -61,46 +61,6 @@ type TransparencyPageData struct {
2 Analytics *db.Analytics
3 }
4
5-func renderTemplate(cfg *shared.ConfigSite, templates []string) (*template.Template, error) {
6- files := make([]string, len(templates))
7- copy(files, templates)
8- files = append(
9- files,
10- cfg.StaticPath("html/footer.partial.tmpl"),
11- cfg.StaticPath("html/marketing-footer.partial.tmpl"),
12- cfg.StaticPath("html/base.layout.tmpl"),
13- )
14-
15- ts, err := template.ParseFiles(files...)
16- if err != nil {
17- return nil, err
18- }
19- return ts, nil
20-}
21-
22-func createPageHandler(fname string) http.HandlerFunc {
23- return func(w http.ResponseWriter, r *http.Request) {
24- logger := shared.GetLogger(r)
25- cfg := shared.GetCfg(r)
26- ts, err := renderTemplate(cfg, []string{cfg.StaticPath(fname)})
27-
28- if err != nil {
29- logger.Error(err)
30- http.Error(w, err.Error(), http.StatusInternalServerError)
31- return
32- }
33-
34- data := PageData{
35- Site: *cfg.GetSiteData(),
36- }
37- err = ts.Execute(w, data)
38- if err != nil {
39- logger.Error(err)
40- http.Error(w, err.Error(), http.StatusInternalServerError)
41- }
42- }
43-}
44-
45 type Link struct {
46 URL string
47 Text string
48@@ -113,18 +73,8 @@ type HeaderTxt struct {
49 HasLinks bool
50 }
51
52-func GetUsernameFromRequest(r *http.Request) string {
53- subdomain := shared.GetSubdomain(r)
54- cfg := shared.GetCfg(r)
55-
56- if !cfg.IsSubdomains() || subdomain == "" {
57- return shared.GetField(r, 0)
58- }
59- return subdomain
60-}
61-
62 func blogHandler(w http.ResponseWriter, r *http.Request) {
63- username := GetUsernameFromRequest(r)
64+ username := shared.GetUsernameFromRequest(r)
65 dbpool := shared.GetDB(r)
66 logger := shared.GetLogger(r)
67 cfg := shared.GetCfg(r)
68@@ -148,7 +98,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
69 onSubdomain := cfg.IsSubdomains() && strings.Contains(hostDomain, appDomain)
70 withUserName := (!onSubdomain && hostDomain == appDomain) || !cfg.IsCustomdomains()
71
72- ts, err := renderTemplate(cfg, []string{
73+ ts, err := shared.RenderTemplate(cfg, []string{
74 cfg.StaticPath("html/blog.page.tmpl"),
75 })
76
77@@ -207,7 +157,7 @@ func GetBlogName(username string) string {
78 }
79
80 func postHandler(w http.ResponseWriter, r *http.Request) {
81- username := GetUsernameFromRequest(r)
82+ username := shared.GetUsernameFromRequest(r)
83 subdomain := shared.GetSubdomain(r)
84 cfg := shared.GetCfg(r)
85
86@@ -268,7 +218,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
87 }
88 }
89
90- ts, err := renderTemplate(cfg, []string{
91+ ts, err := shared.RenderTemplate(cfg, []string{
92 cfg.StaticPath("html/post.page.tmpl"),
93 })
94
95@@ -284,7 +234,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
96 }
97
98 func postHandlerRaw(w http.ResponseWriter, r *http.Request) {
99- username := GetUsernameFromRequest(r)
100+ username := shared.GetUsernameFromRequest(r)
101 subdomain := shared.GetSubdomain(r)
102 cfg := shared.GetCfg(r)
103
104@@ -388,12 +338,13 @@ func createStaticRoutes() []shared.Route {
105
106 func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
107 routes := []shared.Route{
108- shared.NewRoute("GET", "/", createPageHandler("html/marketing.page.tmpl")),
109- shared.NewRoute("GET", "/spec", createPageHandler("html/spec.page.tmpl")),
110- shared.NewRoute("GET", "/ops", createPageHandler("html/ops.page.tmpl")),
111- shared.NewRoute("GET", "/privacy", createPageHandler("html/privacy.page.tmpl")),
112- shared.NewRoute("GET", "/help", createPageHandler("html/help.page.tmpl")),
113+ shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
114+ shared.NewRoute("GET", "/spec", shared.CreatePageHandler("html/spec.page.tmpl")),
115+ shared.NewRoute("GET", "/ops", shared.CreatePageHandler("html/ops.page.tmpl")),
116+ shared.NewRoute("GET", "/privacy", shared.CreatePageHandler("html/privacy.page.tmpl")),
117+ shared.NewRoute("GET", "/help", shared.CreatePageHandler("html/help.page.tmpl")),
118 shared.NewRoute("GET", "/transparency", transparencyHandler),
119+ shared.NewRoute("GET", "/check", shared.CheckHandler),
120 }
121
122 routes = append(
+27,
-100
1@@ -77,50 +77,6 @@ type TransparencyPageData struct {
2 Analytics *db.Analytics
3 }
4
5-func isRequestTrackable(r *http.Request) bool {
6- return true
7-}
8-
9-func renderTemplate(cfg *shared.ConfigSite, templates []string) (*template.Template, error) {
10- files := make([]string, len(templates))
11- copy(files, templates)
12- files = append(
13- files,
14- cfg.StaticPath("html/footer.partial.tmpl"),
15- cfg.StaticPath("html/marketing-footer.partial.tmpl"),
16- cfg.StaticPath("html/base.layout.tmpl"),
17- )
18-
19- ts, err := template.ParseFiles(files...)
20- if err != nil {
21- return nil, err
22- }
23- return ts, nil
24-}
25-
26-func createPageHandler(fname string) http.HandlerFunc {
27- return func(w http.ResponseWriter, r *http.Request) {
28- logger := shared.GetLogger(r)
29- cfg := shared.GetCfg(r)
30- ts, err := renderTemplate(cfg, []string{cfg.StaticPath(fname)})
31-
32- if err != nil {
33- logger.Error(err)
34- http.Error(w, err.Error(), http.StatusInternalServerError)
35- return
36- }
37-
38- data := PageData{
39- Site: *cfg.GetSiteData(),
40- }
41- err = ts.Execute(w, data)
42- if err != nil {
43- logger.Error(err)
44- http.Error(w, err.Error(), http.StatusInternalServerError)
45- }
46- }
47-}
48-
49 type Link struct {
50 URL string
51 Text string
52@@ -138,18 +94,24 @@ type ReadmeTxt struct {
53 Contents template.HTML
54 }
55
56-func GetUsernameFromRequest(r *http.Request) string {
57- subdomain := shared.GetSubdomain(r)
58- cfg := shared.GetCfg(r)
59-
60- if !cfg.IsSubdomains() || subdomain == "" {
61- return shared.GetField(r, 0)
62+func GetPostTitle(post *db.Post) string {
63+ if post.Description == "" {
64+ return post.Title
65 }
66- return subdomain
67+
68+ return fmt.Sprintf("%s: %s", post.Title, post.Description)
69+}
70+
71+func GetBlogName(username string) string {
72+ return fmt.Sprintf("%s's blog", username)
73+}
74+
75+func isRequestTrackable(r *http.Request) bool {
76+ return true
77 }
78
79 func blogStyleHandler(w http.ResponseWriter, r *http.Request) {
80- username := GetUsernameFromRequest(r)
81+ username := shared.GetUsernameFromRequest(r)
82 dbpool := shared.GetDB(r)
83 logger := shared.GetLogger(r)
84 cfg := shared.GetCfg(r)
85@@ -177,7 +139,7 @@ func blogStyleHandler(w http.ResponseWriter, r *http.Request) {
86 }
87
88 func blogHandler(w http.ResponseWriter, r *http.Request) {
89- username := GetUsernameFromRequest(r)
90+ username := shared.GetUsernameFromRequest(r)
91 dbpool := shared.GetDB(r)
92 logger := shared.GetLogger(r)
93 cfg := shared.GetCfg(r)
94@@ -201,7 +163,7 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
95 onSubdomain := cfg.IsSubdomains() && strings.Contains(hostDomain, appDomain)
96 withUserName := (!onSubdomain && hostDomain == appDomain) || !cfg.IsCustomdomains()
97
98- ts, err := renderTemplate(cfg, []string{
99+ ts, err := shared.RenderTemplate(cfg, []string{
100 cfg.StaticPath("html/blog.page.tmpl"),
101 })
102
103@@ -270,20 +232,8 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
104 }
105 }
106
107-func GetPostTitle(post *db.Post) string {
108- if post.Description == "" {
109- return post.Title
110- }
111-
112- return fmt.Sprintf("%s: %s", post.Title, post.Description)
113-}
114-
115-func GetBlogName(username string) string {
116- return fmt.Sprintf("%s's blog", username)
117-}
118-
119 func postRawHandler(w http.ResponseWriter, r *http.Request) {
120- username := GetUsernameFromRequest(r)
121+ username := shared.GetUsernameFromRequest(r)
122 subdomain := shared.GetSubdomain(r)
123 cfg := shared.GetCfg(r)
124
125@@ -321,7 +271,7 @@ func postRawHandler(w http.ResponseWriter, r *http.Request) {
126 }
127
128 func postHandler(w http.ResponseWriter, r *http.Request) {
129- username := GetUsernameFromRequest(r)
130+ username := shared.GetUsernameFromRequest(r)
131 subdomain := shared.GetSubdomain(r)
132 cfg := shared.GetCfg(r)
133
134@@ -417,7 +367,7 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
135 logger.Infof("post not found %s/%s", username, slug)
136 }
137
138- ts, err := renderTemplate(cfg, []string{
139+ ts, err := shared.RenderTemplate(cfg, []string{
140 cfg.StaticPath("html/post.page.tmpl"),
141 })
142
143@@ -466,29 +416,6 @@ func transparencyHandler(w http.ResponseWriter, r *http.Request) {
144 }
145 }
146
147-func checkHandler(w http.ResponseWriter, r *http.Request) {
148- dbpool := shared.GetDB(r)
149- cfg := shared.GetCfg(r)
150-
151- if cfg.IsCustomdomains() {
152- hostDomain := r.URL.Query().Get("domain")
153- appDomain := strings.Split(cfg.ConfigCms.Domain, ":")[0]
154-
155- if !strings.Contains(hostDomain, appDomain) {
156- subdomain := shared.GetCustomDomain(hostDomain)
157- if subdomain != "" {
158- u, err := dbpool.FindUserForName(subdomain)
159- if u != nil && err == nil {
160- w.WriteHeader(http.StatusOK)
161- return
162- }
163- }
164- }
165- }
166-
167- w.WriteHeader(http.StatusNotFound)
168-}
169-
170 func readHandler(w http.ResponseWriter, r *http.Request) {
171 dbpool := shared.GetDB(r)
172 logger := shared.GetLogger(r)
173@@ -502,7 +429,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
174 return
175 }
176
177- ts, err := renderTemplate(cfg, []string{
178+ ts, err := shared.RenderTemplate(cfg, []string{
179 cfg.StaticPath("html/read.page.tmpl"),
180 })
181
182@@ -549,7 +476,7 @@ func readHandler(w http.ResponseWriter, r *http.Request) {
183 }
184
185 func rssBlogHandler(w http.ResponseWriter, r *http.Request) {
186- username := GetUsernameFromRequest(r)
187+ username := shared.GetUsernameFromRequest(r)
188 dbpool := shared.GetDB(r)
189 logger := shared.GetLogger(r)
190 cfg := shared.GetCfg(r)
191@@ -778,14 +705,14 @@ func createStaticRoutes() []shared.Route {
192
193 func createMainRoutes(staticRoutes []shared.Route) []shared.Route {
194 routes := []shared.Route{
195- shared.NewRoute("GET", "/", createPageHandler("html/marketing.page.tmpl")),
196- shared.NewRoute("GET", "/spec", createPageHandler("html/spec.page.tmpl")),
197- shared.NewRoute("GET", "/ops", createPageHandler("html/ops.page.tmpl")),
198- shared.NewRoute("GET", "/privacy", createPageHandler("html/privacy.page.tmpl")),
199- shared.NewRoute("GET", "/help", createPageHandler("html/help.page.tmpl")),
200+ shared.NewRoute("GET", "/", shared.CreatePageHandler("html/marketing.page.tmpl")),
201+ shared.NewRoute("GET", "/spec", shared.CreatePageHandler("html/spec.page.tmpl")),
202+ shared.NewRoute("GET", "/ops", shared.CreatePageHandler("html/ops.page.tmpl")),
203+ shared.NewRoute("GET", "/privacy", shared.CreatePageHandler("html/privacy.page.tmpl")),
204+ shared.NewRoute("GET", "/help", shared.CreatePageHandler("html/help.page.tmpl")),
205 shared.NewRoute("GET", "/transparency", transparencyHandler),
206 shared.NewRoute("GET", "/read", readHandler),
207- shared.NewRoute("GET", "/check", checkHandler),
208+ shared.NewRoute("GET", "/check", shared.CheckHandler),
209 }
210
211 routes = append(
1@@ -0,0 +1,102 @@
2+package shared
3+
4+import (
5+ "fmt"
6+ "html/template"
7+ "io/ioutil"
8+ "net/http"
9+ "strings"
10+)
11+
12+func CheckHandler(w http.ResponseWriter, r *http.Request) {
13+ dbpool := GetDB(r)
14+ cfg := GetCfg(r)
15+
16+ if cfg.IsCustomdomains() {
17+ hostDomain := r.URL.Query().Get("domain")
18+ appDomain := strings.Split(cfg.ConfigCms.Domain, ":")[0]
19+
20+ if !strings.Contains(hostDomain, appDomain) {
21+ subdomain := GetCustomDomain(hostDomain, cfg.Space)
22+ if subdomain != "" {
23+ u, err := dbpool.FindUserForName(subdomain)
24+ if u != nil && err == nil {
25+ w.WriteHeader(http.StatusOK)
26+ return
27+ }
28+ }
29+ }
30+ }
31+
32+ w.WriteHeader(http.StatusNotFound)
33+}
34+
35+func GetUsernameFromRequest(r *http.Request) string {
36+ subdomain := GetSubdomain(r)
37+ cfg := GetCfg(r)
38+
39+ if !cfg.IsSubdomains() || subdomain == "" {
40+ return GetField(r, 0)
41+ }
42+ return subdomain
43+}
44+
45+func ServeFile(file string, contentType string) http.HandlerFunc {
46+ return func(w http.ResponseWriter, r *http.Request) {
47+ logger := GetLogger(r)
48+ cfg := GetCfg(r)
49+
50+ contents, err := ioutil.ReadFile(cfg.StaticPath(fmt.Sprintf("public/%s", file)))
51+ if err != nil {
52+ logger.Error(err)
53+ http.Error(w, "file not found", 404)
54+ }
55+
56+ w.Header().Add("Content-Type", contentType)
57+
58+ _, err = w.Write(contents)
59+ if err != nil {
60+ logger.Error(err)
61+ }
62+ }
63+}
64+
65+func RenderTemplate(cfg *ConfigSite, templates []string) (*template.Template, error) {
66+ files := make([]string, len(templates))
67+ copy(files, templates)
68+ files = append(
69+ files,
70+ cfg.StaticPath("html/footer.partial.tmpl"),
71+ cfg.StaticPath("html/marketing-footer.partial.tmpl"),
72+ cfg.StaticPath("html/base.layout.tmpl"),
73+ )
74+
75+ ts, err := template.ParseFiles(files...)
76+ if err != nil {
77+ return nil, err
78+ }
79+ return ts, nil
80+}
81+
82+func CreatePageHandler(fname string) http.HandlerFunc {
83+ return func(w http.ResponseWriter, r *http.Request) {
84+ logger := GetLogger(r)
85+ cfg := GetCfg(r)
86+ ts, err := RenderTemplate(cfg, []string{cfg.StaticPath(fname)})
87+
88+ if err != nil {
89+ logger.Error(err)
90+ http.Error(w, err.Error(), http.StatusInternalServerError)
91+ return
92+ }
93+
94+ data := PageData{
95+ Site: *cfg.GetSiteData(),
96+ }
97+ err = ts.Execute(w, data)
98+ if err != nil {
99+ logger.Error(err)
100+ http.Error(w, err.Error(), http.StatusInternalServerError)
101+ }
102+ }
103+}
1@@ -17,6 +17,10 @@ type SitePageData struct {
2 Email string
3 }
4
5+type PageData struct {
6+ Site SitePageData
7+}
8+
9 type ConfigSite struct {
10 config.ConfigCms
11 config.ConfigURL
1@@ -45,7 +45,7 @@ func CreateServe(routes []Route, subdomainRoutes []Route, cfg *ConfigSite, dbpoo
2 curRoutes = subdomainRoutes
3 }
4 } else {
5- subdomain = GetCustomDomain(hostDomain)
6+ subdomain = GetCustomDomain(hostDomain, cfg.Space)
7 if subdomain != "" {
8 curRoutes = subdomainRoutes
9 }
10@@ -105,8 +105,8 @@ func GetSubdomain(r *http.Request) string {
11 return r.Context().Value(ctxSubdomainKey{}).(string)
12 }
13
14-func GetCustomDomain(host string) string {
15- records, err := net.LookupTXT(fmt.Sprintf("_prose.%s", host))
16+func GetCustomDomain(host string, space string) string {
17+ records, err := net.LookupTXT(fmt.Sprintf("_%s.%s", host, space))
18 if err != nil {
19 return ""
20 }