seperate styles logic
Signed-off-by: Naman Sood <mail@nsood.in>
This commit is contained in:
parent
ff9fe3d550
commit
0373431876
2 changed files with 121 additions and 88 deletions
120
server.go
120
server.go
|
@ -1,8 +1,6 @@
|
||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
|
||||||
"io"
|
|
||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
@ -12,7 +10,6 @@ import (
|
||||||
|
|
||||||
"github.com/aymerick/raymond"
|
"github.com/aymerick/raymond"
|
||||||
"github.com/rjeczalik/notify"
|
"github.com/rjeczalik/notify"
|
||||||
"github.com/wellington/go-libsass"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
type server struct {
|
type server struct {
|
||||||
|
@ -23,6 +20,9 @@ type server struct {
|
||||||
|
|
||||||
postsMutex sync.RWMutex
|
postsMutex sync.RWMutex
|
||||||
postList
|
postList
|
||||||
|
|
||||||
|
cssMutex sync.RWMutex
|
||||||
|
styles map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func newServer() (*server, error) {
|
func newServer() (*server, error) {
|
||||||
|
@ -46,10 +46,13 @@ func newServer() (*server, error) {
|
||||||
s.templates = tpls
|
s.templates = tpls
|
||||||
s.tplMutex.Unlock()
|
s.tplMutex.Unlock()
|
||||||
|
|
||||||
err = s.refreshStyles()
|
styles, err := newStylesMap()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
s.cssMutex.Lock()
|
||||||
|
s.styles = styles
|
||||||
|
s.cssMutex.Unlock()
|
||||||
|
|
||||||
postsLn := newPostListener(func(updateFn func(postList) postList) {
|
postsLn := newPostListener(func(updateFn func(postList) postList) {
|
||||||
s.postsMutex.Lock()
|
s.postsMutex.Lock()
|
||||||
|
@ -65,95 +68,16 @@ func newServer() (*server, error) {
|
||||||
})
|
})
|
||||||
go templatesLn.listen()
|
go templatesLn.listen()
|
||||||
|
|
||||||
stylesLn := &listener{
|
stylesLn := newStylesListener(func(updateFn func(map[string]string)) {
|
||||||
folder: "styles/",
|
s.cssMutex.Lock()
|
||||||
update: func(file string) error {
|
defer s.cssMutex.Unlock()
|
||||||
var err error
|
updateFn(s.styles)
|
||||||
if strings.HasSuffix(file, ".scss") {
|
})
|
||||||
err = loadSassStylesheet(file)
|
|
||||||
} else if strings.HasSuffix(file, ".css") {
|
|
||||||
err = loadRegularStylesheet(file)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
clean: func(file string) error {
|
|
||||||
var err error
|
|
||||||
if strings.HasSuffix(file, ".scss") {
|
|
||||||
err = os.Remove("static/style/" + strings.TrimSuffix(file, ".scss") + ".css")
|
|
||||||
} else if strings.HasSuffix(file, ".css") {
|
|
||||||
err = os.Remove("static/style/" + file)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
},
|
|
||||||
}
|
|
||||||
go stylesLn.listen()
|
go stylesLn.listen()
|
||||||
|
|
||||||
return s, nil
|
return s, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func loadSassStylesheet(filename string) error {
|
|
||||||
in, err := os.Open("styles/" + filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not open style infile %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
output := strings.TrimSuffix(filename, ".scss") + ".css"
|
|
||||||
out, err := os.Create("static/css/" + output)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not open style outfile %s: %w", output, err)
|
|
||||||
}
|
|
||||||
comp, err := libsass.New(out, in)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not start sass compiler for file %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
if err = comp.Run(); err != nil {
|
|
||||||
return fmt.Errorf("Could not generate stylesheet %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func loadRegularStylesheet(filename string) error {
|
|
||||||
in, err := os.Open("styles/" + filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not open style infile %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
out, err := os.Create("static/css/" + filename)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not open style outfile %s: %w", filename, err)
|
|
||||||
}
|
|
||||||
_, err = io.Copy(out, in)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not copy stylesheet %s: %s", filename, err)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *server) refreshStyles() error {
|
|
||||||
styles, err := os.ReadDir("styles/")
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Could not load styles directory: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, s := range styles {
|
|
||||||
filename := s.Name()
|
|
||||||
if strings.HasSuffix(filename, ".scss") {
|
|
||||||
err := loadSassStylesheet(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else if strings.HasSuffix(filename, ".css") {
|
|
||||||
err := loadRegularStylesheet(filename)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Printf("Skipping stylesheet %s, don't know how to handle", filename)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
log.Printf("Loaded stylesheet %s", filename)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type listener struct {
|
type listener struct {
|
||||||
folder string
|
folder string
|
||||||
update func(string) error
|
update func(string) error
|
||||||
|
@ -250,6 +174,14 @@ func (s *server) router(res http.ResponseWriter, req *http.Request) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if strings.HasPrefix(slug, "css/") {
|
||||||
|
filename := strings.TrimPrefix(slug, "css/")
|
||||||
|
ok := s.loadStylesheet(res, req, filename)
|
||||||
|
if ok {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
s.staticHandler.ServeHTTP(res, req)
|
s.staticHandler.ServeHTTP(res, req)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -303,3 +235,15 @@ func (s *server) homePage(res http.ResponseWriter, req *http.Request) {
|
||||||
|
|
||||||
res.Write([]byte(page))
|
res.Write([]byte(page))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *server) loadStylesheet(res http.ResponseWriter, req *http.Request, filename string) (ok bool) {
|
||||||
|
s.cssMutex.RLock()
|
||||||
|
defer s.cssMutex.RUnlock()
|
||||||
|
contents, ok := s.styles[filename]
|
||||||
|
if !ok {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
res.Header().Add("content-type", "text/css")
|
||||||
|
res.Write([]byte(contents))
|
||||||
|
return ok
|
||||||
|
}
|
||||||
|
|
89
style.go
Normal file
89
style.go
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"github.com/wellington/go-libsass"
|
||||||
|
)
|
||||||
|
|
||||||
|
func newStylesMap() (map[string]string, error) {
|
||||||
|
folder, err := os.ReadDir("styles/")
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("Could not load styles directory: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
styles := make(map[string]string)
|
||||||
|
for _, s := range folder {
|
||||||
|
contents, filename, err := loadStylesheet(s.Name())
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("could not generate styles for %s: %v", s.Name(), err)
|
||||||
|
}
|
||||||
|
styles[filename] = contents
|
||||||
|
log.Printf("Loaded stylesheet %s", filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
return styles, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func newStylesListener(updateMap func(func(map[string]string))) *listener {
|
||||||
|
ln := &listener{
|
||||||
|
folder: "styles/",
|
||||||
|
update: func(file string) error {
|
||||||
|
contents, filename, err := loadStylesheet(file)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
updateMap(func(styles map[string]string) {
|
||||||
|
styles[filename] = contents
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
clean: func(file string) error {
|
||||||
|
updateMap(func(styles map[string]string) {
|
||||||
|
delete(styles, file+".css")
|
||||||
|
})
|
||||||
|
return nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
return ln
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadStylesheet(filename string) (string, string, error) {
|
||||||
|
if strings.HasSuffix(filename, ".scss") {
|
||||||
|
return loadSCSS(filename)
|
||||||
|
}
|
||||||
|
return loadCSS(filename)
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadSCSS(filename string) (string, string, error) {
|
||||||
|
in, err := os.Open("styles/" + filename)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Could not open style infile %s: %w", filename, err)
|
||||||
|
}
|
||||||
|
var buf strings.Builder
|
||||||
|
comp, err := libsass.New(&buf, in)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Could not start sass compiler for file %s: %w", filename, err)
|
||||||
|
}
|
||||||
|
if err = comp.Run(); err != nil {
|
||||||
|
return "", "", fmt.Errorf("Could not generate stylesheet %s: %w", filename, err)
|
||||||
|
}
|
||||||
|
return buf.String(), strings.TrimSuffix(filename, ".scss") + ".css", nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func loadCSS(filename string) (string, string, error) {
|
||||||
|
in, err := os.Open("styles/" + filename)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Could not open style infile %s: %w", filename, err)
|
||||||
|
}
|
||||||
|
var buf strings.Builder
|
||||||
|
_, err = io.Copy(&buf, in)
|
||||||
|
if err != nil {
|
||||||
|
return "", "", fmt.Errorf("Could not copy stylesheet %s: %s", filename, err)
|
||||||
|
}
|
||||||
|
return buf.String(), filename, nil
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue