Skip to content

Commit f46ddb6

Browse files
committed
Add a Go server with Soy templates.
* convert (branched copy of) static HTML file to Soy format * use github.com/robfig/soy to render template server-side in Go * add `Makefile`, `go.mod`, `go.sum` for proper Go build * add `.gitignore` to ignore the built Go server
1 parent 3c39747 commit f46ddb6

File tree

7 files changed

+156
-18
lines changed

7 files changed

+156
-18
lines changed

.editorconfig

+28
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,17 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
115
root = true
216

317
[*]
@@ -6,3 +20,17 @@ indent_style = space
620
indent_size = 2
721
trim_trailing_whitespace = true
822
insert_final_newline = true
23+
24+
[BUILD,*.bzl]
25+
indent_style = space
26+
indent_size = 4
27+
28+
[*.py]
29+
indent_style = space
30+
indent_size = 4
31+
32+
[*.go]
33+
indent_style = tab
34+
35+
[Makefile,Makefile.*,*.mk]
36+
indent_style = tab

collections/docs-list/.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Binary built from dynamic/server/...
2+
server

collections/docs-list/Makefile

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Copyright 2020 Google LLC
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
VERB = @
16+
ifeq ($(VERBOSE),1)
17+
VERB =
18+
endif
19+
20+
GO_SRCS := $(shell find . -type f -name '*.go')
21+
GO_BIN = server
22+
23+
serve: $(GO_BIN)
24+
$(VERB) ./$(GO_BIN) -web-root dynamic/web
25+
26+
build: $(GO_BIN)
27+
28+
$(GO_BIN): $(GO_SRCS)
29+
$(VERB) go build ./...

collections/docs-list/dynamic/server/server.go

+39-3
Original file line numberDiff line numberDiff line change
@@ -15,20 +15,28 @@
1515
package main
1616

1717
import (
18+
"bytes"
1819
"flag"
1920
"fmt"
21+
"io"
2022
"log"
2123
"net/http"
2224
"os"
2325
"path"
26+
"strings"
27+
28+
"github.com/robfig/soy"
29+
"github.com/robfig/soy/data"
30+
"github.com/robfig/soy/soyhtml"
2431
)
2532

2633
var (
2734
cwd, _ = os.Getwd()
2835
webRoot = flag.String("web-root", cwd, "Root of the web file tree.")
2936
host = flag.String("host", "127.0.0.1", "By default, the server is only accessible via localhost. "+
3037
"Set to 0.0.0.0 or empty string to open to all.")
31-
port = flag.String("port", getEnvWithDefault("PORT", "8080"), "Port to listen on; $PORT env var overrides default value.")
38+
port = flag.String("port", getEnvWithDefault("PORT", "8080"), "Port to listen on; $PORT env var overrides default value.")
39+
tofu *soyhtml.Tofu = nil
3240
)
3341

3442
func getEnvWithDefault(varName, defaultValue string) string {
@@ -38,14 +46,42 @@ func getEnvWithDefault(varName, defaultValue string) string {
3846
return defaultValue
3947
}
4048

49+
func dispatchHandler(rw http.ResponseWriter, req *http.Request) {
50+
if strings.HasSuffix(req.URL.Path, ".css") || strings.HasSuffix(req.URL.Path, ".js") {
51+
staticFileHandler(rw, req)
52+
} else if req.URL.Path == "/" {
53+
indexHandler(rw, req)
54+
} else {
55+
http.Error(rw, fmt.Sprintf("Not found: %s", req.URL.Path), 404)
56+
}
57+
}
58+
4159
func indexHandler(rw http.ResponseWriter, req *http.Request) {
42-
log.Printf("Access log: %s %s", req.Method, req.URL.Path)
60+
log.Printf("Access [index]: %s %s", req.Method, req.URL.Path)
61+
var buf bytes.Buffer
62+
var m = make(data.Map)
63+
if err := tofu.Render(&buf, "home.index", m); err != nil {
64+
http.Error(rw, err.Error(), 500)
65+
return
66+
}
67+
io.Copy(rw, &buf)
68+
}
69+
70+
func staticFileHandler(rw http.ResponseWriter, req *http.Request) {
71+
log.Printf("Access [asset]: %s %s", req.Method, req.URL.Path)
4372
http.ServeFile(rw, req, path.Join(*webRoot, req.URL.Path))
4473
}
4574

4675
func main() {
4776
flag.Parse()
48-
http.HandleFunc("/", indexHandler)
77+
78+
compiledTofu, err := soy.NewBundle().WatchFiles(true).AddTemplateDir(*webRoot).CompileToTofu()
79+
if err != nil {
80+
log.Fatal("Error compiling Soy templates: ", err.Error())
81+
}
82+
tofu = compiledTofu
83+
84+
http.HandleFunc("/", dispatchHandler)
4985

5086
hostPort := fmt.Sprintf("%s:%s", *host, *port)
5187
log.Printf("Listening on %s", hostPort)

collections/docs-list/dynamic/web/index.html collections/docs-list/dynamic/web/index.soy

+18-15
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
1-
<!DOCTYPE html>
2-
<!--
3-
Copyright 2020 Google LLC
4-
5-
Licensed under the Apache License, Version 2.0 (the "License");
6-
you may not use this file except in compliance with the License.
7-
You may obtain a copy of the License at
1+
// Copyright 2020 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
814

9-
http://www.apache.org/licenses/LICENSE-2.0
15+
{namespace home}
1016

11-
Unless required by applicable law or agreed to in writing, software
12-
distributed under the License is distributed on an "AS IS" BASIS,
13-
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14-
See the License for the specific language governing permissions and
15-
limitations under the License.
16-
-->
17+
{template .index}
18+
<!DOCTYPE html>
1719
<html ng-app="DocsList">
1820
<head>
1921
<title>Docs list</title>
@@ -48,7 +50,7 @@ <h1>Docs list</h1>
4850
</td>
4951
<td align="left" class="pad">
5052
<span>
51-
<a ng-href="{{docUrl(doc)}}">{{doc.name}}</a>
53+
<a ng-href="{lb}{lb}docUrl(doc){rb}{rb}">{lb}{lb}doc.name{rb}{rb}</a>
5254
</span>
5355
</td>
5456
</div>
@@ -57,3 +59,4 @@ <h1>Docs list</h1>
5759

5860
</body>
5961
</html>
62+
{/template}

go.mod

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
module github.com/mbrukman/notebook
2+
3+
go 1.12
4+
5+
require github.com/robfig/soy v0.0.0-20200615133538-61beb7d40330

go.sum

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883 h1:bvNMNQO63//z+xNgfBlViaCIJKLlCJ6/fmUseuG0wVQ=
2+
github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
3+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
4+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
5+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
7+
github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
8+
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
9+
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
10+
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
11+
github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
12+
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
13+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
14+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
15+
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff h1:+6NUiITWwE5q1KO6SAfUX918c+Tab0+tGAM/mtdlUyA=
16+
github.com/robertkrimen/otto v0.0.0-20191219234010-c382bd3c16ff/go.mod h1:xvqspoSXJTIpemEonrMDFq6XzwHYYgToXWj5eRX1OtY=
17+
github.com/robfig/gettext v0.0.0-20200526193151-a093425df149 h1:UdCKxM6GqWm6z97V7jFUctMG5ZCIMYKROuJzamw5P+w=
18+
github.com/robfig/gettext v0.0.0-20200526193151-a093425df149/go.mod h1:5KSZdCir8kQ33UwFOeBzxIXDVCb7ine4/iCMiJ9D1oQ=
19+
github.com/robfig/soy v0.0.0-20200615133538-61beb7d40330 h1:zYPHxDtudtGkY3bOgPkXQ9f3S50uPXQaAIFI9knNXrE=
20+
github.com/robfig/soy v0.0.0-20200615133538-61beb7d40330/go.mod h1:h6IqIiBRukdcn8T+3XxQQ6FQTGY2N9gWKM6kat1z7Fc=
21+
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
22+
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
23+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
24+
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
25+
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
26+
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9 h1:L2auWcuQIvxz9xSEqzESnV/QN/gNRXNApHi3fYwl2w0=
27+
golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
28+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
29+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
30+
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
31+
gopkg.in/sourcemap.v1 v1.0.5 h1:inv58fC9f9J3TK2Y2R1NPntXEn3/wjWHkonhIUODNTI=
32+
gopkg.in/sourcemap.v1 v1.0.5/go.mod h1:2RlvNNSMglmRrcvhfuzp4hQHwOtjxlbjX7UPY/GXb78=
33+
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
34+
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
35+
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=

0 commit comments

Comments
 (0)