repos / pico

pico services - prose.sh, pastes.sh, imgs.sh, feeds.sh, pgs.sh
git clone https://github.com/picosh/pico.git

commit
160f932
parent
e52ab6f
author
Eric Bower
date
2022-08-28 04:24:17 +0000 UTC
feat(prose): support for og images on blog and posts
5 files changed,  +73, -17
M prose/api.go
+31, -12
  1@@ -66,17 +66,19 @@ type PostPageData struct {
  2 	PageTitle    string
  3 	URL          template.URL
  4 	BlogURL      template.URL
  5+	BlogName     string
  6 	Slug         string
  7 	Title        string
  8 	Description  string
  9 	Username     string
 10-	BlogName     string
 11 	Contents     template.HTML
 12 	PublishAtISO string
 13 	PublishAt    string
 14 	HasCSS       bool
 15 	CssURL       template.URL
 16 	Tags         []string
 17+	Image        template.URL
 18+	ImageCard    string
 19 }
 20 
 21 type TransparencyPageData struct {
 22@@ -85,11 +87,13 @@ type TransparencyPageData struct {
 23 }
 24 
 25 type HeaderTxt struct {
 26-	Title    string
 27-	Bio      string
 28-	Nav      []shared.Link
 29-	HasLinks bool
 30-	Layout   string
 31+	Title     string
 32+	Bio       string
 33+	Nav       []shared.Link
 34+	HasLinks  bool
 35+	Layout    string
 36+	Image     template.URL
 37+	ImageCard string
 38 }
 39 
 40 type ReadmeTxt struct {
 41@@ -190,9 +194,10 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 42 	}
 43 
 44 	headerTxt := &HeaderTxt{
 45-		Title:  GetBlogName(username),
 46-		Bio:    "",
 47-		Layout: "default",
 48+		Title:     GetBlogName(username),
 49+		Bio:       "",
 50+		Layout:    "default",
 51+		ImageCard: "summary",
 52 	}
 53 	readmeTxt := &ReadmeTxt{}
 54 
 55@@ -203,12 +208,12 @@ func blogHandler(w http.ResponseWriter, r *http.Request) {
 56 			logger.Error(err)
 57 		}
 58 		headerTxt.Bio = parsedText.Description
 59+		headerTxt.Layout = parsedText.Layout
 60+		headerTxt.Image = template.URL(parsedText.Image)
 61+		headerTxt.ImageCard = parsedText.ImageCard
 62 		if parsedText.Title != "" {
 63 			headerTxt.Title = parsedText.Title
 64 		}
 65-		if parsedText.Layout != "" {
 66-			headerTxt.Layout = parsedText.Layout
 67-		}
 68 
 69 		headerTxt.Nav = []shared.Link{}
 70 		for _, nav := range parsedText.Nav {
 71@@ -342,6 +347,8 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 72 	onSubdomain := cfg.IsSubdomains() && strings.Contains(hostDomain, appDomain)
 73 	withUserName := (!onSubdomain && hostDomain == appDomain) || !cfg.IsCustomdomains()
 74 
 75+	ogImage := ""
 76+	ogImageCard := ""
 77 	hasCSS := false
 78 	var data PostPageData
 79 	post, err := dbpool.FindPostWithSlug(slug, user.ID, cfg.Space)
 80@@ -361,6 +368,16 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 81 			if readmeParsed.MetaData.Title != "" {
 82 				blogName = readmeParsed.MetaData.Title
 83 			}
 84+			ogImage = readmeParsed.Image
 85+			ogImageCard = readmeParsed.ImageCard
 86+		}
 87+
 88+		if parsedText.Image != "" {
 89+			ogImage = parsedText.Image
 90+		}
 91+
 92+		if parsedText.ImageCard != "" {
 93+			ogImageCard = parsedText.ImageCard
 94 		}
 95 
 96 		// we need the blog name from the readme unfortunately
 97@@ -395,6 +412,8 @@ func postHandler(w http.ResponseWriter, r *http.Request) {
 98 			HasCSS:       hasCSS,
 99 			CssURL:       template.URL(cfg.CssURL(username)),
100 			Tags:         parsedText.Tags,
101+			Image:        template.URL(ogImage),
102+			ImageCard:    ogImageCard,
103 		}
104 	} else {
105 		data = PostPageData{
M prose/html/blog.page.tmpl
+14, -2
 1@@ -10,17 +10,29 @@
 2 <meta property="og:url" content="{{.URL}}">
 3 <meta property="og:title" content="{{.Header.Title}}">
 4 {{if .Header.Bio}}<meta property="og:description" content="{{.Header.Bio}}">{{end}}
 5+
 6+{{if .Header.Image}}
 7+<meta itemprop="image" content="{{.Header.Image}}" />
 8+<meta property="og:image" content="{{.Header.Image}}" />
 9+
10+<meta name="twitter:image" content="{{.Header.Image}}" />
11+{{else}}
12 <meta property="og:image:width" content="300" />
13 <meta property="og:image:height" content="300" />
14 <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" />
15 <meta property="og:image" content="https://{{.Site.Domain}}/card.png" />
16 
17+<meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" />
18+{{end}}
19+
20+{{if .Header.ImageCard}}
21+<meta property="twitter:card" content="{{.Header.ImageCard}}">
22+{{else}}
23 <meta property="twitter:card" content="summary">
24+{{end}}
25 <meta property="twitter:url" content="{{.URL}}">
26 <meta property="twitter:title" content="{{.Header.Title}}">
27 {{if .Header.Bio}}<meta property="twitter:description" content="{{.Header.Bio}}">{{end}}
28-<meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" />
29-<meta name="twitter:image:src" content="https://{{.Site.Domain}}/card.png" />
30 
31 <link rel="stylesheet" href="/syntax.css" />
32 {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}}
M prose/html/help.page.tmpl
+5, -1
 1@@ -100,8 +100,10 @@ date: 2022-06-28
 2             <ul>
 3                 <li>title (custom title not dependent on filename)</li>
 4                 <li>description (what is the purpose of this post?  It's also added to meta tag)</li>
 5-                <li>date (format must be YYYY-MM-DD, if set in future post wil be unlisted)</li>
 6+                <li>date (suggested format YYYY-MM-DD, if set in future post wil be unlisted)</li>
 7                 <li>tags (<code>[feature, announcement]</code>)</li>
 8+                <li>image (og image)</li>
 9+                <li>card (og image twitter card: summary, summary_large_image, etc.)</li>
10             </ul>
11         </p>
12     </section>
13@@ -182,6 +184,8 @@ This will show up on the blog landing page.
14                 <li>title (name of the blog, default: "X's blog")</li>
15                 <li>description (description of blog)</li>
16                 <li>nav (key=value pair that corresponds to text=href in html)</li>
17+                <li>image (og image)</li>
18+                <li>card (og image twitter card: summary, summary_large_image, etc.)</li>
19             </ul>
20         </p>
21     </section>
M prose/html/post.page.tmpl
+14, -2
 1@@ -10,17 +10,29 @@
 2 <meta property="og:url" content="{{.URL}}">
 3 <meta property="og:title" content="{{.Title}}">
 4 {{if .Description}}<meta property="og:description" content="{{.Description}}">{{end}}
 5+
 6+{{if .Image}}
 7+<meta itemprop="image" content="{{.Image}}" />
 8+<meta property="og:image" content="{{.Image}}" />
 9+
10+<meta name="twitter:image" content="{{.Image}}" />
11+{{else}}
12 <meta property="og:image:width" content="300" />
13 <meta property="og:image:height" content="300" />
14 <meta itemprop="image" content="https://{{.Site.Domain}}/card.png" />
15 <meta property="og:image" content="https://{{.Site.Domain}}/card.png" />
16 
17+<meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" />
18+{{end}}
19+
20+{{if .ImageCard}}
21+<meta property="twitter:card" content="{{.ImageCard}}">
22+{{else}}
23 <meta property="twitter:card" content="summary">
24+{{end}}
25 <meta property="twitter:url" content="{{.URL}}">
26 <meta property="twitter:title" content="{{.Title}}">
27 {{if .Description}}<meta property="twitter:description" content="{{.Description}}">{{end}}
28-<meta name="twitter:image" content="https://{{.Site.Domain}}/card.png" />
29-<meta name="twitter:image:src" content="https://{{.Site.Domain}}/card.png" />
30 
31 <link rel="stylesheet" href="/syntax.css" />
32 {{if .HasCSS}}<link rel="stylesheet" href="{{.CssURL}}" />{{end}}
M shared/mdparser.go
+9, -0
 1@@ -32,6 +32,8 @@ type MetaData struct {
 2 	Nav         []Link
 3 	Tags        []string
 4 	Layout      string
 5+	Image       string
 6+	ImageCard   string
 7 }
 8 
 9 type ParsedText struct {
10@@ -210,6 +212,13 @@ func ParseText(text string, absURL string) (*ParsedText, error) {
11 	parsed.MetaData.Title = toString(metaData["title"])
12 	parsed.MetaData.Description = toString(metaData["description"])
13 	parsed.MetaData.Layout = toString(metaData["layout"])
14+	parsed.MetaData.Image = toString(metaData["image"])
15+	if strings.HasPrefix(parsed.Image, "/") {
16+		parsed.MetaData.Image = fmt.Sprintf("%s%s", absURL, parsed.Image)
17+	} else if strings.HasPrefix(parsed.Image, "./") {
18+		parsed.MetaData.Image = fmt.Sprintf("%s%s", absURL, parsed.Image[1:])
19+	}
20+	parsed.MetaData.ImageCard = toString(metaData["card"])
21 
22 	var publishAt *time.Time = nil
23 	var err error