Repos / s4g / c572b9ebea
commit c572b9ebea0cfb5967120ddd27dca28eb9a95137
Author: Nhân <hi@imnhan.com>
Date: Sat Jul 22 14:21:26 2023 +0700
implement redirects
diff --git a/docs/manifest.txt b/docs/manifest.txt
index 207b13f..c0da3ca 100644
--- a/docs/manifest.txt
+++ b/docs/manifest.txt
@@ -2,4 +2,6 @@ about/index.html
feed.xml
index.html
mfws.html
+mfws/index.html
+scale.html
scale/index.html
\ No newline at end of file
diff --git a/docs/mfws/index.html b/docs/mfws/index.html
new file mode 100644
index 0000000..d3ca5e5
--- /dev/null
+++ b/docs/mfws/index.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>Redirecting to /webmaker2000/mfws.html</title>
+ <meta http-equiv="Refresh" content="0; URL=/webmaker2000/mfws.html" />
+ </head>
+ <body>
+ The page you're looking for has been moved to <a href="/webmaker2000/mfws.html">/webmaker2000/mfws.html</a>.
+ </body>
+</html>
diff --git a/docs/redirects.txt b/docs/redirects.txt
new file mode 100644
index 0000000..c20f396
--- /dev/null
+++ b/docs/redirects.txt
@@ -0,0 +1,2 @@
+mfws/index.html -> mfws.html
+scale.html -> scale/
diff --git a/docs/scale.html b/docs/scale.html
new file mode 100644
index 0000000..df77cf9
--- /dev/null
+++ b/docs/scale.html
@@ -0,0 +1,10 @@
+<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>Redirecting to /webmaker2000/scale/</title>
+ <meta http-equiv="Refresh" content="0; URL=/webmaker2000/scale/" />
+ </head>
+ <body>
+ The page you're looking for has been moved to <a href="/webmaker2000/scale/">/webmaker2000/scale/</a>.
+ </body>
+</html>
diff --git a/main.go b/main.go
index be06e87..b429160 100644
--- a/main.go
+++ b/main.go
@@ -28,6 +28,7 @@
const SiteExt = ".wbmkr2k"
const SiteFileName = "website" + SiteExt
const FeedPath = "feed.xml"
+const RedirectsPath = "redirects.txt"
func main() {
invalidCommand := func() {
@@ -255,6 +256,15 @@ func regenerate(fsys writablefs.FS) (site *SiteMetadata, err error) {
fmt.Println("Generated", FeedPath)
}
+ redirects, uerr := generateRedirects(fsys, RedirectsPath, site.Root)
+ if uerr != nil {
+ return nil, fmt.Errorf("generate redirects: %w", uerr)
+ }
+ for _, p := range redirects {
+ generatedFiles[p] = true
+ fmt.Println("Generated", p)
+ }
+
DeleteOldGeneratedFiles(fsys, generatedFiles)
WriteManifest(fsys, generatedFiles)
diff --git a/redirects.go b/redirects.go
new file mode 100644
index 0000000..5c1c54e
--- /dev/null
+++ b/redirects.go
@@ -0,0 +1,102 @@
+package main
+
+import (
+ "bufio"
+ "bytes"
+ "fmt"
+ "html/template"
+ "io/fs"
+ "path/filepath"
+ "strings"
+
+ "go.imnhan.com/webmaker2000/errs"
+ "go.imnhan.com/webmaker2000/writablefs"
+)
+
+// Returns list of generated files
+func generateRedirects(fsys writablefs.FS, path string, root string) ([]string, *errs.UserErr) {
+ f, err := fsys.Open(path)
+ if err != nil {
+ panic(err)
+ }
+
+ var sources, dests []string
+
+ s := bufio.NewScanner(f)
+ lineNo := 0
+ for s.Scan() {
+ lineNo++
+ line := strings.TrimSpace(s.Text())
+ if line == "" || line[0] == '#' {
+ continue
+ }
+ src, dest, found := strings.Cut(line, "->")
+ if !found {
+ return nil, &errs.UserErr{
+ File: path,
+ Line: lineNo,
+ Msg: fmt.Sprintf(`Expected "src -> dest", found "%s"`, line),
+ }
+ }
+
+ src = strings.TrimPrefix(strings.TrimSpace(src), "/")
+ dest = strings.TrimPrefix(strings.TrimSpace(dest), "/")
+
+ if strings.HasSuffix(src, "/") {
+ return nil, &errs.UserErr{
+ File: path,
+ Line: lineNo,
+ Msg: fmt.Sprintf(`Source must not end with a "/" (found "%s")`, line),
+ }
+ }
+
+ srcStat, err := fs.Stat(fsys, src)
+ if err == nil {
+ if srcStat.IsDir() {
+ return nil, &errs.UserErr{
+ File: path,
+ Line: lineNo,
+ Msg: fmt.Sprintf(`Source must not be a folder (found "%s")`, line),
+ }
+ }
+ }
+
+ sources = append(sources, src)
+ dests = append(dests, dest)
+ }
+
+ for i, src := range sources {
+ srcDir := filepath.Dir(src)
+ err := fsys.MkdirAll(srcDir)
+ if err != nil {
+ panic(err)
+ }
+
+ var srcBuf bytes.Buffer
+ err = srcTmpl.Execute(&srcBuf, root+dests[i])
+ if err != nil {
+ panic(err)
+ }
+
+ err = fsys.WriteFile(src, srcBuf.Bytes())
+ if err != nil {
+ panic(err)
+ }
+
+ fmt.Printf("Redirect: %s -> %s\n", src, dests[i])
+ }
+
+ return sources, nil
+}
+
+var srcTmpl = template.Must(template.New("src").Parse(`<!DOCTYPE html>
+<html lang="en">
+ <head>
+ <title>Redirecting to {{.}}</title>
+ <meta http-equiv="Refresh" content="0; URL={{.}}" />
+ </head>
+ <body>
+ The page you're looking for has been moved to <a href="{{.}}">{{.}}</a>.
+ </body>
+</html>
+`))
diff --git a/writablefs/writablefs.go b/writablefs/writablefs.go
index d99a1f6..de6ca63 100644
--- a/writablefs/writablefs.go
+++ b/writablefs/writablefs.go
@@ -10,6 +10,7 @@ type FS interface {
fs.FS
WriteFile(path string, content []byte) error
RemoveAll(path string) error
+ MkdirAll(path string) error
Path() string
}
@@ -36,3 +37,8 @@ func (w writeDirFS) WriteFile(path string, content []byte) error {
func (w writeDirFS) Path() string {
return string(w)
}
+
+func (w writeDirFS) MkdirAll(path string) error {
+ fullPath := filepath.Join(string(w), path)
+ return os.MkdirAll(fullPath, 0755)
+}