diff --git a/Dockerfile b/Dockerfile index e554625..d018c73 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,8 +12,5 @@ RUN go build -o ./elon . FROM alpine:3.14 COPY --from=go-builder /app/elon /app/elon -COPY --from=go-builder /app/public /app/public - -ENV ELON_PUBLIC_PATH "/app/public" ENTRYPOINT ["/app/elon"] diff --git a/config/config.go b/config/config.go index ec7da1c..0f8ef02 100644 --- a/config/config.go +++ b/config/config.go @@ -9,7 +9,6 @@ type TwitterConfig struct { ClientID, ClientSecret, CallbackURL, AuthorizeURL, TokenURL string } type Config struct { - PublicPath string DatabaseURL string SessionKey string ListenAddr string @@ -26,7 +25,6 @@ func NewFromEnv() (Config, error) { return Config{}, errors.New("missing ELON_SESSION_KEY") } return Config{ - PublicPath: os.Getenv("ELON_PUBLIC_PATH"), DatabaseURL: os.Getenv("ELON_DATABASE_URL"), SessionKey: sessionKey, ListenAddr: listenAddr, diff --git a/httpserver/handler.go b/httpserver/handler.go index 0cc663a..1803b24 100644 --- a/httpserver/handler.go +++ b/httpserver/handler.go @@ -5,12 +5,12 @@ package httpserver import ( "context" - "html/template" "net/http" "time" "git.netflux.io/rob/elon-eats-my-tweets/config" "git.netflux.io/rob/elon-eats-my-tweets/generated/store" + "git.netflux.io/rob/elon-eats-my-tweets/templates" "git.netflux.io/rob/elon-eats-my-tweets/twitter" "github.com/go-chi/chi" "github.com/go-chi/chi/middleware" @@ -32,7 +32,6 @@ type TwitterAPIClient interface { } type handler struct { - templates *template.Template store twitter.Store twitterAPIClientFunc func(c *http.Client) TwitterAPIClient oauth2Config *oauth2.Config @@ -41,7 +40,7 @@ type handler struct { logger *zap.SugaredLogger } -func NewHandler(cfg config.Config, templates *template.Template, store twitter.Store, twitterAPIClientFunc func(c *http.Client) TwitterAPIClient, sessionStore sessions.Store, tokenGenerator TokenGenerator, logger *zap.Logger) http.Handler { +func NewHandler(cfg config.Config, store twitter.Store, twitterAPIClientFunc func(c *http.Client) TwitterAPIClient, sessionStore sessions.Store, tokenGenerator TokenGenerator, logger *zap.Logger) http.Handler { r := chi.NewRouter() r.Use(middleware.RequestID) r.Use(middleware.RealIP) @@ -49,7 +48,6 @@ func NewHandler(cfg config.Config, templates *template.Template, store twitter.S r.Use(middleware.Recoverer) h := handler{ - templates: templates, store: store, twitterAPIClientFunc: twitterAPIClientFunc, oauth2Config: &oauth2.Config{ @@ -76,7 +74,7 @@ func NewHandler(cfg config.Config, templates *template.Template, store twitter.S } func (h *handler) getIndex(w http.ResponseWriter, r *http.Request) { - if err := h.templates.ExecuteTemplate(w, "index", nil); err != nil { + if err := templates.Execute(w, "index.html", nil); err != nil { h.logger.With("err", err).Error("error rendering template") http.Error(w, "error rendering template", http.StatusInternalServerError) return diff --git a/httpserver/handler_test.go b/httpserver/handler_test.go index 473c083..fb59b9d 100644 --- a/httpserver/handler_test.go +++ b/httpserver/handler_test.go @@ -2,11 +2,9 @@ package httpserver_test import ( "errors" - "html/template" "io/ioutil" "net/http" "net/http/httptest" - "path/filepath" "testing" "git.netflux.io/rob/elon-eats-my-tweets/config" @@ -21,8 +19,6 @@ import ( "go.uber.org/zap" ) -var templates = template.Must(template.ParseGlob(filepath.Join("..", "public", "views", "*.html"))) - // mockTokenGenerator implements httpserver.TokenGenerator. type mockTokenGenerator struct { i int @@ -44,7 +40,6 @@ func TestGetIndex(t *testing.T) { handler := httpserver.NewHandler( config.Config{}, - templates, &mocks.Store{}, func(*http.Client) httpserver.TwitterAPIClient { return &mocks.TwitterAPIClient{} }, &mocks.SessionStore{}, @@ -100,7 +95,6 @@ func TestLogin(t *testing.T) { TokenURL: "https://www.example.com/oauth/token", }, }, - templates, &mocks.Store{}, func(*http.Client) httpserver.TwitterAPIClient { return &mocks.TwitterAPIClient{} }, &mockSessionStore, @@ -266,7 +260,6 @@ func TestCallback(t *testing.T) { TokenURL: srv.URL + "/oauth/token", }, }, - templates, &mockStore, func(*http.Client) httpserver.TwitterAPIClient { return &mockTwitterClient }, &mockSessionStore, diff --git a/main.go b/main.go index 45c347b..0a5989d 100644 --- a/main.go +++ b/main.go @@ -4,10 +4,8 @@ package main import ( "context" - "html/template" "log" "net/http" - "path/filepath" "git.netflux.io/rob/elon-eats-my-tweets/config" "git.netflux.io/rob/elon-eats-my-tweets/generated/store" @@ -29,11 +27,6 @@ func main() { log.Fatal(err) } - templates, err := template.ParseGlob(filepath.Join(cfg.PublicPath, "views", "*.html")) - if err != nil { - log.Fatalf("error loading templates: %s", err) - } - ctx := context.Background() dbconn, err := pgxpool.Connect(ctx, cfg.DatabaseURL) if err != nil { @@ -44,7 +37,6 @@ func main() { handler := httpserver.NewHandler( cfg, - templates, store, func(c *http.Client) httpserver.TwitterAPIClient { return twitter.NewAPIClient(c) }, sessions.NewCookieStore([]byte(cfg.SessionKey)), diff --git a/templates/templates.go b/templates/templates.go new file mode 100644 index 0000000..97be628 --- /dev/null +++ b/templates/templates.go @@ -0,0 +1,20 @@ +package templates + +import ( + "embed" + "html/template" + "io" +) + +//go:embed views/*.html +var tmplFS embed.FS + +var templatesMap *template.Template + +func init() { + templatesMap = template.Must(template.ParseFS(tmplFS, "views/*.html")) +} + +func Execute(w io.Writer, name string, data any) error { + return templatesMap.ExecuteTemplate(w, name, data) +} diff --git a/templates/views/base.html b/templates/views/base.html new file mode 100644 index 0000000..dc019a5 --- /dev/null +++ b/templates/views/base.html @@ -0,0 +1,9 @@ + + + + Elon Eats My Tweets + + + {{block "content" .}}{{end}} + + diff --git a/public/views/index.html b/templates/views/index.html similarity index 77% rename from public/views/index.html rename to templates/views/index.html index 8c6b270..e247300 100644 --- a/public/views/index.html +++ b/templates/views/index.html @@ -1,8 +1,9 @@ -{{define "index"}} +{{template "base.html" .}} + +{{define "content"}}

Elon eats my tweets

Sick of Elon? Tired of Twitter? Have Elon Musk delete your tweets for you.

Sign in with Twitter - {{end}}