diff options
| author | Alex Scerba <alex@scerba.org> | 2024-11-09 23:21:53 -0500 | 
|---|---|---|
| committer | Alex Scerba <alex@scerba.org> | 2024-11-09 23:21:53 -0500 | 
| commit | 545ebd7cebd891f6099d3a62f219d49303af0fca (patch) | |
| tree | db8295d8e084d93c9a2f48831e2f5a2de284304e | |
| parent | 5ec772029d4ea4b4f4ed2c78b4416afd9dab71cd (diff) | |
Move to dynamic blog system
| -rw-r--r-- | cmd/http/handle.go | 73 | ||||
| -rw-r--r-- | cmd/http/load.go | 73 | ||||
| -rw-r--r-- | cmd/http/main.go | 12 | ||||
| -rw-r--r-- | cmd/http/render.go | 61 | 
4 files changed, 141 insertions, 78 deletions
diff --git a/cmd/http/handle.go b/cmd/http/handle.go index ce0e8c0..f5ee67a 100644 --- a/cmd/http/handle.go +++ b/cmd/http/handle.go @@ -17,7 +17,7 @@ func (app *application) home(w http.ResponseWriter, r *http.Request) {  		   			app.serverError(w, err)  		   		} */ -		err := renderTemplate(w, "index", nil) +		err := renderPage(w, "index")  		if err != nil {  			app.serverError(w, err)  		} @@ -29,51 +29,82 @@ func (app *application) page(w http.ResponseWriter, r *http.Request) {  	path := strings.Split(r.URL.Path, "/") -	/* Redirect paths like /about/sth/oeusth to /about */ +	// Redirect paths like /about/sth/oeusth to /about  	if len(path) > 2 {  		http.Redirect(w, r, "/"+path[1], http.StatusFound)  	} -	err := renderTemplate(w, path[1], nil) +	err := renderPage(w, path[1])  	if err != nil {  		app.serverError(w, err)  	}  } -/*  func (app *application) blog(w http.ResponseWriter, r *http.Request) {  	w.Header().Set("Content-Type", "text/html; charset=utf-8")  	path := strings.Split(r.URL.Path, "/") -	if path[1] != "blog" { -		app.notFound(w) -	} else { -		err := renderTemplate(w, "blog", nil) + +	// Setup redirects for trailing / and extraneous path elements +	if len(path) > 3 { +		// Redirect to /blog/article +		http.Redirect(w, r, "/"+path[1]+"/"+path[2], http.StatusFound) +	} else if len(path) == 3 && path[2] == "" { +		// Redirect to /blog +		http.Redirect(w, r, "/"+path[1], http.StatusFound) +	} else if len(path) == 2 { +		p, err := app.aggregate("html/blog")  		if err != nil {  			app.serverError(w, err) +			return +		} +		a, err := app.aggregate("html/archive") +		if err != nil { +			app.serverError(w, err) +			return  		} -	} -	if len(path) > 4 { -		app.notFound(w) -	} else if len(path) == 4 && path[3] == "" { -		http.Redirect(w, r, "/"+path[1]+"/"+path[2], http.StatusFound) -	} else { -		post, err := app.readFile("html" + strings.TrimSuffix(r.URL.Path, "/") + ".tmpl.html") +		err = renderBlog(w, "blog2", p, a)  		if err != nil { +			app.serverError(w, err) +			return +		} +	} else if len(path) == 3 { +		if !app.fileExists("html/" + path[1] + "/" + path[2] + ".tmpl.html") {  			app.notFound(w)  			return  		} +		post := app.parseFileName(path[2]) -		var posts []*Post -		posts = append(posts, post) -		p := &Posts{Contents: posts} - -		err = renderTemplate(w, path[1]+"/"+path[2], p) +		err := renderPost(w, path[2], post)  		if err != nil {  			app.serverError(w, err)  		}  	} +} + +func (app *application) archive(w http.ResponseWriter, r *http.Request) { +	w.Header().Set("Content-Type", "text/html; charset=utf-8") + +	path := strings.Split(r.URL.Path, "/") + +	// Setup redirects for trailing / and extraneous path elements +	if len(path) > 3 { +		// Redirect to /archive/article +		http.Redirect(w, r, "/"+path[1]+"/"+path[2], http.StatusFound) +	} else if len(path) == 3 && path[2] == "" { +		// Redirect to /blog +		http.Redirect(w, r, "/blog", http.StatusFound) +	} else if len(path) == 3 { +		if !app.fileExists("html/" + path[1] + "/" + path[2] + ".tmpl.html") { +			app.notFound(w) +			return +		} +		post := app.parseFileName(path[2]) +		err := renderArchivePost(w, path[2], post) +		if err != nil { +			app.serverError(w, err) +		} +	}  } -*/ diff --git a/cmd/http/load.go b/cmd/http/load.go index d63d7ce..6ab2eba 100644 --- a/cmd/http/load.go +++ b/cmd/http/load.go @@ -1,24 +1,23 @@  package main  import ( +	"errors"  	"os" -	"regexp"  	"sort"  	"strings"  )  // Post struct contains necessary data for a post  type Post struct { -	FileName string -	Title    string -	Date     string -	Tags     []string -	Image    string +	File  string +	Title string +	Date  string +	Tags  []string  }  // Posts stuct contains a collection of type Post  type Posts struct { -	Contents []*Post +	Collection []*Post  }  // Read all found files and load them into a stuct @@ -33,10 +32,7 @@ func (app *application) aggregate(location string) (p *Posts, err error) {  	// Loop over every file in the directory and read the contents.  	for _, file := range files {  		if !file.IsDir() && strings.HasSuffix(file.Name(), ".tmpl.html") { -			newPost, err := app.readFile(location + "/" + file.Name()) -			if err != nil { -				return nil, err -			} +			newPost := app.parseFileName(strings.TrimSuffix(file.Name(), ".tmpl.html"))  			posts = append(posts, newPost)  		} @@ -46,35 +42,32 @@ func (app *application) aggregate(location string) (p *Posts, err error) {  		return posts[i].Date > posts[j].Date  	}) -	return &Posts{Contents: posts}, nil +	return &Posts{Collection: posts}, nil  } -func (app *application) readFile(location string) (p *Post, err error) { -	fileContent, err := os.ReadFile(location) -	if err != nil { -		return nil, err -	} - +func (app *application) parseFileName(file string) (p *Post) {  	var post *Post = new(Post) -	fileName := strings.TrimSuffix(strings.Split(location, "/")[2], ".tmpl.html") - -	// title -	title := strings.ReplaceAll(fileName, "_", " ") +	svList := strings.Split(file, "+") +	usvLength := len(svList)  	// date -	datePattern := regexp.MustCompile(`{{define "uploaded-on"}}(\d{4}-\d{2}-\d{2}){{end}}`) +	/*datePattern := regexp.MustCompile(`{{define "uploaded-on"}}(\d{4}-\d{2}-\d{2}){{end}}`)  	dateMatching := datePattern.FindStringSubmatch(string(fileContent)) -	var date string +	//var date string  	if len(dateMatching) > 1 {  		date = dateMatching[1]  	} else {  		date = "" -	} +	}*/ +	date := svList[0] + +	// title +	title := strings.ReplaceAll(svList[1], "_", " ")  	// tags -	tagsPattern := regexp.MustCompile(`{{define "keywords"}}([\w\s]+){{end}}`) +	/*tagsPattern := regexp.MustCompile(`{{define "keywords"}}([\w\s]+){{end}}`)  	matchingTags := tagsPattern.FindStringSubmatch(string(fileContent))  	var tags []string @@ -82,25 +75,29 @@ func (app *application) readFile(location string) (p *Post, err error) {  		tags = strings.Fields(matchingTags[1])  	} else {  		tags = []string{} -	} - -	// thumbnail image -	imagePattern := regexp.MustCompile(`<img src="(.+)" class="mainImage"( alt="(.+)")* />`) -	matchingImage := imagePattern.FindStringSubmatch(string(fileContent)) +	}*/ -	var image string -	if len(matchingImage) > 1 { -		image = matchingImage[0] +	var tags []string +	if usvLength > 2 { +		for i := 2; i < usvLength; i++ { +			tags = append(tags, svList[i]) +		}  	} else { -		image = "" +		tags = []string{}  	} -	post.FileName = fileName +	post.File = file  	post.Title = title  	post.Date = date  	post.Tags = tags -	post.Image = image -	return post, nil +	return post + +} +func (app *application) fileExists(file string) bool { +	if _, err := os.Stat(file); errors.Is(err, os.ErrNotExist) { +		return false +	} +	return true  } diff --git a/cmd/http/main.go b/cmd/http/main.go index a75ccfc..951c02f 100644 --- a/cmd/http/main.go +++ b/cmd/http/main.go @@ -18,7 +18,7 @@ type application struct {  	infoLog  *log.Logger  } -func (app *application) httpsRedirect(w http.ResponseWriter, req *http.Request) { +/*func (app *application) httpsRedirect(w http.ResponseWriter, req *http.Request) {  	// remove/add not default ports from req.Host  	target := "https://" + req.Host + req.URL.Path  	if len(req.URL.RawQuery) > 0 { @@ -28,12 +28,12 @@ func (app *application) httpsRedirect(w http.ResponseWriter, req *http.Request)  	http.Redirect(w, req, target,  		// see comments below and consider the codes 308, 302, or 301  		http.StatusMovedPermanently) -} +}*/  func (app *application) wwwRedirect(h http.Handler) http.Handler {  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {  		if !strings.HasPrefix(r.Host, "www.") { -			http.Redirect(w, r, "https://www."+r.Host+r.RequestURI, 302) +			http.Redirect(w, r, "https://www."+r.Host+r.RequestURI, http.StatusFound)  			return  		} @@ -66,8 +66,10 @@ func main() {  	mux.HandleFunc("/gallery/", app.page)  	mux.HandleFunc("/links", app.page)  	mux.HandleFunc("/links/", app.page) -	mux.HandleFunc("/blog", app.page) -	mux.HandleFunc("/blog/", app.page) +	mux.HandleFunc("/blog", app.blog) +	mux.HandleFunc("/blog/", app.blog) +	mux.HandleFunc("/archive", app.archive) +	mux.HandleFunc("/archive/", app.archive)  	mux.HandleFunc("/", app.home)  	if *addr == ":443" { diff --git a/cmd/http/render.go b/cmd/http/render.go index 585ba31..deaa68e 100644 --- a/cmd/http/render.go +++ b/cmd/http/render.go @@ -2,32 +2,65 @@ package main  import (  	"net/http" -	//"strings"  	"text/template"  ) -func renderTemplate(w http.ResponseWriter, page string, p *Posts) (err error) { +func renderPage(w http.ResponseWriter, page string) (err error) {  	t, err := template.ParseFiles("html/master.tmpl.html", "html/"+page+".tmpl.html")  	if err != nil {  		return err  	} -	//splitPath := strings.Split(page, "/") +	err = t.Execute(w, nil) +	if err != nil { +		return err +	} + +	return nil +} + +func renderBlog(w http.ResponseWriter, page string, p *Posts, a *Posts) (err error) { +	t, err := template.ParseFiles("html/master.tmpl.html", "html/"+page+".tmpl.html") +	if err != nil { +		return err +	} -	//data := make(map[string]interface{}) +	data := make(map[string]interface{}) -	// If were loading the index, set page to 'Index' and pass through all posts. -	// Otherwise, set page to 'Projects' and pass through the first post (should only be one -	// coming in) -	/* if splitPath[0] == "index" { -		data["Page"] = "Index" +	if page == "blog2" {  		data["Posts"] = p -	} else { -		data["Page"] = "Project" -		data["Post"] = p.Contents[0] -	} */ +		data["Archive"] = a +	} -	err = t.Execute(w, nil) +	err = t.Execute(w, data) +	if err != nil { +		return err +	} + +	return nil +} + +func renderPost(w http.ResponseWriter, page string, p *Post) (err error) { +	t, err := template.ParseFiles("html/master.tmpl.html", "html/post.tmpl.html", "html/blog/"+page+".tmpl.html") +	if err != nil { +		return err +	} + +	err = t.Execute(w, p) +	if err != nil { +		return err +	} + +	return nil +} + +func renderArchivePost(w http.ResponseWriter, page string, p *Post) (err error) { +	t, err := template.ParseFiles("html/master.tmpl.html", "html/post.tmpl.html", "html/archive/"+page+".tmpl.html") +	if err != nil { +		return err +	} + +	err = t.Execute(w, p)  	if err != nil {  		return err  	}  | 
