2022-08-03 14:55:48 +00:00
|
|
|
package owl
|
2022-07-21 17:02:37 +00:00
|
|
|
|
2022-07-23 16:37:41 +00:00
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
_ "embed"
|
|
|
|
"html/template"
|
2022-11-07 19:24:21 +00:00
|
|
|
"strings"
|
2022-07-23 16:37:41 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
type PageContent struct {
|
2022-10-19 19:14:31 +00:00
|
|
|
Title string
|
|
|
|
Description string
|
|
|
|
Content template.HTML
|
|
|
|
Type string
|
|
|
|
SelfUrl string
|
2022-07-23 16:37:41 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type PostRenderData struct {
|
2022-08-22 19:35:50 +00:00
|
|
|
Title string
|
|
|
|
Post *Post
|
|
|
|
Content template.HTML
|
2022-07-23 16:37:41 +00:00
|
|
|
}
|
2022-07-21 17:44:07 +00:00
|
|
|
|
2022-11-04 20:53:14 +00:00
|
|
|
type AuthRequestData struct {
|
2022-11-06 15:27:35 +00:00
|
|
|
Me string
|
|
|
|
ClientId string
|
|
|
|
RedirectUri string
|
|
|
|
State string
|
2022-11-06 18:57:39 +00:00
|
|
|
Scope string
|
2022-11-07 19:24:21 +00:00
|
|
|
Scopes []string // Split version of scope. filled by rendering function.
|
2022-11-06 15:27:35 +00:00
|
|
|
ResponseType string
|
|
|
|
CodeChallenge string
|
|
|
|
CodeChallengeMethod string
|
|
|
|
User User
|
|
|
|
CsrfToken string
|
2022-11-04 20:53:14 +00:00
|
|
|
}
|
|
|
|
|
2022-11-29 19:36:50 +00:00
|
|
|
type EditorViewData struct {
|
|
|
|
User User
|
|
|
|
CsrfToken string
|
|
|
|
}
|
|
|
|
|
2022-11-08 18:57:20 +00:00
|
|
|
type ErrorMessage struct {
|
|
|
|
Error string
|
|
|
|
Message string
|
|
|
|
}
|
|
|
|
|
2022-12-01 18:43:59 +00:00
|
|
|
func noescape(str string) template.HTML {
|
|
|
|
return template.HTML(str)
|
|
|
|
}
|
|
|
|
|
2022-12-03 15:21:51 +00:00
|
|
|
func listUrl(user User, id string) string {
|
|
|
|
return user.ListUrl(PostList{
|
|
|
|
Id: id,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-08-18 19:06:01 +00:00
|
|
|
func renderEmbedTemplate(templateFile string, data interface{}) (string, error) {
|
|
|
|
templateStr, err := embed_files.ReadFile(templateFile)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return renderTemplateStr(templateStr, data)
|
|
|
|
}
|
|
|
|
|
|
|
|
func renderTemplateStr(templateStr []byte, data interface{}) (string, error) {
|
2022-12-01 18:43:59 +00:00
|
|
|
t, err := template.New("_").Funcs(template.FuncMap{
|
|
|
|
"noescape": noescape,
|
2022-12-03 15:21:51 +00:00
|
|
|
"listUrl": listUrl,
|
2022-12-01 18:43:59 +00:00
|
|
|
}).Parse(string(templateStr))
|
2022-08-18 19:06:01 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
var html bytes.Buffer
|
|
|
|
err = t.Execute(&html, data)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
return html.String(), nil
|
|
|
|
}
|
|
|
|
|
2022-07-27 19:53:56 +00:00
|
|
|
func renderIntoBaseTemplate(user User, data PageContent) (string, error) {
|
|
|
|
baseTemplate, _ := user.Template()
|
2022-12-03 15:21:51 +00:00
|
|
|
t, err := template.New("index").Funcs(template.FuncMap{
|
|
|
|
"noescape": noescape,
|
|
|
|
"listUrl": listUrl,
|
|
|
|
}).Parse(baseTemplate)
|
2022-07-27 19:53:56 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
full_data := struct {
|
2022-10-19 19:14:31 +00:00
|
|
|
Title string
|
|
|
|
Description string
|
|
|
|
Content template.HTML
|
|
|
|
Type string
|
|
|
|
SelfUrl string
|
|
|
|
User User
|
2022-07-27 19:53:56 +00:00
|
|
|
}{
|
2022-10-19 19:14:31 +00:00
|
|
|
Title: data.Title,
|
|
|
|
Description: data.Description,
|
|
|
|
Content: data.Content,
|
|
|
|
Type: data.Type,
|
|
|
|
SelfUrl: data.SelfUrl,
|
|
|
|
User: user,
|
2022-07-27 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
var html bytes.Buffer
|
2022-11-08 18:57:20 +00:00
|
|
|
err = t.Execute(&html, full_data)
|
|
|
|
return html.String(), err
|
2022-07-27 19:53:56 +00:00
|
|
|
}
|
|
|
|
|
2022-09-04 13:32:37 +00:00
|
|
|
func renderPostContent(post *Post) (string, error) {
|
2022-08-22 19:15:36 +00:00
|
|
|
buf := post.RenderedContent()
|
2022-08-18 19:06:01 +00:00
|
|
|
postHtml, err := renderEmbedTemplate("embed/post.html", PostRenderData{
|
2022-08-22 19:35:50 +00:00
|
|
|
Title: post.Title(),
|
|
|
|
Post: post,
|
2022-12-01 18:37:13 +00:00
|
|
|
Content: template.HTML(buf),
|
2022-07-23 16:37:41 +00:00
|
|
|
})
|
2022-09-04 13:32:37 +00:00
|
|
|
return postHtml, err
|
|
|
|
}
|
|
|
|
|
|
|
|
func RenderPost(post *Post) (string, error) {
|
|
|
|
postHtml, err := renderPostContent(post)
|
2022-07-23 16:37:41 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-08-18 19:10:03 +00:00
|
|
|
return renderIntoBaseTemplate(*post.user, PageContent{
|
2022-10-19 19:14:31 +00:00
|
|
|
Title: post.Title(),
|
|
|
|
Description: post.Meta().Description,
|
|
|
|
Content: template.HTML(postHtml),
|
|
|
|
Type: "article",
|
|
|
|
SelfUrl: post.FullUrl(),
|
2022-08-18 19:10:03 +00:00
|
|
|
})
|
2022-07-21 17:02:37 +00:00
|
|
|
}
|
2022-07-23 15:19:47 +00:00
|
|
|
|
|
|
|
func RenderIndexPage(user User) (string, error) {
|
2022-11-29 19:58:34 +00:00
|
|
|
posts, _ := user.PrimaryFeedPosts()
|
2022-07-23 16:37:41 +00:00
|
|
|
|
2022-08-18 19:09:02 +00:00
|
|
|
postHtml, err := renderEmbedTemplate("embed/post-list.html", posts)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
2022-07-23 15:19:47 +00:00
|
|
|
}
|
2022-07-23 16:37:41 +00:00
|
|
|
|
2022-08-18 19:10:03 +00:00
|
|
|
return renderIntoBaseTemplate(user, PageContent{
|
2022-07-23 16:37:41 +00:00
|
|
|
Title: "Index",
|
|
|
|
Content: template.HTML(postHtml),
|
2022-08-18 19:10:03 +00:00
|
|
|
})
|
2022-11-03 20:22:55 +00:00
|
|
|
}
|
2022-07-23 16:37:41 +00:00
|
|
|
|
2022-12-01 18:10:08 +00:00
|
|
|
func RenderPostList(user User, list *PostList) (string, error) {
|
|
|
|
posts, _ := user.GetPostsOfList(*list)
|
|
|
|
postHtml, err := renderEmbedTemplate("embed/post-list.html", posts)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderIntoBaseTemplate(user, PageContent{
|
|
|
|
Title: "Index",
|
|
|
|
Content: template.HTML(postHtml),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-11-04 20:53:14 +00:00
|
|
|
func RenderUserAuthPage(reqData AuthRequestData) (string, error) {
|
2022-11-07 19:35:05 +00:00
|
|
|
reqData.Scopes = strings.Split(reqData.Scope, " ")
|
2022-11-04 20:53:14 +00:00
|
|
|
authHtml, err := renderEmbedTemplate("embed/auth.html", reqData)
|
2022-11-03 20:22:55 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
2022-11-04 20:53:14 +00:00
|
|
|
return renderIntoBaseTemplate(reqData.User, PageContent{
|
2022-11-03 20:22:55 +00:00
|
|
|
Title: "Auth",
|
|
|
|
Content: template.HTML(authHtml),
|
|
|
|
})
|
2022-07-23 15:19:47 +00:00
|
|
|
}
|
2022-07-23 16:37:41 +00:00
|
|
|
|
2022-11-08 18:57:20 +00:00
|
|
|
func RenderUserError(user User, error ErrorMessage) (string, error) {
|
|
|
|
errHtml, err := renderEmbedTemplate("embed/error.html", error)
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderIntoBaseTemplate(user, PageContent{
|
|
|
|
Title: "Error",
|
|
|
|
Content: template.HTML(errHtml),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2022-07-24 18:29:31 +00:00
|
|
|
func RenderUserList(repo Repository) (string, error) {
|
|
|
|
baseTemplate, _ := repo.Template()
|
|
|
|
users, _ := repo.Users()
|
2022-08-18 19:06:01 +00:00
|
|
|
userHtml, err := renderEmbedTemplate("embed/user-list.html", users)
|
2022-07-24 18:29:31 +00:00
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
data := PageContent{
|
|
|
|
Title: "Index",
|
2022-08-18 19:06:01 +00:00
|
|
|
Content: template.HTML(userHtml),
|
2022-07-24 18:29:31 +00:00
|
|
|
}
|
|
|
|
|
2022-08-18 19:06:01 +00:00
|
|
|
return renderTemplateStr([]byte(baseTemplate), data)
|
2022-07-24 18:29:31 +00:00
|
|
|
}
|
2022-11-29 19:36:50 +00:00
|
|
|
|
|
|
|
func RenderLoginPage(user User, csrfToken string) (string, error) {
|
|
|
|
loginHtml, err := renderEmbedTemplate("embed/editor/login.html", EditorViewData{
|
|
|
|
User: user,
|
|
|
|
CsrfToken: csrfToken,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderIntoBaseTemplate(user, PageContent{
|
|
|
|
Title: "Login",
|
|
|
|
Content: template.HTML(loginHtml),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func RenderEditorPage(user User, csrfToken string) (string, error) {
|
|
|
|
editorHtml, err := renderEmbedTemplate("embed/editor/editor.html", EditorViewData{
|
|
|
|
User: user,
|
|
|
|
CsrfToken: csrfToken,
|
|
|
|
})
|
|
|
|
if err != nil {
|
|
|
|
return "", err
|
|
|
|
}
|
|
|
|
|
|
|
|
return renderIntoBaseTemplate(user, PageContent{
|
|
|
|
Title: "Editor",
|
|
|
|
Content: template.HTML(editorHtml),
|
|
|
|
})
|
|
|
|
}
|