GoBlog/templateAssets.go

146 lines
3.3 KiB
Go
Raw Normal View History

package main
import (
2021-12-30 11:40:21 +00:00
"bytes"
"io"
"mime"
"net/http"
"os"
"path"
"path/filepath"
2020-09-19 10:57:14 +00:00
"strings"
2021-11-15 20:48:16 +00:00
chromahtml "github.com/alecthomas/chroma/formatters/html"
"go.goblog.app/app/pkgs/contenttype"
)
const assetsFolder = "templates/assets"
type assetFile struct {
contentType string
body []byte
}
func (a *goBlog) initTemplateAssets() (err error) {
a.assetFileNames = map[string]string{}
a.assetFiles = map[string]*assetFile{}
err = filepath.Walk(assetsFolder, func(path string, info os.FileInfo, err error) error {
if info.Mode().IsRegular() {
2021-12-30 11:40:21 +00:00
// Open file
file, err := os.Open(path)
if err != nil {
return err
}
2021-12-30 11:40:21 +00:00
// Compile asset and close file
compiled, err := a.compileAsset(path, file)
_ = file.Close()
if err != nil {
return err
}
// Add to map
if compiled != "" {
a.assetFileNames[strings.TrimPrefix(path, assetsFolder+"/")] = compiled
}
}
return nil
})
if err != nil {
return err
}
2021-11-15 20:48:16 +00:00
// Add syntax highlighting CSS
err = a.initChromaCSS()
if err != nil {
return err
}
return nil
}
2021-12-30 11:40:21 +00:00
func (a *goBlog) compileAsset(name string, read io.Reader) (string, error) {
ext := path.Ext(name)
compiledExt := ext
2021-12-30 11:40:21 +00:00
var contentBuffer bytes.Buffer
switch ext {
case ".js":
2021-12-30 11:40:21 +00:00
if err := a.min.Minify(contenttype.JS, &contentBuffer, read); err != nil {
2021-02-08 17:51:07 +00:00
return "", err
}
case ".css":
2021-12-30 11:40:21 +00:00
if err := a.min.Minify(contenttype.CSS, &contentBuffer, read); err != nil {
2021-08-04 13:45:58 +00:00
return "", err
}
case ".xml", ".xsl":
2021-12-30 11:40:21 +00:00
if err := a.min.Minify(contenttype.XML, &contentBuffer, read); err != nil {
2021-02-08 17:51:07 +00:00
return "", err
}
default:
2021-12-30 11:40:21 +00:00
if _, err := io.Copy(&contentBuffer, read); err != nil {
return "", err
}
}
// Hashes
2021-12-30 11:40:21 +00:00
hash, err := getSHA256(bytes.NewReader(contentBuffer.Bytes()))
if err != nil {
2021-02-08 17:51:07 +00:00
return "", err
}
// File name
2021-12-30 11:40:21 +00:00
compiledFileName := hash + compiledExt
// Create struct
a.assetFiles[compiledFileName] = &assetFile{
contentType: mime.TypeByExtension(compiledExt),
2021-12-30 11:40:21 +00:00
body: contentBuffer.Bytes(),
}
2021-02-08 17:51:07 +00:00
return compiledFileName, err
}
// Function for templates
func (a *goBlog) assetFileName(fileName string) string {
return "/" + a.assetFileNames[fileName]
}
func (a *goBlog) allAssetPaths() []string {
var paths []string
for _, name := range a.assetFileNames {
paths = append(paths, "/"+name)
}
return paths
}
// Gets only called by registered paths
func (a *goBlog) serveAsset(w http.ResponseWriter, r *http.Request) {
af, ok := a.assetFiles[strings.TrimPrefix(r.URL.Path, "/")]
if !ok {
a.serve404(w, r)
return
}
w.Header().Set("Cache-Control", "public,max-age=31536000,immutable")
w.Header().Set(contentType, af.contentType+contenttype.CharsetUtf8Suffix)
2021-02-08 17:51:07 +00:00
_, _ = w.Write(af.body)
}
2021-11-15 20:48:16 +00:00
func (a *goBlog) initChromaCSS() error {
2021-12-30 11:40:21 +00:00
chromaPath := "css/chroma.css"
2021-11-15 20:48:16 +00:00
// Check if file already exists
2021-12-30 11:40:21 +00:00
if _, ok := a.assetFiles[chromaPath]; ok {
2021-11-15 20:48:16 +00:00
return nil
}
// Initialize the style
2021-11-16 09:37:30 +00:00
chromaStyleBuilder := chromaGoBlogStyle.Builder()
2021-11-15 20:48:16 +00:00
chromaStyle, err := chromaStyleBuilder.Build()
if err != nil {
return err
}
2021-12-30 11:40:21 +00:00
// Write the CSS to a buffer
var cssBuffer bytes.Buffer
if err = chromahtml.New(chromahtml.ClassPrefix("c-")).WriteCSS(&cssBuffer, chromaStyle); err != nil {
return err
}
2021-11-15 20:48:16 +00:00
// Compile asset
2021-12-30 11:40:21 +00:00
compiled, err := a.compileAsset(chromaPath, &cssBuffer)
2021-11-15 20:48:16 +00:00
if err != nil {
return err
}
2021-12-30 11:40:21 +00:00
// Add to map
a.assetFileNames[chromaPath] = compiled
2021-11-15 20:48:16 +00:00
return nil
}