STUFF
This commit is contained in:
@@ -1,8 +1,42 @@
|
|||||||
package blog
|
package blog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo/options"
|
||||||
|
)
|
||||||
|
|
||||||
type BlogList struct {
|
type BlogList struct {
|
||||||
ID string `json:"id" bson:"_id"`
|
ID string `json:"id" bson:"_id"`
|
||||||
Title string `json:"title" bson:"title"`
|
Title string `json:"title" bson:"title"`
|
||||||
Draft bool `json:"draft" bson:"draft"`
|
Draft bool `json:"draft" bson:"draft"`
|
||||||
CreateTime int64 `json:"createTime" bson:"createTime"`
|
CreateTime int64 `json:"createTime" bson:"createTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Backend) FullBlogList(ctx context.Context) ([]BlogList, error) {
|
||||||
|
res, err := b.blogCol.Find(ctx, bson.M{}, options.Find().
|
||||||
|
SetProjection(bson.M{"_id": 1, "createTime": 1, "title": 1, "draft": 1}).
|
||||||
|
SetSort(bson.M{"createTime": -1}))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var list []BlogList
|
||||||
|
err = res.All(ctx, &list)
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) BlogList(ctx context.Context) ([]BlogList, error) {
|
||||||
|
res, err := b.blogCol.Find(ctx, bson.M{
|
||||||
|
"draft": false,
|
||||||
|
"staticPage": false,
|
||||||
|
}, options.Find().
|
||||||
|
SetProjection(bson.M{"_id": 1, "createTime": 1, "title": 1, "draft": 1}).
|
||||||
|
SetSort(bson.M{"createTime": -1}))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
var list []BlogList
|
||||||
|
err = res.All(ctx, &list)
|
||||||
|
return list, err
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,5 +1,17 @@
|
|||||||
package blog
|
package blog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"go.mongodb.org/mongo-driver/bson"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
|
)
|
||||||
|
|
||||||
type Blog struct {
|
type Blog struct {
|
||||||
ID string `json:"id" bson:"_id"`
|
ID string `json:"id" bson:"_id"`
|
||||||
Author string `json:"author" bson:"author"`
|
Author string `json:"author" bson:"author"`
|
||||||
@@ -12,3 +24,202 @@ type Blog struct {
|
|||||||
CreateTime int64 `json:"createTime" bson:"createTime"`
|
CreateTime int64 `json:"createTime" bson:"createTime"`
|
||||||
UpdateTime int64 `json:"updateTime" bson:"updateTime"`
|
UpdateTime int64 `json:"updateTime" bson:"updateTime"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Backend) GetBlog(ctx context.Context, ID string, allowDraft bool) (Blog, error) {
|
||||||
|
filter := bson.M{"_id": ID}
|
||||||
|
if !allowDraft {
|
||||||
|
filter["draft"] = false
|
||||||
|
}
|
||||||
|
res := b.blogCol.FindOne(ctx, filter)
|
||||||
|
if res.Err() != nil {
|
||||||
|
return Blog{}, res.Err()
|
||||||
|
}
|
||||||
|
var out Blog
|
||||||
|
err := res.Decode(&out)
|
||||||
|
return out, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) postBlogReq(w http.ResponseWriter, r *http.Request) {
|
||||||
|
usr := b.verifyEditorCookie(r)
|
||||||
|
if usr == nil {
|
||||||
|
redirect(w, r, "/login")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if usr.Perm["blog"] != "admin" && usr.Perm["blog"] != "writer" {
|
||||||
|
w.Write([]byte("<p>Sorry, but you aren't authorized to do this action.</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
err := r.ParseForm()
|
||||||
|
if err != nil {
|
||||||
|
w.Write([]byte("<p>Error decoding form</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newBlog := Blog{
|
||||||
|
ID: r.FormValue("id"),
|
||||||
|
Title: r.FormValue("title"),
|
||||||
|
RawBlog: r.FormValue("blog"),
|
||||||
|
StaticPage: r.FormValue("staticPage") == "on",
|
||||||
|
Draft: r.FormValue("draft") == "on",
|
||||||
|
UpdateTime: time.Now().Unix(),
|
||||||
|
}
|
||||||
|
if newBlog.Title == "" || newBlog.RawBlog == "" {
|
||||||
|
w.Write([]byte("<p>Title and blog contents are required</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if newBlog.ID == "" {
|
||||||
|
newBlog.ID = strings.ToLower(strings.ReplaceAll(newBlog.Title, " ", "-"))
|
||||||
|
newBlog.CreateTime = newBlog.UpdateTime
|
||||||
|
newBlog.Author = usr.Username
|
||||||
|
_, err = b.blogCol.InsertOne(r.Context(), newBlog)
|
||||||
|
if mongo.IsDuplicateKeyError(err) {
|
||||||
|
w.Write([]byte("<p>Title already exists</p>"))
|
||||||
|
return
|
||||||
|
} else if err != nil {
|
||||||
|
log.Println("error inserting document")
|
||||||
|
w.Write([]byte("<p>Server error inserting document</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.blogSuccessFullPageReplace(r.Context(), w, newBlog)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res := b.blogCol.FindOne(r.Context(), bson.M{"_id": newBlog.ID})
|
||||||
|
if res.Err() == mongo.ErrNoDocuments {
|
||||||
|
w.Write([]byte("<p>Error finding old document</p>"))
|
||||||
|
return
|
||||||
|
} else if res.Err() != nil {
|
||||||
|
log.Println("error getting old blog for update:", res.Err())
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var oldBlog Blog
|
||||||
|
err = res.Decode(&oldBlog)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error decoding old blog for update:", res.Err())
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newBlog.CreateTime = oldBlog.CreateTime
|
||||||
|
if oldBlog.Title != newBlog.Title {
|
||||||
|
res = b.blogCol.FindOne(r.Context(), bson.M{"_id": strings.ToLower(strings.ReplaceAll(newBlog.Title, " ", "-"))})
|
||||||
|
if res.Err() == nil {
|
||||||
|
w.Write([]byte("<p>Title already exists</p>"))
|
||||||
|
return
|
||||||
|
} else if res.Err() != mongo.ErrNoDocuments {
|
||||||
|
log.Println("error checking for title existance:", res.Err())
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
res = b.blogCol.FindOneAndDelete(r.Context(), bson.M{"_id": oldBlog.ID})
|
||||||
|
if res.Err() != nil {
|
||||||
|
log.Println("error deleting old blog:", res.Err())
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
newBlog.ID = strings.ToLower(strings.ReplaceAll(newBlog.Title, " ", "-"))
|
||||||
|
_, err = b.blogCol.InsertOne(r.Context(), newBlog)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error inserting document")
|
||||||
|
w.Write([]byte("<p>Server error inserting document</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.blogSuccessFullPageReplace(r.Context(), w, newBlog)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_, err = b.blogCol.UpdateByID(r.Context(), newBlog.ID, bson.M{
|
||||||
|
"updateTime": newBlog.UpdateTime,
|
||||||
|
"blog": newBlog.RawBlog,
|
||||||
|
"staticPage": newBlog.StaticPage,
|
||||||
|
"draft": newBlog.Draft,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error updating blog:", err)
|
||||||
|
w.Write([]byte("<p>Server error inserting document</p>"))
|
||||||
|
} else {
|
||||||
|
w.Write([]byte("<p>Successfully updated</p>"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) blogSuccessFullPageReplace(ctx context.Context, w http.ResponseWriter, blog Blog) {
|
||||||
|
form, err := b.BlogEditForm(blog)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error with blogForm template:", err)
|
||||||
|
w.Write([]byte("<p>Success, but error reloading page</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out, err := b.BlogEditPage(ctx, blog.ID, form)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error with getting blog list:", err)
|
||||||
|
w.Write([]byte("<p>Success, but error reloading page</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Header().Set("Hx-Retarget", "#editPage")
|
||||||
|
w.Write([]byte(out))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) BlogEditForm(blog Blog) (string, error) {
|
||||||
|
form := new(bytes.Buffer)
|
||||||
|
err := b.tmpl.ExecuteTemplate(form, "blogForm", blogFormStruct{
|
||||||
|
Blog: blog,
|
||||||
|
Result: "<p>Success!!</p>",
|
||||||
|
})
|
||||||
|
return form.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) blogFormReq(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Header.Get("Hx-Request") != "true" {
|
||||||
|
redirect(w, r, "/editor")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blogID := r.URL.Query().Get("blog")
|
||||||
|
var blog Blog
|
||||||
|
if blogID != "" {
|
||||||
|
var err error
|
||||||
|
blog, err = b.GetBlog(r.Context(), blogID, true)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error getting blog:", err)
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
}
|
||||||
|
form, err := b.BlogEditForm(blog)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using blogForm template:", err)
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write([]byte(form))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) BlogEditPage(ctx context.Context, selectedID, editor string) (string, error) {
|
||||||
|
blogs, err := b.FullBlogList(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
out := new(bytes.Buffer)
|
||||||
|
err = b.tmpl.ExecuteTemplate(out, "blogPage", blogPageStruct{
|
||||||
|
Selected: selectedID,
|
||||||
|
Editor: editor,
|
||||||
|
Blogs: blogs,
|
||||||
|
})
|
||||||
|
return out.String(), err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) blogPageReq(w http.ResponseWriter, r *http.Request) {
|
||||||
|
if r.Header.Get("Hx-Request") != "true" {
|
||||||
|
redirect(w, r, "/editor")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
form, err := b.BlogEditForm(Blog{})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using blogForm template:", err)
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
page, err := b.BlogEditPage(r.Context(), "", form)
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using blogPage template:", err)
|
||||||
|
w.Write([]byte("<p>Server error!</p>"))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
w.Write([]byte(page))
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,9 +0,0 @@
|
|||||||
package blog
|
|
||||||
|
|
||||||
import "net/http"
|
|
||||||
|
|
||||||
|
|
||||||
func (b *Backend) editorPage(w http.ResponseWriter, r *http.Request) {
|
|
||||||
pag := r.PathValue("page")
|
|
||||||
if
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,47 @@
|
|||||||
|
package blog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
func (b *Backend) editorReq(w http.ResponseWriter, r *http.Request) {
|
||||||
|
blogForm := new(bytes.Buffer)
|
||||||
|
err := b.tmpl.ExecuteTemplate(blogForm, "blogForm", blogFormStruct{
|
||||||
|
Blog: Blog{},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using blogForm:", err)
|
||||||
|
b.wrapper(w, r, "error", "<p>Server error</p>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blogs, err := b.FullBlogList(r.Context())
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error getting blog list:", err)
|
||||||
|
b.wrapper(w, r, "error", "<p>Server error</p>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
blogPage := new(bytes.Buffer)
|
||||||
|
err = b.tmpl.ExecuteTemplate(blogPage, "blogPage", blogPageStruct{
|
||||||
|
Selected: "",
|
||||||
|
Editor: blogForm.String(),
|
||||||
|
Blogs: blogs,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using blogPage:", err)
|
||||||
|
b.wrapper(w, r, "error", "<p>Server error</p>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
out := new(bytes.Buffer)
|
||||||
|
err = b.tmpl.ExecuteTemplate(out, "editor", editorStruct{
|
||||||
|
SelectedPage: "",
|
||||||
|
Page: blogPage.String(),
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
log.Println("error using editor:", err)
|
||||||
|
b.wrapper(w, r, "error", "<p>Server error</p>")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
b.wrapper(w, r, "Editor", out.String())
|
||||||
|
}
|
||||||
+62
-20
@@ -4,36 +4,78 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"net/http"
|
"net/http"
|
||||||
"sync"
|
"sync"
|
||||||
|
"text/template"
|
||||||
|
|
||||||
|
"github.com/CalebQ42/darkstorm-server/internal/backend"
|
||||||
|
"go.mongodb.org/mongo-driver/mongo"
|
||||||
)
|
)
|
||||||
|
|
||||||
type HTMXReturner func(http.ResponseWriter, *http.Request) (string, error)
|
type WrapperFunc func(w http.ResponseWriter, r *http.Request, title, content string)
|
||||||
|
|
||||||
type Backend struct {
|
type Backend struct {
|
||||||
|
blogCol *mongo.Collection
|
||||||
|
authCol *mongo.Collection
|
||||||
|
projCol *mongo.Collection
|
||||||
|
|
||||||
|
tmpl *template.Template
|
||||||
|
wrapper WrapperFunc
|
||||||
|
|
||||||
|
back *backend.Backend
|
||||||
|
|
||||||
cacheMutex sync.RWMutex
|
cacheMutex sync.RWMutex
|
||||||
cache map[string]string
|
cache map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) AddToMux(mux *http.ServeMux) {
|
func New(c *mongo.Client, back *backend.Backend, wrapper WrapperFunc) (*Backend, error) {
|
||||||
mux.HandleFunc("GET /editor/{page}", b.editorPage)
|
var b = &Backend{
|
||||||
|
blogCol: c.Database("blog").Collection("blog"),
|
||||||
|
authCol: c.Database("blog").Collection("blog"),
|
||||||
|
projCol: c.Database("blog").Collection("blog"),
|
||||||
|
wrapper: wrapper,
|
||||||
|
back: back,
|
||||||
|
cache: make(map[string]string),
|
||||||
|
}
|
||||||
|
return b, b.parseTemplates()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Backend) cacheMiddleware(h HTMXReturner) http.Handler {
|
func (b *Backend) RegisterToMux(mux *http.ServeMux) {
|
||||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
mux.HandleFunc("GET /editor", b.editorReq)
|
||||||
b.cacheMutex.RLock()
|
|
||||||
if pag, ok := b.cache[r.URL.EscapedPath()]; ok {
|
mux.HandleFunc("GET /editor/blog", b.blogPageReq)
|
||||||
w.Write([]byte(pag))
|
mux.HandleFunc("GET /editor/blog/edit", b.blogFormReq)
|
||||||
b.cacheMutex.RUnlock()
|
mux.HandleFunc("POST /editor/blog/post", b.postBlogReq)
|
||||||
return
|
|
||||||
|
// mux.HandleFunc("GET /editor/portfolio", b.portfolioPageReq)
|
||||||
|
// mux.HandleFunc("GET /editor/portfolio/edit", b.portfolioFormReq)
|
||||||
|
// mux.HandleFunc("POST /editor/portfolio/post", b.postPortfolioReq)
|
||||||
|
|
||||||
|
// mux.HandleFunc("GET /editor/author", b.authorPageReq)
|
||||||
|
// mux.HandleFunc("GET /editor/author/edit", b.authorFormReq)
|
||||||
|
// mux.HandleFunc("POST /editor/author/post", b.postAuthorReq)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (b *Backend) verifyEditorCookie(r *http.Request) *backend.User {
|
||||||
|
authCookie, err := r.Cookie("blogAuthToken")
|
||||||
|
if err != nil {
|
||||||
|
if err != http.ErrNoCookie {
|
||||||
|
log.Println("error getting auth cookie:", err)
|
||||||
}
|
}
|
||||||
b.cacheMutex.RUnlock()
|
return nil
|
||||||
b.cacheMutex.Lock()
|
}
|
||||||
defer b.cacheMutex.Unlock()
|
usr, err := b.back.VerifyUser(r.Context(), authCookie.Value)
|
||||||
res, err := h(w, r)
|
if err != nil {
|
||||||
if err != nil {
|
if err != backend.ErrTokenUnauthorized {
|
||||||
log.Printf("error getting %v: %v", r.URL.EscapedPath(), err)
|
log.Println("error authorizing JWT token:", err)
|
||||||
} else {
|
|
||||||
b.cache[r.URL.EscapedPath()] = res
|
|
||||||
}
|
}
|
||||||
w.Write([]byte(res))
|
return nil
|
||||||
})
|
}
|
||||||
|
return usr
|
||||||
|
}
|
||||||
|
|
||||||
|
func redirect(w http.ResponseWriter, r *http.Request, path string) {
|
||||||
|
if r.Header.Get("HX-Request") == "true" {
|
||||||
|
w.Header().Set("HX-Location", `{"path": "`+path+`", "target":"#content"}`)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
http.Redirect(w, r, "https://darkstorm.tech"+path, http.StatusFound)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,8 +1,12 @@
|
|||||||
package blog
|
package blog
|
||||||
|
|
||||||
|
import (
|
||||||
|
"text/template"
|
||||||
|
)
|
||||||
|
|
||||||
const editor = `
|
const editor = `
|
||||||
<p id="editSelector" hx-target="#editPage" hx-swap="swap:0.5s settle:0.5s" hx-push-url="true">
|
<p id="editSelector" hx-target="#editPage" hx-swap="swap:0.5s settle:0.5s" hx-push-url="true">
|
||||||
<a href="/editor/blog" hx-get="/editor/blog" class="editSelectorItems{{if eq .SelectedPage "blogs"}} editSelectorSelected{{end}}" {{if eq .SelectedPage "blogs"}}{{end}}>Blogs</a>
|
<a href="/editor/blog" hx-get="/editor/blog" class="editSelectorItems{{if (eq .SelectedPage "blogs") | (eq .SelectedPage "")}} editSelectorSelected{{end}}" {{if eq .SelectedPage "blogs"}}{{end}}>Blogs</a>
|
||||||
<a href="/editor/portfolio" hx-get="/editor/portfolio" class="editSelectorItems{{if eq .SelectedPage "portfolio"}} editSelectorSelected{{end}}">Portfolio</a>
|
<a href="/editor/portfolio" hx-get="/editor/portfolio" class="editSelectorItems{{if eq .SelectedPage "portfolio"}} editSelectorSelected{{end}}">Portfolio</a>
|
||||||
<a href="/editor/author" hx-get="/editor/author" class="editSelectorItems{{if eq .SelectedPage "author"}} editSelectorSelected{{end}}">Author</a>
|
<a href="/editor/author" hx-get="/editor/author" class="editSelectorItems{{if eq .SelectedPage "author"}} editSelectorSelected{{end}}">Author</a>
|
||||||
</p>
|
</p>
|
||||||
@@ -33,6 +37,7 @@ type blogPageStruct struct {
|
|||||||
Blogs []BlogList
|
Blogs []BlogList
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: Add delete
|
||||||
const blogForm = `
|
const blogForm = `
|
||||||
<form id="editorForm" hx-post="/editor/blog/post" hx-target="#formResult" hx-confirm="Save changes, overwritting previous values??">
|
<form id="editorForm" hx-post="/editor/blog/post" hx-target="#formResult" hx-confirm="Save changes, overwritting previous values??">
|
||||||
<input name="id" type="hidden" value="{{.Blog.ID}}"></input>
|
<input name="id" type="hidden" value="{{.Blog.ID}}"></input>
|
||||||
@@ -150,3 +155,33 @@ type authorFormStruct struct {
|
|||||||
Author Author
|
Author Author
|
||||||
Result string
|
Result string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Backend) parseTemplates() error {
|
||||||
|
var err error
|
||||||
|
b.tmpl, err = template.New("editor").Parse(editor)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("blogPage").Parse(blogPage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("blogForm").Parse(blogForm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("portfolioPage").Parse(portfolioPage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("portfolioForm").Parse(portfolioForm)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("authorPage").Parse(authorPage)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
b.tmpl, err = template.New("authorForm").Parse(authorForm)
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user