Skip to content

Commit

Permalink
feat: add <meta> tags for Open Graph
Browse files Browse the repository at this point in the history
  • Loading branch information
rynhndrcksn authored Dec 8, 2024
1 parent 962fdec commit 317d6bf
Show file tree
Hide file tree
Showing 14 changed files with 115 additions and 36 deletions.
22 changes: 22 additions & 0 deletions cmd/web/handlers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,33 @@ import (
"runtime/debug"
)

// aboutHandler displays the about page.
func (app *application) aboutHandler(w http.ResponseWriter, r *http.Request) {
data := app.newTemplateData(r)
data.Description = "About website"
data.ImageUrl = "/static/images/default_og_image.png"
data.PageType = "website"
data.Title = "About"
app.render(w, r, http.StatusOK, "home.tmpl", data)
}

// homeHandler displays the home page.
func (app *application) homeHandler(w http.ResponseWriter, r *http.Request) {
data := app.newTemplateData(r)
data.Description = "Homepage of a website"
data.ImageUrl = "/static/images/default_og_image.png"
data.PageType = "website"
data.Title = "Home"
app.render(w, r, http.StatusOK, "home.tmpl", data)
}

// notFoundHandler displays a 404 page.
func (app *application) notFoundHandler(w http.ResponseWriter, r *http.Request) {
data := app.newTemplateData(r)
data.Description = "404 page"
data.ImageUrl = "/static/images/default_og_image.png"
data.PageType = "website"
data.Title = "Not Found"
app.render(w, r, http.StatusNotFound, "404.tmpl", data)
}

Expand All @@ -25,5 +43,9 @@ func (app *application) serverErrorHandler(w http.ResponseWriter, r *http.Reques
return
}
data := app.newTemplateData(r)
data.Description = "Server error"
data.ImageUrl = "/static/images/default_og_image.png"
data.PageType = "website"
data.Title = "Server Error"
app.render(w, r, http.StatusInternalServerError, "500.tmpl", data)
}
14 changes: 2 additions & 12 deletions cmd/web/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"net/http"

"github.com/julienschmidt/httprouter"

"github.com/rynhndrcksn/go-starter-site/ui"
)

Expand All @@ -23,19 +24,8 @@ func (app *application) routes() http.Handler {

// Register routes.
router.HandlerFunc(http.MethodGet, "/", app.homeHandler)
router.HandlerFunc(http.MethodGet, "/about", app.aboutHandler)
router.Handler(http.MethodGet, "/debug/vars", expvar.Handler())

return app.recoverPanic(app.logRequest(app.commonHeaders(router)))
}

func (app *application) routeThatPanics() http.Handler {
// Initialize new httprouter instance.
router := httprouter.New()

// Register route to test against:
router.HandlerFunc(http.MethodGet, "/server-error", func(writer http.ResponseWriter, r *http.Request) {
panic("this triggers a 500 status page")
})

return app.recoverPanic(router)
}
33 changes: 29 additions & 4 deletions cmd/web/templates.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import (
"io/fs"
"net/http"
"path/filepath"
"strings"
"time"

"github.com/rynhndrcksn/go-starter-site/internal/env"
"github.com/rynhndrcksn/go-starter-site/ui"
)

Expand Down Expand Up @@ -55,15 +57,23 @@ func props(pairs ...any) (map[string]any, error) {

// templateData holds dynamic data that can be passed to the HTML templates.
type templateData struct {
CurrentYear int
Flash string
CanonicalUrl string
CurrentYear int
Description string
Flash string
ImageUrl string
PageType string
SiteName string
Title string
}

// newTemplateData initializes a new templateData struct and returns it.
func (app *application) newTemplateData(r *http.Request) templateData {
return templateData{
CurrentYear: time.Now().Year(),
Flash: app.sessionManager.PopString(r.Context(), "flash"),
CanonicalUrl: getCanonicalURL(r),
CurrentYear: time.Now().Year(),
Flash: app.sessionManager.PopString(r.Context(), "flash"),
SiteName: env.GetStringOrDefault("SITE_NAME", "Site"),
}
}

Expand Down Expand Up @@ -106,3 +116,18 @@ func newTemplateCache() (map[string]*template.Template, error) {

return cache, nil
}

// getCanonicalURL creates the canonical URL and returns it.
func getCanonicalURL(r *http.Request) string {
// Get the full URL from the request
scheme := "https"

// Remove www if present and clean the host
host := r.Host
host = strings.TrimPrefix(host, "www.")

// Build the canonical URL without query parameters
canonicalURL := scheme + "://" + host + r.URL.Path

return canonicalURL
}
13 changes: 13 additions & 0 deletions cmd/web/testutils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import (

"github.com/alexedwards/scs/v2"
"github.com/alexedwards/scs/v2/memstore"
"github.com/julienschmidt/httprouter"
)

// newTestApplication creates a new application struct containing mocked dependencies.
Expand Down Expand Up @@ -90,3 +91,15 @@ func (ts *testServer) get(t *testing.T, urlPath string) (int, http.Header, strin

return rs.StatusCode, rs.Header, string(body)
}

func (app *application) routeThatPanics() http.Handler {
// Initialize new httprouter instance.
router := httprouter.New()

// Register route to test against:
router.HandlerFunc(http.MethodGet, "/server-error", func(writer http.ResponseWriter, r *http.Request) {
panic("this triggers a 500 status page")
})

return app.recoverPanic(router)
}
42 changes: 34 additions & 8 deletions ui/html/base.tmpl
Original file line number Diff line number Diff line change
@@ -1,25 +1,51 @@
{{- /*gotype: github.com/rynhndrcksn/go-starter-site/cmd/web.templateData*/ -}}
{{define "base"}}
<!doctype html>
<html lang="en">
<head>
<head prefix="og: https://ogp.me/ns#">
<meta charset="utf-8">
<title>{{template "title" .}} - Site</title>
<title>{{ .Title }} - {{ .SiteName }}</title>

<!-- Make the search engine overlords happy -->
<link rel="canonical" href="{{ .CanonicalUrl }}">
<meta name="description" content="{{ .Description }}">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<meta name="keyword" content="">

<!-- Open Graph -->
<meta property="og:site_name" content="{{ .SiteName }}">
<meta property="og:title" content="{{ .Title }}">
<meta property="og:description" content="{{ .Description }}">
<meta property="og:type" content="{{ .PageType }}">
<meta property="og:url" content="{{ .CanonicalUrl }}">
<meta property="og:locale" content="en_US">
<meta property="og:image" content="{{ .ImageUrl }}">
<meta property="og:image:width" content="1200">
<meta property="og:image:height" content="630">
<!-- Why no og:image:alt? Read this: https://yoast.com/developer-blog/why-we-dont-set-the-og-image-alt-tag/ -->

<!-- Twitter/X-->
<meta name="twitter:card" content="summary_large_image">
<meta name="twitter:title" content="{{ .Title }}">
<meta name="twitter:description" content="{{ .Description }}">
<meta name="twitter:image" content="{{ .ImageUrl }}">
<meta name="twitter:image:width" content="1200">
<meta name="twitter:image:height" content="630">
<!-- Why no twitter:image:alt? Read this: https://yoast.com/developer-blog/why-we-dont-set-the-og-image-alt-tag/ -->

<link rel="icon" href="/static/favicon.svg" type="image/svg+xml">
<link rel="stylesheet" href="/static/css/main.css">
<link rel="shortcut icon" href="/static/img/favicon.ico" type="image/x-icon">
</head>
<body>
<header>
<h1><a href='/'>Home</a></h1>
</header>
{{template "nav" .}}
{{template "header" .}}
<main>
{{with .Flash}}
<div class="flash">{{.}}</div>
{{end}}
{{template "main" .}}
</main>
{{template "footer" .}}
<script src="/static/js/main.js" type="text/javascript" async defer></script>
<script src="/static/js/main.js" async defer></script>
</body>
</html>
{{end}}
2 changes: 1 addition & 1 deletion ui/html/components/nav-link.tmpl
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
{{define "nav-link"}}
<a href="{{.Link}}">{{.Text}}</a>
<a href="{{ .Link }}" class="{{ .Classes }}">{{ .Text }}</a>
{{end}}
2 changes: 0 additions & 2 deletions ui/html/pages/404.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{{define "title"}}Not Found{{end}}

{{define "main"}}
<p>We were unable to find what you were looking for! Want to go back <a href="/">home</a>?</p>
{{end}}
2 changes: 0 additions & 2 deletions ui/html/pages/500.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{{define "title"}}Server Error{{end}}

{{define "main"}}
<p>We encountered an unexpected error! Want to go back <a href="/">home</a>?</p>
{{end}}
3 changes: 3 additions & 0 deletions ui/html/pages/about.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{{define "main"}}
<h1>There's nothing to read about yet!</h1>
{{end}}
2 changes: 0 additions & 2 deletions ui/html/pages/home.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
{{define "title"}}Home{{end}}

{{define "main"}}
<h1>There's nothing to see here yet!</h1>
{{end}}
2 changes: 1 addition & 1 deletion ui/html/partials/footer.tmpl
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{{define "footer"}}
<footer>
<div>Powered by <a href="https://go.dev/" target="_blank">Go</a> in {{.CurrentYear}}</div>
<div>Powered by <a href="https://go.dev/" target="_blank">Go</a> in {{ .CurrentYear }}</div>
</footer>
{{end}}
5 changes: 5 additions & 0 deletions ui/html/partials/header.tmpl
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{{define "header"}}
<header>
{{template "nav" .}}
</header>
{{end}}
6 changes: 2 additions & 4 deletions ui/html/partials/nav.tmpl
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{{define "nav"}}
<nav>
<div>
{{template "nav-link" (props "Link" "/" "Text" "Home")}}
{{template "nav-link" (props "Link" "/about" "Text" "About")}}
</div>
{{template "nav-link" (props "Link" "/" "Text" "Home" "Classes" "home")}}
{{template "nav-link" (props "Link" "/about" "Text" "About" "Classes" "")}}
</nav>
{{end}}
3 changes: 3 additions & 0 deletions ui/static/favicon.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 317d6bf

Please sign in to comment.