server, post: add about images for social media
Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
parent
4fd8925116
commit
4c39700474
36 changed files with 216 additions and 3 deletions
BIN
fonts/JetBrainsMono-Bold.ttf
Normal file
BIN
fonts/JetBrainsMono-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-BoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraBold.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraBoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraLight.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ExtraLightItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ExtraLightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Italic.ttf
Normal file
BIN
fonts/JetBrainsMono-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Light.ttf
Normal file
BIN
fonts/JetBrainsMono-Light.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-LightItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-LightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Medium.ttf
Normal file
BIN
fonts/JetBrainsMono-Medium.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-MediumItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-MediumItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Regular.ttf
Normal file
BIN
fonts/JetBrainsMono-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-SemiBold.ttf
Normal file
BIN
fonts/JetBrainsMono-SemiBold.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-SemiBoldItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-SemiBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-Thin.ttf
Normal file
BIN
fonts/JetBrainsMono-Thin.ttf
Normal file
Binary file not shown.
BIN
fonts/JetBrainsMono-ThinItalic.ttf
Normal file
BIN
fonts/JetBrainsMono-ThinItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Black.ttf
Normal file
BIN
fonts/Nunito-Black.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-BlackItalic.ttf
Normal file
BIN
fonts/Nunito-BlackItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Bold.ttf
Normal file
BIN
fonts/Nunito-Bold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-BoldItalic.ttf
Normal file
BIN
fonts/Nunito-BoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraBold.ttf
Normal file
BIN
fonts/Nunito-ExtraBold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraBoldItalic.ttf
Normal file
BIN
fonts/Nunito-ExtraBoldItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
BIN
fonts/Nunito-ExtraLight.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-ExtraLightItalic.ttf
Normal file
BIN
fonts/Nunito-ExtraLightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Italic.ttf
Normal file
BIN
fonts/Nunito-Italic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Light.ttf
Normal file
BIN
fonts/Nunito-Light.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-LightItalic.ttf
Normal file
BIN
fonts/Nunito-LightItalic.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-Regular.ttf
Normal file
BIN
fonts/Nunito-Regular.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-SemiBold.ttf
Normal file
BIN
fonts/Nunito-SemiBold.ttf
Normal file
Binary file not shown.
BIN
fonts/Nunito-SemiBoldItalic.ttf
Normal file
BIN
fonts/Nunito-SemiBoldItalic.ttf
Normal file
Binary file not shown.
93
fonts/OFL.txt
Normal file
93
fonts/OFL.txt
Normal file
|
@ -0,0 +1,93 @@
|
|||
Copyright 2014 The Nunito Project Authors (https://github.com/googlefonts/nunito)
|
||||
|
||||
This Font Software is licensed under the SIL Open Font License, Version 1.1.
|
||||
This license is copied below, and is also available with a FAQ at:
|
||||
http://scripts.sil.org/OFL
|
||||
|
||||
|
||||
-----------------------------------------------------------
|
||||
SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
|
||||
-----------------------------------------------------------
|
||||
|
||||
PREAMBLE
|
||||
The goals of the Open Font License (OFL) are to stimulate worldwide
|
||||
development of collaborative font projects, to support the font creation
|
||||
efforts of academic and linguistic communities, and to provide a free and
|
||||
open framework in which fonts may be shared and improved in partnership
|
||||
with others.
|
||||
|
||||
The OFL allows the licensed fonts to be used, studied, modified and
|
||||
redistributed freely as long as they are not sold by themselves. The
|
||||
fonts, including any derivative works, can be bundled, embedded,
|
||||
redistributed and/or sold with any software provided that any reserved
|
||||
names are not used by derivative works. The fonts and derivatives,
|
||||
however, cannot be released under any other type of license. The
|
||||
requirement for fonts to remain under this license does not apply
|
||||
to any document created using the fonts or their derivatives.
|
||||
|
||||
DEFINITIONS
|
||||
"Font Software" refers to the set of files released by the Copyright
|
||||
Holder(s) under this license and clearly marked as such. This may
|
||||
include source files, build scripts and documentation.
|
||||
|
||||
"Reserved Font Name" refers to any names specified as such after the
|
||||
copyright statement(s).
|
||||
|
||||
"Original Version" refers to the collection of Font Software components as
|
||||
distributed by the Copyright Holder(s).
|
||||
|
||||
"Modified Version" refers to any derivative made by adding to, deleting,
|
||||
or substituting -- in part or in whole -- any of the components of the
|
||||
Original Version, by changing formats or by porting the Font Software to a
|
||||
new environment.
|
||||
|
||||
"Author" refers to any designer, engineer, programmer, technical
|
||||
writer or other person who contributed to the Font Software.
|
||||
|
||||
PERMISSION & CONDITIONS
|
||||
Permission is hereby granted, free of charge, to any person obtaining
|
||||
a copy of the Font Software, to use, study, copy, merge, embed, modify,
|
||||
redistribute, and sell modified and unmodified copies of the Font
|
||||
Software, subject to the following conditions:
|
||||
|
||||
1) Neither the Font Software nor any of its individual components,
|
||||
in Original or Modified Versions, may be sold by itself.
|
||||
|
||||
2) Original or Modified Versions of the Font Software may be bundled,
|
||||
redistributed and/or sold with any software, provided that each copy
|
||||
contains the above copyright notice and this license. These can be
|
||||
included either as stand-alone text files, human-readable headers or
|
||||
in the appropriate machine-readable metadata fields within text or
|
||||
binary files as long as those fields can be easily viewed by the user.
|
||||
|
||||
3) No Modified Version of the Font Software may use the Reserved Font
|
||||
Name(s) unless explicit written permission is granted by the corresponding
|
||||
Copyright Holder. This restriction only applies to the primary font name as
|
||||
presented to the users.
|
||||
|
||||
4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
|
||||
Software shall not be used to promote, endorse or advertise any
|
||||
Modified Version, except to acknowledge the contribution(s) of the
|
||||
Copyright Holder(s) and the Author(s) or with their explicit written
|
||||
permission.
|
||||
|
||||
5) The Font Software, modified or unmodified, in part or in whole,
|
||||
must be distributed entirely under this license, and must not be
|
||||
distributed under any other license. The requirement for fonts to
|
||||
remain under this license does not apply to any document created
|
||||
using the Font Software.
|
||||
|
||||
TERMINATION
|
||||
This license becomes null and void if any of the above conditions are
|
||||
not met.
|
||||
|
||||
DISCLAIMER
|
||||
THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
|
||||
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
|
||||
OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
|
||||
COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
|
||||
DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
|
||||
OTHER DEALINGS IN THE FONT SOFTWARE.
|
3
go.mod
3
go.mod
|
@ -4,12 +4,15 @@ go 1.15
|
|||
|
||||
require (
|
||||
github.com/aymerick/raymond v2.0.2+incompatible
|
||||
github.com/fogleman/gg v1.3.0 // indirect
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 // indirect
|
||||
github.com/mitchellh/mapstructure v1.4.1
|
||||
github.com/rjeczalik/notify v0.9.2
|
||||
github.com/wellington/go-libsass v0.9.2
|
||||
github.com/yuin/goldmark v1.3.1
|
||||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691
|
||||
github.com/yuin/goldmark-meta v1.0.0
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d // indirect
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 // indirect
|
||||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 // indirect
|
||||
)
|
||||
|
|
7
go.sum
7
go.sum
|
@ -23,6 +23,10 @@ github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
|
|||
github.com/dlclark/regexp2 v1.1.6/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/dlclark/regexp2 v1.2.0 h1:8sAhBGEM0dRWogWqWyQeIJnxjWO6oIjl8FKqREDsGfk=
|
||||
github.com/dlclark/regexp2 v1.2.0/go.mod h1:2pZnwuY/m+8K6iRw6wQdMtk+rH5tNGR1i55kozfMjCc=
|
||||
github.com/fogleman/gg v1.3.0 h1:/7zJX8F6AaYQc57WQCyN9cAIz+4bCJGO9B+dyW29am8=
|
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0 h1:DACJavvAHhabrF08vX0COfcOBJRhZ8lUbR+ZWIs0Y5g=
|
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k=
|
||||
github.com/gorilla/csrf v1.6.0/go.mod h1:7tSf8kmjNYr7IWDCYhd3U8Ck34iQ/Yw5CJu7bAkHEGI=
|
||||
github.com/gorilla/handlers v1.4.1/go.mod h1:Qkdc/uu4tH4g6mTK6auzZ766c4CA0Ng8+o/OAirnOIQ=
|
||||
github.com/gorilla/mux v1.7.3/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs=
|
||||
|
@ -60,6 +64,8 @@ github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691 h1:VWSx
|
|||
github.com/yuin/goldmark-highlighting v0.0.0-20200307114337-60d527fdb691/go.mod h1:YLF3kDffRfUH/bTxOxHhV6lxwIB3Vfj91rEwNMS9MXo=
|
||||
github.com/yuin/goldmark-meta v1.0.0 h1:ScsatUIT2gFS6azqzLGUjgOnELsBOxMXerM3ogdJhAM=
|
||||
github.com/yuin/goldmark-meta v1.0.0/go.mod h1:zsNNOrZ4nLuyHAJeLQEZcQat8dm70SmB2kHbls092Gc=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d h1:RNPAfi2nHY7C2srAV8A49jpsYr0ADedCk1wq6fTMTvs=
|
||||
golang.org/x/image v0.0.0-20210628002857-a66eb6448b8d/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777 h1:003p0dJM77cxMSyCPFphvZf/Y5/NXf5fzg6ufd1/Oew=
|
||||
golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
|
@ -69,6 +75,7 @@ golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46 h1:V066+OYJ66oTjnhm4Yrn7SXIw
|
|||
golang.org/x/sys v0.0.0-20210228012217-479acdf4ea46/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
|
|
7
post.go
7
post.go
|
@ -31,6 +31,7 @@ type Post struct {
|
|||
Slug string
|
||||
Metadata Metadata
|
||||
Contents string
|
||||
Image bytes.Buffer
|
||||
}
|
||||
|
||||
func newPost(slug string) (*Post, error) {
|
||||
|
@ -73,6 +74,12 @@ func newPost(slug string) (*Post, error) {
|
|||
Contents: converted.String(),
|
||||
}
|
||||
|
||||
url := blogURL + "/" + slug
|
||||
err = createImage(post.Metadata.Title, post.Metadata.Summary, url, &post.Image)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not create post image: %v", err)
|
||||
}
|
||||
|
||||
return post, nil
|
||||
}
|
||||
|
||||
|
|
108
server.go
108
server.go
|
@ -1,12 +1,22 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"io"
|
||||
"log"
|
||||
"math"
|
||||
"net/http"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/aymerick/raymond"
|
||||
"github.com/fogleman/gg"
|
||||
)
|
||||
|
||||
const (
|
||||
blogTitle = "Prose"
|
||||
blogURL = "https://prose.nsood.in"
|
||||
blogSummary = "Where I infodump in Markdown and nobody can stop me."
|
||||
)
|
||||
|
||||
type server struct {
|
||||
|
@ -15,7 +25,8 @@ type server struct {
|
|||
mu sync.RWMutex
|
||||
templates map[string]*raymond.Template
|
||||
postList
|
||||
styles map[string]string
|
||||
styles map[string]string
|
||||
homeImage bytes.Buffer
|
||||
}
|
||||
|
||||
func newServer() (*server, error) {
|
||||
|
@ -23,6 +34,11 @@ func newServer() (*server, error) {
|
|||
staticHandler: http.FileServer(http.Dir("static/")),
|
||||
}
|
||||
|
||||
err := createImage(blogTitle, blogSummary, blogURL, &s.homeImage)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
posts, err := newPostList()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
@ -92,11 +108,18 @@ func (s *server) router(res http.ResponseWriter, req *http.Request) {
|
|||
s.homePage(res, req)
|
||||
return
|
||||
}
|
||||
if slug == "about.png" {
|
||||
s.renderImage(res, req, &s.homeImage)
|
||||
return
|
||||
}
|
||||
|
||||
for _, p := range s.postList {
|
||||
if p.Slug == slug {
|
||||
if slug == p.Slug {
|
||||
s.postPage(p, res, req)
|
||||
return
|
||||
} else if slug == p.Slug+"/about.png" {
|
||||
s.renderImage(res, req, &p.Image)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -152,7 +175,7 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
|
|||
posts = posts + summary
|
||||
}
|
||||
|
||||
page, err := s.createWebPage("Home", "Where I infodump in Markdown and nobody can stop me.", posts)
|
||||
page, err := s.createWebPage("Home", blogSummary, posts)
|
||||
|
||||
if err != nil {
|
||||
s.errorInRequest(res, req, err)
|
||||
|
@ -161,6 +184,14 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
|
|||
res.Write([]byte(page))
|
||||
}
|
||||
|
||||
func (s *server) renderImage(res http.ResponseWriter, req *http.Request, img io.Reader) {
|
||||
res.Header().Add("content-type", "image/png")
|
||||
_, err := io.Copy(res, img)
|
||||
if err != nil {
|
||||
s.errorInRequest(res, req, err)
|
||||
}
|
||||
}
|
||||
|
||||
func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, filename string) (ok bool) {
|
||||
contents, ok := s.styles[filename]
|
||||
if !ok {
|
||||
|
@ -170,3 +201,74 @@ func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, file
|
|||
res.Write([]byte(contents))
|
||||
return ok
|
||||
}
|
||||
|
||||
func createImage(title, summary, url string, out io.Writer) error {
|
||||
imgWidth, imgPaddingX, imgPaddingY := 800, 30, 60
|
||||
titleSize, summarySize, urlSize := 42.0, 28.0, 18.0
|
||||
lineHeight := 1.5
|
||||
textWidth := float64(imgWidth - 2*imgPaddingX)
|
||||
|
||||
// temporarily set height = 0 for context only used to generate
|
||||
// wrapped strings
|
||||
draw := gg.NewContext(imgWidth, 0)
|
||||
|
||||
titleFont, err := gg.LoadFontFace("fonts/Nunito-Bold.ttf", titleSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
summaryFont, err := gg.LoadFontFace("fonts/Nunito-LightItalic.ttf", summarySize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
urlFont, err := gg.LoadFontFace("fonts/JetBrainsMono-ExtraLight.ttf", urlSize)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
draw.SetFontFace(titleFont)
|
||||
wrappedTitle := draw.WordWrap(title, textWidth)
|
||||
draw.SetFontFace(summaryFont)
|
||||
wrappedSummary := draw.WordWrap(summary, textWidth)
|
||||
|
||||
imgHeight := 2 * imgPaddingY
|
||||
for range wrappedTitle {
|
||||
imgHeight += int(math.Ceil(lineHeight * titleSize))
|
||||
}
|
||||
for range wrappedSummary {
|
||||
imgHeight += int(math.Ceil(lineHeight * summarySize))
|
||||
}
|
||||
imgHeight += int(math.Ceil(lineHeight * urlSize))
|
||||
|
||||
// actual context with actual height
|
||||
draw = gg.NewContext(imgWidth, imgHeight)
|
||||
draw.SetHexColor("#fff")
|
||||
draw.DrawRectangle(0, 0, float64(imgWidth), float64(imgHeight))
|
||||
draw.Fill()
|
||||
draw.SetHexColor("#3498db")
|
||||
accentHeight := 5.0
|
||||
draw.DrawRectangle(0, float64(imgHeight)-accentHeight, float64(imgWidth), accentHeight)
|
||||
draw.Fill()
|
||||
|
||||
offset := float64(imgPaddingY)
|
||||
|
||||
draw.SetFontFace(titleFont)
|
||||
draw.SetHexColor("#333")
|
||||
for _, line := range wrappedTitle {
|
||||
draw.DrawString(line, float64(imgPaddingX), offset)
|
||||
offset += lineHeight * titleSize
|
||||
}
|
||||
|
||||
draw.SetFontFace(summaryFont)
|
||||
draw.SetHexColor("#999")
|
||||
for _, line := range wrappedSummary {
|
||||
draw.DrawString(line, float64(imgPaddingX), offset)
|
||||
offset += lineHeight * summarySize
|
||||
}
|
||||
|
||||
draw.SetHexColor("#333")
|
||||
draw.SetFontFace(urlFont)
|
||||
urlY := float64(imgHeight - imgPaddingY)
|
||||
draw.DrawStringWrapped(url, float64(imgPaddingX), urlY, 0, 0, textWidth, lineHeight, gg.AlignRight)
|
||||
|
||||
return draw.EncodePNG(out)
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@
|
|||
<meta property="og:type" content="website">
|
||||
<meta property="og:title" content="{{title}} – Prose">
|
||||
<meta property="og:description" content="{{subtitle}}">
|
||||
<meta property="og:image" content="./about.png">
|
||||
<meta name="twitter:creator" content="@tendstofortytwo">
|
||||
<meta name="color-scheme" content="dark light">
|
||||
<meta name="viewport" content="width=device-width">
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue