From b71d24a0f0de5cd211eaf9852e55722952bc86ff Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Tue, 9 Apr 2024 00:06:08 +0530 Subject: [PATCH 1/6] feat: auto-refresh browser on live reload TODO: If the browser is refreshed manually, the file has to be modified twice to reload the page later. Co-authored-by: Aditya Hegde --- cmd/anna/anna.go | 2 ++ cmd/anna/livereload.go | 35 +++++++++++++++++++++++++++++++++- main.go | 1 + pkg/parser/parser.go | 6 +++++- site/layout/page.html | 2 +- site/layout/partials/head.html | 18 ++++++++++++++++- 6 files changed, 60 insertions(+), 4 deletions(-) diff --git a/cmd/anna/anna.go b/cmd/anna/anna.go index dc943dd..be9ea6b 100644 --- a/cmd/anna/anna.go +++ b/cmd/anna/anna.go @@ -14,6 +14,7 @@ import ( type Cmd struct { RenderDrafts bool Addr string + LiveReload bool } func (cmd *Cmd) VanillaRender() { @@ -23,6 +24,7 @@ func (cmd *Cmd) VanillaRender() { TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), RenderDrafts: cmd.RenderDrafts, + LiveReload: cmd.LiveReload, } e := engine.Engine{ Templates: make(map[template.URL]parser.TemplateData), diff --git a/cmd/anna/livereload.go b/cmd/anna/livereload.go index ecf2b27..00a133f 100644 --- a/cmd/anna/livereload.go +++ b/cmd/anna/livereload.go @@ -6,11 +6,16 @@ import ( "net/http" "os" "path/filepath" + "sync/atomic" "time" "github.com/acmpesuecc/anna/pkg/helpers" ) +var reloadPage = make(chan struct{}) + +var countRequests atomic.Int32 + type liveReload struct { errorLogger *log.Logger fileTimes map[string]time.Time @@ -43,6 +48,7 @@ func (cmd *Cmd) StartLiveReload() { for _, rootDir := range lr.rootDirs { if lr.traverseDirectory(rootDir) { cmd.VanillaRender() + reloadPage <- struct{}{} } } if !lr.serverRunning { @@ -97,8 +103,35 @@ func (lr *liveReload) checkFile(path string, modTime time.Time) bool { func (lr *liveReload) startServer(addr string) { fmt.Print("Serving content at: http://localhost:", addr, "\n") - err := http.ListenAndServe(":"+addr, http.FileServer(http.Dir(helpers.SiteDataPath+"./rendered"))) + http.Handle("/", http.FileServer(http.Dir(helpers.SiteDataPath+"./rendered"))) + http.HandleFunc("/events", eventsHandler) + err := http.ListenAndServe(":"+addr, nil) if err != nil { lr.errorLogger.Fatal(err) } } + +func eventsHandler(w http.ResponseWriter, r *http.Request) { + countRequests.Add(1) + + // Set CORS headers to allow all origins. + w.Header().Set("Access-Control-Allow-Origin", "*") + w.Header().Set("Access-Control-Expose-Headers", "Content-Type") + + w.Header().Set("Content-Type", "text/event-stream") + w.Header().Set("Cache-Control", "no-cache") + w.Header().Set("Connection", "keep-alive") + + if countRequests.Load() == 1 { + <-reloadPage + } else { + countRequests.Store(countRequests.Load() - 1) + return + } + + event := "event:\ndata:\n\n" + w.Write([]byte(event)) + w.(http.Flusher).Flush() + + countRequests.Store(countRequests.Load() - 1) +} diff --git a/main.go b/main.go index 6ece361..d84b4f3 100644 --- a/main.go +++ b/main.go @@ -29,6 +29,7 @@ func main() { } if serve { + annaCmd.LiveReload = true annaCmd.StartLiveReload() } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index f0d150b..9a4b6f2 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -46,6 +46,7 @@ type TemplateData struct { Frontmatter Frontmatter Body template.HTML Layout LayoutConfig + LiveReload bool // Do not use these fields to store tags!! // These fields are populated by the ssg to store merged tag data @@ -80,6 +81,9 @@ type Parser struct { ErrorLogger *log.Logger Helper *helpers.Helper + + // Determines the injection of Live Reload JS in HTML + LiveReload bool } func (p *Parser) ParseMDDir(baseDirPath string, baseDirFS fs.FS) { @@ -135,6 +139,7 @@ func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, front Frontmatter: frontmatter, Body: template.HTML(body), Layout: p.LayoutConfig, + LiveReload: p.LiveReload, } // Adding the page to the merged map storing all site pages @@ -253,7 +258,6 @@ func (p *Parser) ParseRobots(inFilePath string, outFilePath string) { // Parse all the ".html" layout files in the layout/ directory func (p *Parser) ParseLayoutFiles() *template.Template { - // Parsing all files in the layout/ dir which match the "*.html" pattern templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.html") if err != nil { diff --git a/site/layout/page.html b/site/layout/page.html index 25b733c..62d8b51 100644 --- a/site/layout/page.html +++ b/site/layout/page.html @@ -43,4 +43,4 @@

{{ .Frontmatter.Title }}

-{{ end}} +{{ end}} \ No newline at end of file diff --git a/site/layout/partials/head.html b/site/layout/partials/head.html index 99b68b0..7472d5e 100644 --- a/site/layout/partials/head.html +++ b/site/layout/partials/head.html @@ -13,12 +13,28 @@ + + {{ if .LiveReload }} + + {{ end }} + + {{range .Frontmatter.JSFiles}} {{end}} {{range .Layout.SiteScripts}} {{end}} + @@ -33,4 +49,4 @@ {{end}} - \ No newline at end of file + From 96f6666aee3da0e7a4fba75befa4e4c48d94f45c Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 14:25:34 +0530 Subject: [PATCH 2/6] feat: implement deep data merge TODO: - Pass the deep data merge struct to all the templates - Remove redundant fields and refactor the engine pkg/ --- cmd/anna/anna.go | 19 ++++++----- pkg/engine/anna_engine.go | 38 ++++++++++----------- pkg/engine/anna_engine_test.go | 28 +++++++-------- pkg/engine/engine.go | 36 ++++++++++++++------ pkg/engine/engine_integration_test.go | 8 ++--- pkg/engine/engine_test.go | 6 ++-- pkg/engine/user_engine.go | 14 ++++---- pkg/engine/user_engine_test.go | 49 ++++++++++++++------------- 8 files changed, 108 insertions(+), 90 deletions(-) diff --git a/cmd/anna/anna.go b/cmd/anna/anna.go index 0db0eec..6e274b2 100644 --- a/cmd/anna/anna.go +++ b/cmd/anna/anna.go @@ -24,11 +24,12 @@ func (cmd *Cmd) VanillaRender() { ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), RenderDrafts: cmd.RenderDrafts, } + e := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), - ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), + ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } + e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) helper := helpers.Helper{ ErrorLogger: e.ErrorLogger, @@ -47,18 +48,18 @@ func (cmd *Cmd) VanillaRender() { p.ParseRobots(helpers.SiteDataPath+"layout/robots.txt", helpers.SiteDataPath+"rendered/robots.txt") p.ParseLayoutFiles() - e.Templates = p.Templates - e.TagsMap = p.TagsMap - e.LayoutConfig = p.LayoutConfig - e.Posts = p.Posts + e.DeepDataMerge.Templates = p.Templates + e.DeepDataMerge.TagsMap = p.TagsMap + e.DeepDataMerge.LayoutConfig = p.LayoutConfig + e.DeepDataMerge.Posts = p.Posts e.GenerateSitemap(helpers.SiteDataPath + "rendered/sitemap.xml") e.GenerateFeed() e.GenerateJSONIndex(helpers.SiteDataPath) helper.CopyDirectoryContents(helpers.SiteDataPath+"static/", helpers.SiteDataPath+"rendered/static/") - sort.Slice(e.Posts, func(i, j int) bool { - return e.Posts[i].Frontmatter.Date > e.Posts[j].Frontmatter.Date + sort.Slice(e.DeepDataMerge.Posts, func(i, j int) bool { + return e.DeepDataMerge.Posts[i].Frontmatter.Date > e.DeepDataMerge.Posts[j].Frontmatter.Date }) templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.layout") diff --git a/pkg/engine/anna_engine.go b/pkg/engine/anna_engine.go index ba4f47e..a719d85 100644 --- a/pkg/engine/anna_engine.go +++ b/pkg/engine/anna_engine.go @@ -20,8 +20,8 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { var tagsBuffer bytes.Buffer // Extracting tag titles - tags := make([]string, 0, len(e.TagsMap)) - for tag := range e.TagsMap { + tags := make([]string, 0, len(e.DeepDataMerge.TagsMap)) + for tag := range e.DeepDataMerge.TagsMap { tags = append(tags, tag) } @@ -31,7 +31,7 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { tagNames := parser.TemplateData{ FilenameWithoutExtension: "Tags", - Layout: e.LayoutConfig, + Layout: e.DeepDataMerge.LayoutConfig, Frontmatter: parser.Frontmatter{Title: "Tags"}, Tags: tags, } @@ -52,15 +52,15 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { var wg sync.WaitGroup // Rendering the subpages with merged tagged posts - for tag, taggedTemplates := range e.TagsMap { + for tag, taggedTemplates := range e.DeepDataMerge.TagsMap { wg.Add(1) go func(tag string, taggedTemplates []parser.TemplateData) { defer wg.Done() - pagePath := "tags/" + tag + pagePath := "tags/" + tag + ".html" templateData := parser.TemplateData{ FilenameWithoutExtension: tag, - Layout: e.LayoutConfig, + Layout: e.DeepDataMerge.LayoutConfig, Frontmatter: parser.Frontmatter{ Title: tag, }, @@ -88,7 +88,7 @@ func (e *Engine) GenerateJSONIndex(outFilePath string) { // Copying contents from e.Templates to new JsonMerged struct jsonIndexTemplate := make(map[template.URL]JSONIndexTemplate) - for templateURL, templateData := range e.Templates { + for templateURL, templateData := range e.DeepDataMerge.Templates { jsonIndexTemplate[templateURL] = JSONIndexTemplate{ CompleteURL: templateData.CompleteURL, FilenameWithoutExtension: templateData.FilenameWithoutExtension, @@ -97,7 +97,7 @@ func (e *Engine) GenerateJSONIndex(outFilePath string) { } } - e.JSONIndex = jsonIndexTemplate + e.DeepDataMerge.JSONIndex = jsonIndexTemplate // Marshal the contents of jsonMergedData jsonMergedMarshaledData, err := json.Marshal(jsonIndexTemplate) @@ -117,22 +117,22 @@ func (e *Engine) GenerateSitemap(outFilePath string) { buffer.WriteString("\n") // Sorting templates by key - keys := make([]string, 0, len(e.Templates)) - for k := range e.Templates { + keys := make([]string, 0, len(e.DeepDataMerge.Templates)) + for k := range e.DeepDataMerge.Templates { keys = append(keys, string(k)) } sort.Strings(keys) tempTemplates := make(map[template.URL]parser.TemplateData) for _, templateURL := range keys { - tempTemplates[template.URL(templateURL)] = e.Templates[template.URL(templateURL)] + tempTemplates[template.URL(templateURL)] = e.DeepDataMerge.Templates[template.URL(templateURL)] } - e.Templates = tempTemplates + e.DeepDataMerge.Templates = tempTemplates // Iterate over parsed markdown files - for _, templateData := range e.Templates { - url := e.LayoutConfig.BaseURL + "/" + templateData.FilenameWithoutExtension + ".html" + for _, templateData := range e.DeepDataMerge.Templates { + url := e.DeepDataMerge.LayoutConfig.BaseURL + "/" + templateData.FilenameWithoutExtension + ".html" buffer.WriteString("\t\n") buffer.WriteString("\t\t" + url + "\n") buffer.WriteString("\t\t" + templateData.Frontmatter.Date + "\n") @@ -156,17 +156,17 @@ func (e *Engine) GenerateFeed() { buffer.WriteString("\n") buffer.WriteString("\n") buffer.WriteString("\n") - buffer.WriteString(" " + e.LayoutConfig.SiteTitle + "\n") - buffer.WriteString(" \n") + buffer.WriteString(" " + e.DeepDataMerge.LayoutConfig.SiteTitle + "\n") + buffer.WriteString(" \n") buffer.WriteString(" " + time.Now().Format(time.RFC3339) + "\n") // iterate over parsed markdown files that are non-draft posts - for _, templateData := range e.Templates { + for _, templateData := range e.DeepDataMerge.Templates { if !templateData.Frontmatter.Draft { buffer.WriteString("\n") buffer.WriteString(" " + templateData.Frontmatter.Title + "\n") - buffer.WriteString(" \n") - buffer.WriteString(" " + e.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html\n") + buffer.WriteString(" \n") + buffer.WriteString(" " + e.DeepDataMerge.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html\n") buffer.WriteString(" " + time.Unix(templateData.Date, 0).Format(time.RFC3339) + "\n") buffer.WriteString(" \n") buffer.WriteString(" \n") diff --git a/pkg/engine/anna_engine_test.go b/pkg/engine/anna_engine_test.go index 38ada32..5dcf6b0 100644 --- a/pkg/engine/anna_engine_test.go +++ b/pkg/engine/anna_engine_test.go @@ -15,15 +15,15 @@ import ( func TestRenderTags(t *testing.T) { e := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } - e.LayoutConfig.BaseURL = "example.org" + e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + e.DeepDataMerge.LayoutConfig.BaseURL = "example.org" fileOutPath := "../../test/engine/render_tags/" - e.TagsMap["blogs"] = []parser.TemplateData{ + e.DeepDataMerge.TagsMap["blogs"] = []parser.TemplateData{ { CompleteURL: "posts/file1.html", Frontmatter: parser.Frontmatter{ @@ -40,7 +40,7 @@ func TestRenderTags(t *testing.T) { }, } - e.TagsMap["tech"] = []parser.TemplateData{ + e.DeepDataMerge.TagsMap["tech"] = []parser.TemplateData{ { CompleteURL: "posts/file2.html", Frontmatter: parser.Frontmatter{ @@ -124,12 +124,12 @@ func TestGenerateMergedJson(t *testing.T) { t.Run("test json creation for the search index", func(t *testing.T) { e := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } + e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) - e.Templates["docs.md"] = parser.TemplateData{ + e.DeepDataMerge.Templates["docs.md"] = parser.TemplateData{ FilenameWithoutExtension: "docs", CompleteURL: "docs.html", Frontmatter: parser.Frontmatter{ @@ -165,10 +165,10 @@ func TestGenerateMergedJson(t *testing.T) { func TestGenerateSitemap(t *testing.T) { t.Run("render sitemap.xml", func(t *testing.T) { engine := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } + engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) t1 := parser.TemplateData{ FilenameWithoutExtension: "index", @@ -191,11 +191,11 @@ func TestGenerateSitemap(t *testing.T) { }, } - engine.LayoutConfig.BaseURL = "example.org" + engine.DeepDataMerge.LayoutConfig.BaseURL = "example.org" // setting up engine - engine.Templates["index"] = t1 - engine.Templates["about"] = t2 - engine.Templates["research"] = t3 + engine.DeepDataMerge.Templates["index"] = t1 + engine.DeepDataMerge.Templates["about"] = t2 + engine.DeepDataMerge.Templates["research"] = t3 engine.GenerateSitemap(TestDirPath + "sitemap/got_sitemap.xml") diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index 63714a5..e6da507 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -10,7 +10,8 @@ import ( "github.com/acmpesuecc/anna/pkg/parser" ) -type Engine struct { +// This struct holds all of the ssg data +type MergedSiteData struct { // Templates stores the template data of all the pages of the site // Access the data for a particular page by using the relative path to the file as the key Templates map[template.URL]parser.TemplateData @@ -26,6 +27,11 @@ type Engine struct { // Stores the index generated for search functionality JSONIndex map[template.URL]JSONIndexTemplate +} + +type Engine struct { + // Stores the merged ssg data + DeepDataMerge MergedSiteData // Common logger for all engine functions ErrorLogger *log.Logger @@ -39,27 +45,37 @@ type JSONIndexTemplate struct { Tags []string } -// fileOutPath for main.go should be refering to helpers.SiteDataPath -func (e *Engine) RenderPage(fileOutPath string, pagePath template.URL, pageTemplateData parser.TemplateData, templ *template.Template, templateStartString string) { +/* +fileOutPath - stores the parent directory to store rendered files, usually `site/` + +pagePath - stores the path to write the given page without the prefix directory +Eg: site/content/posts/file1.html to be passed as posts/file1.html + +pageTemplateData - an interface that accepts any type of data to be passed to ExecuteTemplate() + +template - stores the HTML templates parsed from the layout/ directory + +templateStartString - stores the name of the template to be passed to ExecuteTemplate() +*/ +func (e *Engine) RenderPage(fileOutPath string, pagePath template.URL, pageTemplateData interface{}, template *template.Template, templateStartString string) { // Creating subdirectories if the filepath contains '/' - dirPath := "" if strings.Contains(string(pagePath), "/") { // Extracting the directory path from the page path - dirPath, _ := strings.CutSuffix(string(pagePath), pageTemplateData.FilenameWithoutExtension) - dirPath = fileOutPath + "rendered/" + dirPath + splitPaths := strings.Split(string(pagePath), "/") + filename := splitPaths[len(splitPaths)-1] + pagePathWithoutFilename, _ := strings.CutSuffix(string(pagePath), filename) - err := os.MkdirAll(dirPath, 0750) + err := os.MkdirAll(fileOutPath+"rendered/"+pagePathWithoutFilename, 0750) if err != nil { e.ErrorLogger.Fatal(err) } } - filename, _ := strings.CutSuffix(string(pagePath), ".md") - filepath := fileOutPath + "rendered/" + dirPath + filename + ".html" + filepath := fileOutPath + "rendered/" + string(pagePath) var buffer bytes.Buffer // Storing the rendered HTML file to a buffer - err := templ.ExecuteTemplate(&buffer, templateStartString, pageTemplateData) + err := template.ExecuteTemplate(&buffer, templateStartString, pageTemplateData) if err != nil { e.ErrorLogger.Fatal(err) } diff --git a/pkg/engine/engine_integration_test.go b/pkg/engine/engine_integration_test.go index 678f379..35e2516 100644 --- a/pkg/engine/engine_integration_test.go +++ b/pkg/engine/engine_integration_test.go @@ -13,19 +13,19 @@ import ( func TestRenderUserDefinedPages(t *testing.T) { engine := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } + engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) - engine.Templates["index.md"] = + engine.DeepDataMerge.Templates["index.md"] = parser.TemplateData{ FilenameWithoutExtension: "index", Body: template.HTML("

Index Page

"), CompleteURL: "index.html", } - engine.Templates["posts/hello.md"] = parser.TemplateData{ + engine.DeepDataMerge.Templates["posts/hello.md"] = parser.TemplateData{ FilenameWithoutExtension: "hello", Body: template.HTML("

Hello World

"), CompleteURL: "posts/hello.html", diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index f54ba25..21538f8 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -20,10 +20,10 @@ func TestRenderPage(t *testing.T) { t.Run("render a single page while creating a new directory", func(t *testing.T) { engine := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } + engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) page := parser.TemplateData{ CompleteURL: template.URL("got"), @@ -50,7 +50,7 @@ func TestRenderPage(t *testing.T) { t.Errorf("%v", err) } - engine.RenderPage(TestDirPath+"render_page/", "posts/got.md", page, templ, "page") + engine.RenderPage(TestDirPath+"render_page/", "posts/got.html", page, templ, "page") got_file, err := os.ReadFile(TestDirPath + "render_page/rendered/posts/got.html") if err != nil { diff --git a/pkg/engine/user_engine.go b/pkg/engine/user_engine.go index 2779ffd..3b10d47 100644 --- a/pkg/engine/user_engine.go +++ b/pkg/engine/user_engine.go @@ -21,10 +21,10 @@ func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, templ *template. var postsBuffer bytes.Buffer postsData := postsTemplateData{ - Posts: e.Posts, + Posts: e.DeepDataMerge.Posts, TemplateData: parser.TemplateData{ Frontmatter: parser.Frontmatter{Title: "Posts"}, - Layout: e.LayoutConfig, + Layout: e.DeepDataMerge.LayoutConfig, }, } @@ -42,7 +42,7 @@ func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, templ *template. func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Template) { numCPU := runtime.NumCPU() - numTemplates := len(e.Templates) + numTemplates := len(e.DeepDataMerge.Templates) concurrency := numCPU * 2 // Adjust the concurrency factor based on system hardware resources if numTemplates < concurrency { @@ -50,7 +50,7 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp } templateURLs := make([]string, 0, numTemplates) - for templateURL := range e.Templates { + for templateURL := range e.DeepDataMerge.Templates { templateURLs = append(templateURLs, string(templateURL)) } @@ -58,9 +58,9 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp semaphore := make(chan struct{}, concurrency) for _, templateURL := range templateURLs { - templData := e.Templates[template.URL(templateURL)] + templData := e.DeepDataMerge.Templates[template.URL(templateURL)] fileInPath := strings.TrimSuffix(string(templData.CompleteURL), ".html") - if fileInPath == "" { + if fileInPath == ".html" { continue } @@ -73,7 +73,7 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp wg.Done() }() - e.RenderPage(fileOutPath, template.URL(fileInPath), templData, templ, "page") + e.RenderPage(fileOutPath, templData.CompleteURL, templData, templ, "page") }(templateURL) } diff --git a/pkg/engine/user_engine_test.go b/pkg/engine/user_engine_test.go index 1116923..02c29be 100644 --- a/pkg/engine/user_engine_test.go +++ b/pkg/engine/user_engine_test.go @@ -12,37 +12,38 @@ import ( ) func TestRenderEngineGeneratedFiles(t *testing.T) { + engine := engine.Engine{ - Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), + } + engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) - Posts: []parser.TemplateData{ - { - FilenameWithoutExtension: "file1", - Frontmatter: parser.Frontmatter{ - Title: "file1", - Description: "Description of file 1", - Date: "2024-03-28", - }, + engine.DeepDataMerge.Posts = []parser.TemplateData{ + { + FilenameWithoutExtension: "file1", + Frontmatter: parser.Frontmatter{ + Title: "file1", + Description: "Description of file 1", + Date: "2024-03-28", }, + }, - { - FilenameWithoutExtension: "file2", - Frontmatter: parser.Frontmatter{ - Title: "file2", - Description: "Description of file 2", - Date: "2024-03-28", - }, + { + FilenameWithoutExtension: "file2", + Frontmatter: parser.Frontmatter{ + Title: "file2", + Description: "Description of file 2", + Date: "2024-03-28", }, + }, - { - FilenameWithoutExtension: "file3", - Frontmatter: parser.Frontmatter{ - Title: "file3", - Description: "Description of file 3", - Date: "2024-03-28", - }, + { + FilenameWithoutExtension: "file3", + Frontmatter: parser.Frontmatter{ + Title: "file3", + Description: "Description of file 3", + Date: "2024-03-28", }, }, } From 97dd0b97b37c2a067422e8c90f2c532f9178f09d Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 15:56:13 +0530 Subject: [PATCH 3/6] feat: complete deep data merge and update tests Co-authored-by: Aditya Hegde --- .gitignore | 6 +- cmd/anna/anna.go | 6 +- pkg/engine/anna_engine.go | 80 ++++-- pkg/engine/anna_engine_test.go | 28 +- pkg/engine/engine.go | 33 ++- pkg/engine/engine_integration_test.go | 19 +- pkg/engine/engine_test.go | 12 +- pkg/engine/user_engine.go | 17 +- pkg/engine/user_engine_test.go | 12 +- pkg/parser/parser.go | 35 ++- pkg/parser/parser_integration_test.go | 4 +- pkg/parser/parser_test.go | 29 ++- site/content/posts/markdown_test.md | 245 ++++++++++++++++-- site/layout/page.layout | 25 +- site/layout/posts.layout | 2 +- site/layout/tag-subpage.layout | 12 +- site/layout/tags.layout | 11 +- site/static/index.json | 101 +++++++- test/engine/json_index_test/want_index.json | 3 +- .../posts_template.layout | 2 +- test/engine/render_page/template_input.layout | 48 +++- test/engine/render_page/want.html | 45 +++- .../render_tags/tags_subpage_template.layout | 24 +- test/engine/render_tags/tags_template.layout | 29 ++- test/engine/render_tags/want_blogs_tags.html | 22 +- test/engine/render_tags/want_tags.html | 27 +- test/engine/render_tags/want_tech_tags.html | 22 +- .../render_user_defined/template_input.layout | 48 +++- .../render_user_defined/want_index.html | 16 +- .../render_user_defined/want_post_hello.html | 16 +- test_clean.sh | 5 + 31 files changed, 724 insertions(+), 260 deletions(-) create mode 100644 test_clean.sh diff --git a/.gitignore b/.gitignore index f1febea..576c567 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -site/rendered/ anna !anna/ *.exe @@ -7,3 +6,8 @@ anna ssg/ *.txt dist/ + +#Test directories +**/rendered/ +test/**/static/ +test/**/got_sitemap.xml \ No newline at end of file diff --git a/cmd/anna/anna.go b/cmd/anna/anna.go index 6e274b2..ecc118d 100644 --- a/cmd/anna/anna.go +++ b/cmd/anna/anna.go @@ -20,16 +20,16 @@ func (cmd *Cmd) VanillaRender() { // Defining Engine and Parser Structures p := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), RenderDrafts: cmd.RenderDrafts, } e := engine.Engine{ - ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), + ErrorLogger: log.New(os.Stderr, "ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) helper := helpers.Helper{ ErrorLogger: e.ErrorLogger, diff --git a/pkg/engine/anna_engine.go b/pkg/engine/anna_engine.go index a719d85..c0b0aa1 100644 --- a/pkg/engine/anna_engine.go +++ b/pkg/engine/anna_engine.go @@ -16,28 +16,49 @@ import ( "github.com/acmpesuecc/anna/pkg/parser" ) +type TagRootTemplateData struct { + DeepDataMerge DeepDataMerge + PagePath template.URL + TagTemplateData parser.TemplateData + TagNames []string +} + func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { var tagsBuffer bytes.Buffer // Extracting tag titles - tags := make([]string, 0, len(e.DeepDataMerge.TagsMap)) + tags := make([]template.URL, 0, len(e.DeepDataMerge.TagsMap)) for tag := range e.DeepDataMerge.TagsMap { tags = append(tags, tag) } - slices.SortFunc(tags, func(a, b string) int { - return cmp.Compare(strings.ToLower(a), strings.ToLower(b)) + slices.SortFunc(tags, func(a, b template.URL) int { + return cmp.Compare(strings.ToLower(string(a)), strings.ToLower(string(b))) }) - tagNames := parser.TemplateData{ - FilenameWithoutExtension: "Tags", - Layout: e.DeepDataMerge.LayoutConfig, - Frontmatter: parser.Frontmatter{Title: "Tags"}, - Tags: tags, + tagNames := make([]string, 0, len(tags)) + for _, tag := range tags { + tagString := string(tag) + tagString, _ = strings.CutPrefix(tagString, "tags/") + tagString, _ = strings.CutSuffix(tagString, ".html") + + tagNames = append(tagNames, tagString) + } + + tagRootTemplataData := parser.TemplateData{ + Layout: e.DeepDataMerge.LayoutConfig, + Frontmatter: parser.Frontmatter{Title: "Tags"}, + } + + tagTemplateData := TagRootTemplateData{ + DeepDataMerge: e.DeepDataMerge, + PagePath: "tags.html", + TagTemplateData: tagRootTemplataData, + TagNames: tagNames, } // Rendering the page displaying all tags - err := templ.ExecuteTemplate(&tagsBuffer, "all-tags", tagNames) + err := templ.ExecuteTemplate(&tagsBuffer, "all-tags", tagTemplateData) if err != nil { e.ErrorLogger.Fatal(err) } @@ -51,23 +72,28 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { // Create a wait group to wait for all goroutines to finish var wg sync.WaitGroup + e.DeepDataMerge.Tags = make(map[template.URL]parser.TemplateData) + + for tag := range e.DeepDataMerge.TagsMap { + tagString := string(tag) + tagString, _ = strings.CutPrefix(tagString, "tags/") + tagString, _ = strings.CutSuffix(tagString, ".html") + + e.DeepDataMerge.Tags[tag] = parser.TemplateData{ + Layout: e.DeepDataMerge.LayoutConfig, + Frontmatter: parser.Frontmatter{ + Title: tagString, + }, + } + } + // Rendering the subpages with merged tagged posts for tag, taggedTemplates := range e.DeepDataMerge.TagsMap { wg.Add(1) - go func(tag string, taggedTemplates []parser.TemplateData) { + go func(tag template.URL, taggedTemplates []parser.TemplateData) { defer wg.Done() - pagePath := "tags/" + tag + ".html" - templateData := parser.TemplateData{ - FilenameWithoutExtension: tag, - Layout: e.DeepDataMerge.LayoutConfig, - Frontmatter: parser.Frontmatter{ - Title: tag, - }, - SpecificTagTemplates: taggedTemplates, - } - - e.RenderPage(fileOutPath, template.URL(pagePath), templateData, templ, "tag-subpage") + e.RenderPage(fileOutPath, template.URL(tag), templ, "tag-subpage") }(tag, taggedTemplates) } @@ -90,10 +116,8 @@ func (e *Engine) GenerateJSONIndex(outFilePath string) { jsonIndexTemplate := make(map[template.URL]JSONIndexTemplate) for templateURL, templateData := range e.DeepDataMerge.Templates { jsonIndexTemplate[templateURL] = JSONIndexTemplate{ - CompleteURL: templateData.CompleteURL, - FilenameWithoutExtension: templateData.FilenameWithoutExtension, - Frontmatter: templateData.Frontmatter, - Tags: templateData.Frontmatter.Tags, + CompleteURL: templateData.CompleteURL, + Frontmatter: templateData.Frontmatter, } } @@ -132,7 +156,7 @@ func (e *Engine) GenerateSitemap(outFilePath string) { // Iterate over parsed markdown files for _, templateData := range e.DeepDataMerge.Templates { - url := e.DeepDataMerge.LayoutConfig.BaseURL + "/" + templateData.FilenameWithoutExtension + ".html" + url := e.DeepDataMerge.LayoutConfig.BaseURL + "/" + string(templateData.CompleteURL) buffer.WriteString("\t\n") buffer.WriteString("\t\t" + url + "\n") buffer.WriteString("\t\t" + templateData.Frontmatter.Date + "\n") @@ -165,8 +189,8 @@ func (e *Engine) GenerateFeed() { if !templateData.Frontmatter.Draft { buffer.WriteString("\n") buffer.WriteString(" " + templateData.Frontmatter.Title + "\n") - buffer.WriteString(" \n") - buffer.WriteString(" " + e.DeepDataMerge.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html\n") + buffer.WriteString(" \n") + buffer.WriteString(" " + e.DeepDataMerge.LayoutConfig.BaseURL + string(templateData.CompleteURL) + "\n") buffer.WriteString(" " + time.Unix(templateData.Date, 0).Format(time.RFC3339) + "\n") buffer.WriteString(" \n") buffer.WriteString(" \n") diff --git a/pkg/engine/anna_engine_test.go b/pkg/engine/anna_engine_test.go index 5dcf6b0..39545ec 100644 --- a/pkg/engine/anna_engine_test.go +++ b/pkg/engine/anna_engine_test.go @@ -18,12 +18,12 @@ func TestRenderTags(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) e.DeepDataMerge.LayoutConfig.BaseURL = "example.org" fileOutPath := "../../test/engine/render_tags/" - e.DeepDataMerge.TagsMap["blogs"] = []parser.TemplateData{ + e.DeepDataMerge.TagsMap["tags/blogs.html"] = []parser.TemplateData{ { CompleteURL: "posts/file1.html", Frontmatter: parser.Frontmatter{ @@ -40,7 +40,7 @@ func TestRenderTags(t *testing.T) { }, } - e.DeepDataMerge.TagsMap["tech"] = []parser.TemplateData{ + e.DeepDataMerge.TagsMap["tags/tech.html"] = []parser.TemplateData{ { CompleteURL: "posts/file2.html", Frontmatter: parser.Frontmatter{ @@ -112,9 +112,6 @@ func TestRenderTags(t *testing.T) { } }) - if err := os.RemoveAll(TestDirPath + "render_tags/rendered"); err != nil { - t.Errorf("%v", err) - } } func TestGenerateMergedJson(t *testing.T) { @@ -127,11 +124,10 @@ func TestGenerateMergedJson(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } e.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - e.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + e.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) e.DeepDataMerge.Templates["docs.md"] = parser.TemplateData{ - FilenameWithoutExtension: "docs", - CompleteURL: "docs.html", + CompleteURL: "docs.html", Frontmatter: parser.Frontmatter{ Title: "Anna Documentation", }, @@ -157,9 +153,6 @@ func TestGenerateMergedJson(t *testing.T) { } }) - if err := os.RemoveAll(TestDirPath + "json_index_test/static"); err != nil { - t.Errorf("%v", err) - } } func TestGenerateSitemap(t *testing.T) { @@ -168,24 +161,24 @@ func TestGenerateSitemap(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) t1 := parser.TemplateData{ - FilenameWithoutExtension: "index", + CompleteURL: "index.html", Frontmatter: parser.Frontmatter{ Date: "2024-02-23", }, } t2 := parser.TemplateData{ - FilenameWithoutExtension: "about", + CompleteURL: "about.html", Frontmatter: parser.Frontmatter{ Date: "2024-02-23", }, } t3 := parser.TemplateData{ - FilenameWithoutExtension: "research", + CompleteURL: "research.html", Frontmatter: parser.Frontmatter{ Date: "2024-02-23", }, @@ -223,7 +216,4 @@ func TestGenerateSitemap(t *testing.T) { } }) - if err := os.RemoveAll(TestDirPath + "sitemap/got_sitemap.xml"); err != nil { - t.Errorf("%v", err) - } } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e6da507..e90e3e4 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -11,13 +11,16 @@ import ( ) // This struct holds all of the ssg data -type MergedSiteData struct { +type DeepDataMerge struct { // Templates stores the template data of all the pages of the site // Access the data for a particular page by using the relative path to the file as the key Templates map[template.URL]parser.TemplateData - // K-V pair storing all templates correspoding to a particular tag in the site - TagsMap map[string][]parser.TemplateData + // Templates stores the template data of all tag sub-pages of the site + Tags map[template.URL]parser.TemplateData + + // K-V pair storing all templates corresponding to a particular tag in the site + TagsMap map[template.URL][]parser.TemplateData // Stores data parsed from layout/config.yml LayoutConfig parser.LayoutConfig @@ -31,18 +34,22 @@ type MergedSiteData struct { type Engine struct { // Stores the merged ssg data - DeepDataMerge MergedSiteData + DeepDataMerge DeepDataMerge // Common logger for all engine functions ErrorLogger *log.Logger } +type PageData struct { + DeepDataMerge DeepDataMerge + + PageURL template.URL +} + // This structure is solely used for storing the JSON index type JSONIndexTemplate struct { - CompleteURL template.URL - FilenameWithoutExtension string - Frontmatter parser.Frontmatter - Tags []string + CompleteURL template.URL + Frontmatter parser.Frontmatter } /* @@ -51,13 +58,11 @@ fileOutPath - stores the parent directory to store rendered files, usually `site pagePath - stores the path to write the given page without the prefix directory Eg: site/content/posts/file1.html to be passed as posts/file1.html -pageTemplateData - an interface that accepts any type of data to be passed to ExecuteTemplate() - template - stores the HTML templates parsed from the layout/ directory templateStartString - stores the name of the template to be passed to ExecuteTemplate() */ -func (e *Engine) RenderPage(fileOutPath string, pagePath template.URL, pageTemplateData interface{}, template *template.Template, templateStartString string) { +func (e *Engine) RenderPage(fileOutPath string, pagePath template.URL, template *template.Template, templateStartString string) { // Creating subdirectories if the filepath contains '/' if strings.Contains(string(pagePath), "/") { // Extracting the directory path from the page path @@ -74,8 +79,12 @@ func (e *Engine) RenderPage(fileOutPath string, pagePath template.URL, pageTempl filepath := fileOutPath + "rendered/" + string(pagePath) var buffer bytes.Buffer + pageData := PageData{ + DeepDataMerge: e.DeepDataMerge, + PageURL: pagePath, + } // Storing the rendered HTML file to a buffer - err := template.ExecuteTemplate(&buffer, templateStartString, pageTemplateData) + err := template.ExecuteTemplate(&buffer, templateStartString, pageData) if err != nil { e.ErrorLogger.Fatal(err) } diff --git a/pkg/engine/engine_integration_test.go b/pkg/engine/engine_integration_test.go index 35e2516..2271822 100644 --- a/pkg/engine/engine_integration_test.go +++ b/pkg/engine/engine_integration_test.go @@ -16,19 +16,17 @@ func TestRenderUserDefinedPages(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) - engine.DeepDataMerge.Templates["index.md"] = + engine.DeepDataMerge.Templates["index.html"] = parser.TemplateData{ - FilenameWithoutExtension: "index", - Body: template.HTML("

Index Page

"), - CompleteURL: "index.html", + Body: template.HTML("

Index Page

"), + CompleteURL: "index.html", } - engine.DeepDataMerge.Templates["posts/hello.md"] = parser.TemplateData{ - FilenameWithoutExtension: "hello", - Body: template.HTML("

Hello World

"), - CompleteURL: "posts/hello.html", + engine.DeepDataMerge.Templates["posts/hello.html"] = parser.TemplateData{ + Body: template.HTML("

Hello World

"), + CompleteURL: "posts/hello.html", } if err := os.MkdirAll(TestDirPath+"render_user_defined/rendered", 0750); err != nil { @@ -73,7 +71,4 @@ func TestRenderUserDefinedPages(t *testing.T) { } }) - if err := os.RemoveAll(TestDirPath + "render_user_defined/rendered"); err != nil { - t.Errorf("%v", err) - } } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 21538f8..7c44c17 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -23,11 +23,10 @@ func TestRenderPage(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) - page := parser.TemplateData{ - CompleteURL: template.URL("got"), - FilenameWithoutExtension: "got", + engine.DeepDataMerge.Templates["posts/got.html"] = parser.TemplateData{ + CompleteURL: template.URL("got.html"), Frontmatter: parser.Frontmatter{ Title: "Hello", Date: "2024-03-28", @@ -50,7 +49,7 @@ func TestRenderPage(t *testing.T) { t.Errorf("%v", err) } - engine.RenderPage(TestDirPath+"render_page/", "posts/got.html", page, templ, "page") + engine.RenderPage(TestDirPath+"render_page/", "posts/got.html", templ, "page") got_file, err := os.ReadFile(TestDirPath + "render_page/rendered/posts/got.html") if err != nil { @@ -67,7 +66,4 @@ func TestRenderPage(t *testing.T) { } }) - if err := os.RemoveAll(TestDirPath + "render_page/rendered"); err != nil { - t.Errorf("%v", err) - } } diff --git a/pkg/engine/user_engine.go b/pkg/engine/user_engine.go index 3b10d47..4b19b57 100644 --- a/pkg/engine/user_engine.go +++ b/pkg/engine/user_engine.go @@ -16,7 +16,7 @@ type postsTemplateData struct { parser.TemplateData } -func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, templ *template.Template) { +func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, template *template.Template) { // Rendering "posts.html" var postsBuffer bytes.Buffer @@ -27,8 +27,16 @@ func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, templ *template. Layout: e.DeepDataMerge.LayoutConfig, }, } + // e.DeepDataMerge.Templates["posts.html"] = parser.TemplateData{ + // Frontmatter: parser.Frontmatter{Title: "Posts"}, + // } - err := templ.ExecuteTemplate(&postsBuffer, "posts", postsData) + // pageData := PageData{ + // DeepDataMerge: e.DeepDataMerge, + // PageURL: "posts.html", + // } + + err := template.ExecuteTemplate(&postsBuffer, "posts", postsData) if err != nil { e.ErrorLogger.Fatal(err) } @@ -58,8 +66,7 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp semaphore := make(chan struct{}, concurrency) for _, templateURL := range templateURLs { - templData := e.DeepDataMerge.Templates[template.URL(templateURL)] - fileInPath := strings.TrimSuffix(string(templData.CompleteURL), ".html") + fileInPath := strings.TrimSuffix(templateURL, ".html") if fileInPath == ".html" { continue } @@ -73,7 +80,7 @@ func (e *Engine) RenderUserDefinedPages(fileOutPath string, templ *template.Temp wg.Done() }() - e.RenderPage(fileOutPath, templData.CompleteURL, templData, templ, "page") + e.RenderPage(fileOutPath, template.URL(templateURL), templ, "page") }(templateURL) } diff --git a/pkg/engine/user_engine_test.go b/pkg/engine/user_engine_test.go index 02c29be..1ac3670 100644 --- a/pkg/engine/user_engine_test.go +++ b/pkg/engine/user_engine_test.go @@ -17,11 +17,11 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } engine.DeepDataMerge.Templates = make(map[template.URL]parser.TemplateData) - engine.DeepDataMerge.TagsMap = make(map[string][]parser.TemplateData) + engine.DeepDataMerge.TagsMap = make(map[template.URL][]parser.TemplateData) engine.DeepDataMerge.Posts = []parser.TemplateData{ { - FilenameWithoutExtension: "file1", + CompleteURL: "posts/file1.html", Frontmatter: parser.Frontmatter{ Title: "file1", Description: "Description of file 1", @@ -30,7 +30,7 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { }, { - FilenameWithoutExtension: "file2", + CompleteURL: "posts/file2.html", Frontmatter: parser.Frontmatter{ Title: "file2", Description: "Description of file 2", @@ -39,7 +39,7 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { }, { - FilenameWithoutExtension: "file3", + CompleteURL: "posts/file3.html", Frontmatter: parser.Frontmatter{ Title: "file3", Description: "Description of file 3", @@ -74,8 +74,4 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { t.Errorf("The expected and generated posts.html can be found in test/engine/render_engine_generated/rendered/") } }) - - if err := os.RemoveAll(TestDirPath + "render_engine_generated/rendered"); err != nil { - t.Errorf("%v", err) - } } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index db7c7e9..e574afb 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -40,17 +40,11 @@ type Frontmatter struct { // This struct holds all of the data required to render any page of the site type TemplateData struct { - CompleteURL template.URL - FilenameWithoutExtension string - Date int64 - Frontmatter Frontmatter - Body template.HTML - Layout LayoutConfig - - // Do not use these fields to store tags!! - // These fields are populated by the ssg to store merged tag data - Tags []string - SpecificTagTemplates []TemplateData + CompleteURL template.URL + Date int64 + Frontmatter Frontmatter + Body template.HTML + Layout LayoutConfig } type Date int64 @@ -61,7 +55,7 @@ type Parser struct { Templates map[template.URL]TemplateData // K-V pair storing all templates correspoding to a particular tag in the site - TagsMap map[string][]TemplateData + TagsMap map[template.URL][]TemplateData // Stores data parsed from layout/config.yml LayoutConfig LayoutConfig @@ -128,13 +122,13 @@ func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, front if frontmatter.Type == "post" { url = "posts/" + url } + page := TemplateData{ - CompleteURL: template.URL(url), - Date: date, - FilenameWithoutExtension: strings.Split(dirEntryPath, ".")[0], - Frontmatter: frontmatter, - Body: template.HTML(body), - Layout: p.LayoutConfig, + CompleteURL: template.URL(url), + Date: date, + Frontmatter: frontmatter, + Body: template.HTML(body), + Layout: p.LayoutConfig, } // Adding the page to the merged map storing all site pages @@ -142,11 +136,12 @@ func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, front p.Posts = append(p.Posts, page) } - p.Templates[template.URL(key)] = page + p.Templates[template.URL(url)] = page // Adding the page to the tags map with the corresponding tags for _, tag := range page.Frontmatter.Tags { - p.TagsMap[tag] = append(p.TagsMap[tag], page) + tagsMapKey := "tags/" + tag + ".html" + p.TagsMap[template.URL(tagsMapKey)] = append(p.TagsMap[template.URL(tagsMapKey)], page) } } diff --git a/pkg/parser/parser_integration_test.go b/pkg/parser/parser_integration_test.go index cf863f8..bbbb40e 100644 --- a/pkg/parser/parser_integration_test.go +++ b/pkg/parser/parser_integration_test.go @@ -13,7 +13,7 @@ func TestParseMDDir(t *testing.T) { t.Run("reading markdown files and rendering without drafts", func(t *testing.T) { p := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } p.RenderDrafts = false @@ -33,7 +33,7 @@ func TestParseMDDir(t *testing.T) { t.Run("reading all markdown files inluding drafts", func(t *testing.T) { p := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } p.RenderDrafts = true diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index ea60dc4..8c6d7b9 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -16,7 +16,7 @@ const TestDirPath = "../../test/parser/" func TestAddFileandRender(t *testing.T) { got_parser := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } @@ -34,10 +34,11 @@ func TestAddFileandRender(t *testing.T) { } want_parser := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: got_parser.ErrorLogger, } - sample_frontmatter, sample_body, parseSuccess := got_parser.ParseMarkdownContent(string(inputMd)) + sample_frontmatter, _, parseSuccess := got_parser.ParseMarkdownContent(string(inputMd)) + sample_body := "sample_body" if !parseSuccess { return } @@ -47,18 +48,17 @@ func TestAddFileandRender(t *testing.T) { want_parser.MdFilesName = append(want_parser.MdFilesName, filename) want_parser.MdFilesPath = append(want_parser.MdFilesPath, filename) want_page := parser.TemplateData{ - CompleteURL: template.URL(fileurl), - Date: want_parser.DateParse(sample_frontmatter.Date).Unix(), - FilenameWithoutExtension: "testpost", - Frontmatter: sample_frontmatter, - Body: template.HTML(sample_body), - Layout: want_layout, + CompleteURL: template.URL(fileurl), + Date: want_parser.DateParse(sample_frontmatter.Date).Unix(), + Frontmatter: sample_frontmatter, + Body: template.HTML(sample_body), + Layout: want_layout, } want_parser.LayoutConfig = want_layout - want_parser.Templates[template.URL("testpost.md")] = want_page + want_parser.Templates[template.URL("posts/testpost.html")] = want_page for _, tag := range sample_frontmatter.Tags { - want_parser.TagsMap[tag] = append(want_parser.TagsMap[tag], want_page) + want_parser.TagsMap[template.URL(tag)] = append(want_parser.TagsMap[template.URL(tag)], want_page) } if sample_frontmatter.Type == "post" { @@ -69,6 +69,7 @@ func TestAddFileandRender(t *testing.T) { if !reflect.DeepEqual(got_parser, want_parser) { t.Errorf("want %v; \ngot %v", want_parser, got_parser) + // t.Errorf("please see the files yourself") } }) } @@ -76,7 +77,7 @@ func TestAddFileandRender(t *testing.T) { func TestParseMarkdownContent(t *testing.T) { p := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } t.Run("render markdown files to html", func(t *testing.T) { @@ -126,7 +127,7 @@ func TestParseConfig(t *testing.T) { t.Run("unmarshal `config.yml` to LayoutConfig", func(t *testing.T) { got_parser := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } @@ -149,7 +150,7 @@ func TestParseRobots(t *testing.T) { t.Run("parse and render `robots.txt`", func(t *testing.T) { parser := parser.Parser{ Templates: make(map[template.URL]parser.TemplateData), - TagsMap: make(map[string][]parser.TemplateData), + TagsMap: make(map[template.URL][]parser.TemplateData), ErrorLogger: log.New(os.Stderr, "TEST ERROR\t", log.Ldate|log.Ltime|log.Lshortfile), } parser.LayoutConfig.BaseURL = "example.org" diff --git a/site/content/posts/markdown_test.md b/site/content/posts/markdown_test.md index 686ad71..4edfdce 100644 --- a/site/content/posts/markdown_test.md +++ b/site/content/posts/markdown_test.md @@ -1,27 +1,242 @@ --- title: Sample Post -author: John Doe date: 2024-02-23 -categories: - - Technology - - Programming -scripts: type: post draft: true tags: - - test-post + - testing --- -# heading L1 +# h1 Heading 8-) +## h2 Heading +### h3 Heading +#### h4 Heading +##### h5 Heading +###### h6 Heading -Lorem ipsum dolor sit amet, officia excepteur ex fugiat reprehenderit enim -labore culpa sint ad nisi Lorem pariatur mollit ex esse exercitation amet. Nisi -anim cupidatat excepteur officia. Reprehenderit nostrud nostrud ipsum Lorem est -aliquip amet voluptate voluptate dolor minim nulla est proident. Nostrud -officia pariatur ut officia. Sit irure elit esse ea nulla sunt ex occaecat -## heading L2 +## Horizontal Rules -**_bold and italics_** +___ -> quote text +--- + +*** + + +## Typographic replacements + +Enable typographer option to see result. + +(c) (C) (r) (R) (tm) (TM) (p) (P) +- + +test.. test... test..... test?..... test!.... + +!!!!!! ???? ,, -- --- + +"Smartypants, double quotes" and 'single quotes' + + +## Emphasis + +**This is bold text** + +__This is bold text__ + +*This is italic text* + +_This is italic text_ + +~~Strikethrough~~ + + +## Blockquotes + + +> Blockquotes can also be nested... +>> ...by using additional greater-than signs right next to each other... +> > > ...or with spaces between arrows. + + +## Lists + +Unordered + ++ Create a list by starting a line with `+`, `-`, or `*` ++ Sub-lists are made by indenting 2 spaces: + - Marker character change forces new list start: + * Ac tristique libero volutpat at + + Facilisis in pretium nisl aliquet + - Nulla volutpat aliquam velit ++ Very easy! + +Ordered + +1. Lorem ipsum dolor sit amet +2. Consectetur adipiscing elit +3. Integer molestie lorem at massa + + +1. You can use sequential numbers... +1. ...or keep all the numbers as `1.` + +Start numbering with offset: + +57. foo +1. bar + + +## Code + +Inline `code` + +Indented code + + // Some comments + line 1 of code + line 2 of code + line 3 of code + + +Block code "fences" + +``` +Sample text here... +``` + +Syntax highlighting + +``` js +var foo = function (bar) { + return bar++; +}; + +console.log(foo(5)); +``` + +## Tables + +| Option | Description | +| ------ | ----------- | +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + +Right aligned columns + +| Option | Description | +| ------:| -----------:| +| data | path to data files to supply the data that will be passed into templates. | +| engine | engine to be used for processing templates. Handlebars is the default. | +| ext | extension to be used for dest files. | + + +## Links + +[link text](http://dev.nodeca.com) + +[link with title](http://nodeca.github.io/pica/demo/ "title text!") + +Autoconverted link https://github.com/nodeca/pica (enable linkify to see) + + +## Images + +![Minion](https://octodex.github.com/images/minion.png) +![Stormtroopocat](https://octodex.github.com/images/stormtroopocat.jpg "The Stormtroopocat") + +Like links, Images also have a footnote style syntax + +![Alt text][id] + +With a reference later in the document defining the URL location: + +[id]: https://octodex.github.com/images/dojocat.jpg "The Dojocat" + + +## Plugins + +The killer feature of `markdown-it` is very effective support of +[syntax plugins](https://www.npmjs.org/browse/keyword/markdown-it-plugin). + + +### [Emojies](https://github.com/markdown-it/markdown-it-emoji) + +> Classic markup: :wink: :cry: :laughing: :yum: +> +> Shortcuts (emoticons): :-) :-( 8-) ;) + +see [how to change output](https://github.com/markdown-it/markdown-it-emoji#change-output) with twemoji. + + +### [Subscript](https://github.com/markdown-it/markdown-it-sub) / [Superscript](https://github.com/markdown-it/markdown-it-sup) + +- 19^th^ +- H~2~O + + +### [\](https://github.com/markdown-it/markdown-it-ins) + +++Inserted text++ + + +### [\](https://github.com/markdown-it/markdown-it-mark) + +==Marked text== + + +### [Footnotes](https://github.com/markdown-it/markdown-it-footnote) + +Footnote 1 link[^first]. + +Footnote 2 link[^second]. + +Inline footnote^[Text of inline footnote] definition. + +Duplicated footnote reference[^second]. + +[^first]: Footnote **can have markup** + + and multiple paragraphs. + +[^second]: Footnote text. + + +### [Definition lists](https://github.com/markdown-it/markdown-it-deflist) + +Term 1 + +: Definition 1 +with lazy continuation. + +Term 2 with *inline markup* + +: Definition 2 + + { some code, part of Definition 2 } + + Third paragraph of definition 2. + +_Compact style:_ + +Term 1 + ~ Definition 1 + +Term 2 + ~ Definition 2a + ~ Definition 2b + + +### [Abbreviations](https://github.com/markdown-it/markdown-it-abbr) + +This is HTML abbreviation example. + +It converts "HTML", but keep intact partial entries like "xxxHTMLyyy" and so on. + +*[HTML]: Hyper Text Markup Language + +### [Custom containers](https://github.com/markdown-it/markdown-it-container) + +::: warning +*here be dragons* +::: diff --git a/site/layout/page.layout b/site/layout/page.layout index 84a2478..3ffc6eb 100644 --- a/site/layout/page.layout +++ b/site/layout/page.layout @@ -1,29 +1,30 @@ {{ define "page"}} -{{ template "head" .}} +{{$PageData := index .DeepDataMerge.Templates .PageURL}} +{{ template "head" $PageData}} - {{template "header" .}} + {{template "header" $PageData}}
- {{ if eq .Frontmatter.Type "post" }} + {{ if eq $PageData.Frontmatter.Type "post" }}
-

{{ .Frontmatter.Title }}

+

{{ $PageData.Frontmatter.Title }}

- Published on {{.Frontmatter.Date}} + Published on {{$PageData.Frontmatter.Date}} - {{ if eq (len .Frontmatter.Authors) 0 }} - {{$.Layout.Author}} + {{ if eq (len $PageData.Frontmatter.Authors) 0 }} + {{.DeepDataMerge.LayoutConfig.Author}} {{ else }} - {{range .Frontmatter.Authors }} + {{range $PageData.Frontmatter.Authors }} {{ . }}, {{ end }} {{ end }}

- {{range .Frontmatter.Tags}} + {{range $PageData.Frontmatter.Tags}} @@ -32,12 +33,12 @@
{{ else }} {{ end }} - {{.Body}} + {{$PageData.Body}}
- {{template "footer" .}} + {{template "footer" $PageData}} -{{ end}} \ No newline at end of file +{{ end}} diff --git a/site/layout/posts.layout b/site/layout/posts.layout index 255fd71..c0e3fd5 100644 --- a/site/layout/posts.layout +++ b/site/layout/posts.layout @@ -7,7 +7,7 @@
{{range $PostDate, $Post := .Posts}} - +

{{$Post.Frontmatter.Title}}

{{$Post.Frontmatter.Description}}

diff --git a/site/layout/tag-subpage.layout b/site/layout/tag-subpage.layout index 2fc403c..bc11c87 100644 --- a/site/layout/tag-subpage.layout +++ b/site/layout/tag-subpage.layout @@ -1,22 +1,24 @@ {{ define "tag-subpage"}} -{{ template "head" .}} +{{$PageData := index .DeepDataMerge.Tags .PageURL}} +{{ template "head" $PageData}} - {{template "header" .}} + {{template "header" $PageData}}
- {{template "footer" .}} + {{template "footer" $PageData}} -{{ end}} \ No newline at end of file +{{ end}} diff --git a/site/layout/tags.layout b/site/layout/tags.layout index 3aa6dce..6837776 100644 --- a/site/layout/tags.layout +++ b/site/layout/tags.layout @@ -1,14 +1,15 @@ {{ define "all-tags"}} -{{ template "head" .}} +{{$PageData := .TagTemplateData}} +{{ template "head" $PageData}} - {{template "header" .}} +{{template "header" $PageData}}
- {{range .Tags}} - {{.}} + {{range .TagNames}} + {{.}} {{end}}
@@ -19,7 +20,7 @@ - {{template "footer" .}} + {{template "footer" $PageData}} diff --git a/site/static/index.json b/site/static/index.json index 33cad2e..61c8828 100644 --- a/site/static/index.json +++ b/site/static/index.json @@ -1 +1,100 @@ -{"bench.md":{"CompleteURL":"posts/bench.html","FilenameWithoutExtension":"bench","Frontmatter":{"Title":"benchmark","Date":"2024-01-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["test-post"],"Authors":null},"Tags":["test-post"]},"building_anna.md":{"CompleteURL":"posts/building_anna.html","FilenameWithoutExtension":"building_anna","Frontmatter":{"Title":"Building anna","Date":"2024-04-04","Draft":false,"JSFiles":null,"Type":"post","Description":"This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024","PreviewImage":"","Tags":["acm","hsp","go","tech","talk","aiep"],"Authors":["Adhesh","Aditya","Nathan","Anirudh"]},"Tags":["acm","hsp","go","tech","talk","aiep"]},"docs.md":{"CompleteURL":"docs.html","FilenameWithoutExtension":"docs","Frontmatter":{"Title":"Anna Documentation","Date":"2024-04-10","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null},"index.md":{"CompleteURL":"index.html","FilenameWithoutExtension":"index","Frontmatter":{"Title":"Home","Date":"2024-02-24","Draft":false,"JSFiles":null,"Type":"","Description":"homepage for our ssg","PreviewImage":"/static/plane.jpg","Tags":null,"Authors":null},"Tags":null},"week-1.md":{"CompleteURL":"posts/week-1.html","FilenameWithoutExtension":"week-1","Frontmatter":{"Title":"Week-1 Progress","Date":"2024-03-18","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"week-2.md":{"CompleteURL":"posts/week-2.html","FilenameWithoutExtension":"week-2","Frontmatter":{"Title":"Week-2 Progress","Date":"2024-03-25","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"week-3.md":{"CompleteURL":"posts/week-3.html","FilenameWithoutExtension":"week-3","Frontmatter":{"Title":"Week-3 Progress","Date":"2024-04-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]}} \ No newline at end of file +{ + "docs.html": { + "CompleteURL": "docs.html", + "Frontmatter": { + "Title": "Anna Documentation", + "Date": "2024-04-10", + "Draft": false, + "JSFiles": null, + "Type": "", + "Description": "", + "PreviewImage": "", + "Tags": null, + "Authors": null + } + }, + "index.html": { + "CompleteURL": "index.html", + "Frontmatter": { + "Title": "Home", + "Date": "2024-02-24", + "Draft": false, + "JSFiles": null, + "Type": "", + "Description": "homepage for our ssg", + "PreviewImage": "/static/plane.jpg", + "Tags": null, + "Authors": null + } + }, + "posts/bench.html": { + "CompleteURL": "posts/bench.html", + "Frontmatter": { + "Title": "benchmark", + "Date": "2024-01-01", + "Draft": false, + "JSFiles": null, + "Type": "post", + "Description": "", + "PreviewImage": "", + "Tags": ["test-post"], + "Authors": null + } + }, + "posts/building_anna.html": { + "CompleteURL": "posts/building_anna.html", + "Frontmatter": { + "Title": "Building anna", + "Date": "2024-04-04", + "Draft": false, + "JSFiles": null, + "Type": "post", + "Description": "This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024", + "PreviewImage": "", + "Tags": ["acm", "hsp", "go", "tech", "talk", "aiep"], + "Authors": ["Adhesh", "Aditya", "Nathan", "Anirudh"] + } + }, + "posts/week-1.html": { + "CompleteURL": "posts/week-1.html", + "Frontmatter": { + "Title": "Week-1 Progress", + "Date": "2024-03-18", + "Draft": false, + "JSFiles": null, + "Type": "post", + "Description": "", + "PreviewImage": "", + "Tags": ["progress"], + "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] + } + }, + "posts/week-2.html": { + "CompleteURL": "posts/week-2.html", + "Frontmatter": { + "Title": "Week-2 Progress", + "Date": "2024-03-25", + "Draft": false, + "JSFiles": null, + "Type": "post", + "Description": "", + "PreviewImage": "", + "Tags": ["progress"], + "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] + } + }, + "posts/week-3.html": { + "CompleteURL": "posts/week-3.html", + "Frontmatter": { + "Title": "Week-3 Progress", + "Date": "2024-04-01", + "Draft": false, + "JSFiles": null, + "Type": "post", + "Description": "", + "PreviewImage": "", + "Tags": ["progress"], + "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] + } + } +} diff --git a/test/engine/json_index_test/want_index.json b/test/engine/json_index_test/want_index.json index c8c3fa1..a6f6b45 100644 --- a/test/engine/json_index_test/want_index.json +++ b/test/engine/json_index_test/want_index.json @@ -1,2 +1 @@ -{"docs.md":{"CompleteURL":"docs.html","FilenameWithoutExtension":"docs","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null}} - +{"docs.md":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null}}} diff --git a/test/engine/render_engine_generated/posts_template.layout b/test/engine/render_engine_generated/posts_template.layout index 83673a2..12b2fa0 100644 --- a/test/engine/render_engine_generated/posts_template.layout +++ b/test/engine/render_engine_generated/posts_template.layout @@ -4,7 +4,7 @@
{{range $PostDate, $Post := .Posts}} - +

{{$Post.Frontmatter.Title}}

diff --git a/test/engine/render_page/template_input.layout b/test/engine/render_page/template_input.layout index d10c4ad..028c8e0 100644 --- a/test/engine/render_page/template_input.layout +++ b/test/engine/render_page/template_input.layout @@ -1,15 +1,39 @@ {{ define "page"}} - - +{{$PageData := index .DeepDataMerge.Templates .PageURL}} + -
-{{.Body}} + +
+
+ {{ if eq $PageData.Frontmatter.Type "post" }} +
+

{{ $PageData.Frontmatter.Title }}

+
+

+ Published on {{$PageData.Frontmatter.Date}} + + {{ if eq (len $PageData.Frontmatter.Authors) 0 }} + {{.DeepDataMerge.LayoutConfig.Author}} + {{ else }} + {{range $PageData.Frontmatter.Authors }} + {{ . }}, + {{ end }} + {{ end }} +

+
+
+ {{range $PageData.Frontmatter.Tags}} +
+ {{.}} +
+ {{end}} +
+
+ {{ else }} + {{ end }} + {{$PageData.Body}} +
+
- -{{end}} + +{{ end}} diff --git a/test/engine/render_page/want.html b/test/engine/render_page/want.html index 6cfcd99..74a18c8 100644 --- a/test/engine/render_page/want.html +++ b/test/engine/render_page/want.html @@ -1,18 +1,37 @@ - - - -
-
-blog -
- + -
-

Hello World

+
+
+ +
+

Hello

+
+

+ Published on 2024-03-28 + + + + +

+
+
+ +
+ blog +
+ +
+ thoughts +
+ +
+
+ +

Hello World

+
+
- + diff --git a/test/engine/render_tags/tags_subpage_template.layout b/test/engine/render_tags/tags_subpage_template.layout index 3a3e44b..db17318 100644 --- a/test/engine/render_tags/tags_subpage_template.layout +++ b/test/engine/render_tags/tags_subpage_template.layout @@ -1,12 +1,18 @@ {{ define "tag-subpage"}} +{{$PageData := index .DeepDataMerge.Tags .PageURL}} + -
-
-{{ range .SpecificTagTemplates }} -{{ .Frontmatter.Title }} -{{ end }} -
-
+ +
+
+
+ {{$TagSet := index .DeepDataMerge.TagsMap .PageURL}} + {{range $TagSet }} + {{.Frontmatter.Title}} + {{end}} +
+
+
+ - -{{ end }} +{{ end}} diff --git a/test/engine/render_tags/tags_template.layout b/test/engine/render_tags/tags_template.layout index cb350e1..ed5f1ba 100644 --- a/test/engine/render_tags/tags_template.layout +++ b/test/engine/render_tags/tags_template.layout @@ -1,12 +1,25 @@ {{ define "all-tags"}} +{{$PageData := .TagTemplateData}} + -
-
-{{ range .Tags }} -{{.}} -{{end}} -
-
+
+
+
+
+ {{range .TagNames}} + {{.}} + {{end}} +
+
+
+
+ +
+ + + + -{{ end }} + +{{ end}} diff --git a/test/engine/render_tags/want_blogs_tags.html b/test/engine/render_tags/want_blogs_tags.html index 3d48ac2..417ba83 100644 --- a/test/engine/render_tags/want_blogs_tags.html +++ b/test/engine/render_tags/want_blogs_tags.html @@ -1,13 +1,19 @@ - -
-
-file1 -file2 + + +
+ +
-
-
- diff --git a/test/engine/render_tags/want_tags.html b/test/engine/render_tags/want_tags.html index 1c73adc..243f780 100644 --- a/test/engine/render_tags/want_tags.html +++ b/test/engine/render_tags/want_tags.html @@ -1,13 +1,26 @@ - -
-
-blogs -tech + +
+ +
+ +
+ + -
-
+ + diff --git a/test/engine/render_tags/want_tech_tags.html b/test/engine/render_tags/want_tech_tags.html index 88497f7..1dbd4e7 100644 --- a/test/engine/render_tags/want_tech_tags.html +++ b/test/engine/render_tags/want_tech_tags.html @@ -1,13 +1,19 @@ - -
-
-file2 -file3 + + +
+ +
-
-
- diff --git a/test/engine/render_user_defined/template_input.layout b/test/engine/render_user_defined/template_input.layout index d10c4ad..86f9ef2 100644 --- a/test/engine/render_user_defined/template_input.layout +++ b/test/engine/render_user_defined/template_input.layout @@ -1,15 +1,41 @@ {{ define "page"}} - - +{{$PageData := index .DeepDataMerge.Templates .PageURL}} + -
-{{range .Frontmatter.Tags}} -
-{{.}} -
-{{end}} -
-{{.Body}} + +
+
+ {{ if eq $PageData.Frontmatter.Type "post" }} +
+

{{ $PageData.Frontmatter.Title }}

+
+

+ Published on {{$PageData.Frontmatter.Date}} + + {{ if eq (len $PageData.Frontmatter.Authors) 0 }} + {{.DeepDataMerge.LayoutConfig.Author}} + {{ else }} + {{range $PageData.Frontmatter.Authors }} + {{ . }}, + {{ end }} + {{ end }} +

+
+
+ {{range $PageData.Frontmatter.Tags}} +
+ {{.}} +
+ {{end}} +
+
+ {{ else }} + {{ end }} + {{$PageData.Body}} +
+
+ -{{end}} + +{{ end}} diff --git a/test/engine/render_user_defined/want_index.html b/test/engine/render_user_defined/want_index.html index c3dcf98..b6923df 100644 --- a/test/engine/render_user_defined/want_index.html +++ b/test/engine/render_user_defined/want_index.html @@ -1,10 +1,16 @@ - - + + -
-
-

Index Page

+
+
+ + +

Index Page

+
+
+ + diff --git a/test/engine/render_user_defined/want_post_hello.html b/test/engine/render_user_defined/want_post_hello.html index d4fc935..3364574 100644 --- a/test/engine/render_user_defined/want_post_hello.html +++ b/test/engine/render_user_defined/want_post_hello.html @@ -1,10 +1,16 @@ - - + + -
-
-

Hello World

+
+
+ + +

Hello World

+
+
+ + diff --git a/test_clean.sh b/test_clean.sh new file mode 100644 index 0000000..0b34da1 --- /dev/null +++ b/test_clean.sh @@ -0,0 +1,5 @@ +#This script can be utilised to clean the test output data + +cd test/ +rm -rf `find . -type d -name rendered` +cd ../ \ No newline at end of file From fd618a312180bf3a53f20e71e7c0781bcc63eb9b Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 20:45:30 +0530 Subject: [PATCH 4/6] chore: switch layouts to html --- cmd/anna/anna.go | 4 +- pkg/engine/anna_engine.go | 1 + pkg/engine/anna_engine_test.go | 2 +- pkg/engine/engine.go | 1 + pkg/engine/engine_integration_test.go | 2 +- pkg/engine/engine_test.go | 2 +- pkg/engine/user_engine_test.go | 2 +- pkg/parser/parser.go | 4 +- site/layout/{page.layout => page.html} | 0 .../partials/{footer.layout => footer.html} | 0 .../partials/{head.layout => head.html} | 0 .../partials/{header.layout => header.html} | 0 .../partials/{search.layout => search.html} | 0 site/layout/{posts.layout => posts.html} | 0 .../{tag-subpage.layout => tag-subpage.html} | 0 site/layout/{tags.layout => tags.html} | 0 site/static/index.json | 101 +----------------- test/engine/json_index_test/want_index.json | 2 +- ...ts_template.layout => posts_template.html} | 0 ...plate_input.layout => template_input.html} | 0 ...late.layout => tags_subpage_template.html} | 0 ...ags_template.layout => tags_template.html} | 0 ...plate_input.layout => template_input.html} | 0 23 files changed, 12 insertions(+), 109 deletions(-) rename site/layout/{page.layout => page.html} (100%) rename site/layout/partials/{footer.layout => footer.html} (100%) rename site/layout/partials/{head.layout => head.html} (100%) rename site/layout/partials/{header.layout => header.html} (100%) rename site/layout/partials/{search.layout => search.html} (100%) rename site/layout/{posts.layout => posts.html} (100%) rename site/layout/{tag-subpage.layout => tag-subpage.html} (100%) rename site/layout/{tags.layout => tags.html} (100%) rename test/engine/render_engine_generated/{posts_template.layout => posts_template.html} (100%) rename test/engine/render_page/{template_input.layout => template_input.html} (100%) rename test/engine/render_tags/{tags_subpage_template.layout => tags_subpage_template.html} (100%) rename test/engine/render_tags/{tags_template.layout => tags_template.html} (100%) rename test/engine/render_user_defined/{template_input.layout => template_input.html} (100%) diff --git a/cmd/anna/anna.go b/cmd/anna/anna.go index ecc118d..95a5d9c 100644 --- a/cmd/anna/anna.go +++ b/cmd/anna/anna.go @@ -62,12 +62,12 @@ func (cmd *Cmd) VanillaRender() { return e.DeepDataMerge.Posts[i].Frontmatter.Date > e.DeepDataMerge.Posts[j].Frontmatter.Date }) - templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.layout") + templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.html") if err != nil { e.ErrorLogger.Fatalf("%v", err) } - templ, err = templ.ParseGlob(helpers.SiteDataPath + "layout/partials/*.layout") + templ, err = templ.ParseGlob(helpers.SiteDataPath + "layout/partials/*.html") if err != nil { e.ErrorLogger.Fatalf("%v", err) } diff --git a/pkg/engine/anna_engine.go b/pkg/engine/anna_engine.go index c0b0aa1..2101d37 100644 --- a/pkg/engine/anna_engine.go +++ b/pkg/engine/anna_engine.go @@ -118,6 +118,7 @@ func (e *Engine) GenerateJSONIndex(outFilePath string) { jsonIndexTemplate[templateURL] = JSONIndexTemplate{ CompleteURL: templateData.CompleteURL, Frontmatter: templateData.Frontmatter, + Tags: templateData.Frontmatter.Tags, } } diff --git a/pkg/engine/anna_engine_test.go b/pkg/engine/anna_engine_test.go index 39545ec..4d1636b 100644 --- a/pkg/engine/anna_engine_test.go +++ b/pkg/engine/anna_engine_test.go @@ -57,7 +57,7 @@ func TestRenderTags(t *testing.T) { }, } - templ, err := template.ParseFiles(TestDirPath+"render_tags/tags_template.layout", TestDirPath+"render_tags/tags_subpage_template.layout") + templ, err := template.ParseFiles(TestDirPath+"render_tags/tags_template.html", TestDirPath+"render_tags/tags_subpage_template.html") if err != nil { t.Errorf("%v", err) } diff --git a/pkg/engine/engine.go b/pkg/engine/engine.go index e90e3e4..4bbcfda 100644 --- a/pkg/engine/engine.go +++ b/pkg/engine/engine.go @@ -50,6 +50,7 @@ type PageData struct { type JSONIndexTemplate struct { CompleteURL template.URL Frontmatter parser.Frontmatter + Tags []string } /* diff --git a/pkg/engine/engine_integration_test.go b/pkg/engine/engine_integration_test.go index 2271822..a1e7b2a 100644 --- a/pkg/engine/engine_integration_test.go +++ b/pkg/engine/engine_integration_test.go @@ -35,7 +35,7 @@ func TestRenderUserDefinedPages(t *testing.T) { t.Run("render a set of user defined pages", func(t *testing.T) { - templ, err := template.ParseFiles(TestDirPath + "render_user_defined/template_input.layout") + templ, err := template.ParseFiles(TestDirPath + "render_user_defined/template_input.html") if err != nil { t.Errorf("%v", err) } diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 7c44c17..682abfd 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -44,7 +44,7 @@ func TestRenderPage(t *testing.T) { }, } - templ, err := template.ParseFiles(TestDirPath + "render_page/template_input.layout") + templ, err := template.ParseFiles(TestDirPath + "render_page/template_input.html") if err != nil { t.Errorf("%v", err) } diff --git a/pkg/engine/user_engine_test.go b/pkg/engine/user_engine_test.go index 1ac3670..9aa5e40 100644 --- a/pkg/engine/user_engine_test.go +++ b/pkg/engine/user_engine_test.go @@ -53,7 +53,7 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { } t.Run("test rendering of post.html", func(t *testing.T) { - templ, err := template.ParseFiles(TestDirPath + "render_engine_generated/posts_template.layout") + templ, err := template.ParseFiles(TestDirPath + "render_engine_generated/posts_template.html") if err != nil { t.Errorf("%v", err) } diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index e574afb..736f603 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -250,13 +250,13 @@ func (p *Parser) ParseRobots(inFilePath string, outFilePath string) { func (p *Parser) ParseLayoutFiles() *template.Template { // Parsing all files in the layout/ dir which match the "*.html" pattern - templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.layout") + templ, err := template.ParseGlob(helpers.SiteDataPath + "layout/*.html") if err != nil { p.ErrorLogger.Fatal(err) } // Parsing all files in the partials/ dir which match the "*.html" pattern - templ, err = templ.ParseGlob(helpers.SiteDataPath + "layout/partials/*.layout") + templ, err = templ.ParseGlob(helpers.SiteDataPath + "layout/partials/*.html") if err != nil { p.ErrorLogger.Fatal(err) } diff --git a/site/layout/page.layout b/site/layout/page.html similarity index 100% rename from site/layout/page.layout rename to site/layout/page.html diff --git a/site/layout/partials/footer.layout b/site/layout/partials/footer.html similarity index 100% rename from site/layout/partials/footer.layout rename to site/layout/partials/footer.html diff --git a/site/layout/partials/head.layout b/site/layout/partials/head.html similarity index 100% rename from site/layout/partials/head.layout rename to site/layout/partials/head.html diff --git a/site/layout/partials/header.layout b/site/layout/partials/header.html similarity index 100% rename from site/layout/partials/header.layout rename to site/layout/partials/header.html diff --git a/site/layout/partials/search.layout b/site/layout/partials/search.html similarity index 100% rename from site/layout/partials/search.layout rename to site/layout/partials/search.html diff --git a/site/layout/posts.layout b/site/layout/posts.html similarity index 100% rename from site/layout/posts.layout rename to site/layout/posts.html diff --git a/site/layout/tag-subpage.layout b/site/layout/tag-subpage.html similarity index 100% rename from site/layout/tag-subpage.layout rename to site/layout/tag-subpage.html diff --git a/site/layout/tags.layout b/site/layout/tags.html similarity index 100% rename from site/layout/tags.layout rename to site/layout/tags.html diff --git a/site/static/index.json b/site/static/index.json index 61c8828..8dfa96c 100644 --- a/site/static/index.json +++ b/site/static/index.json @@ -1,100 +1 @@ -{ - "docs.html": { - "CompleteURL": "docs.html", - "Frontmatter": { - "Title": "Anna Documentation", - "Date": "2024-04-10", - "Draft": false, - "JSFiles": null, - "Type": "", - "Description": "", - "PreviewImage": "", - "Tags": null, - "Authors": null - } - }, - "index.html": { - "CompleteURL": "index.html", - "Frontmatter": { - "Title": "Home", - "Date": "2024-02-24", - "Draft": false, - "JSFiles": null, - "Type": "", - "Description": "homepage for our ssg", - "PreviewImage": "/static/plane.jpg", - "Tags": null, - "Authors": null - } - }, - "posts/bench.html": { - "CompleteURL": "posts/bench.html", - "Frontmatter": { - "Title": "benchmark", - "Date": "2024-01-01", - "Draft": false, - "JSFiles": null, - "Type": "post", - "Description": "", - "PreviewImage": "", - "Tags": ["test-post"], - "Authors": null - } - }, - "posts/building_anna.html": { - "CompleteURL": "posts/building_anna.html", - "Frontmatter": { - "Title": "Building anna", - "Date": "2024-04-04", - "Draft": false, - "JSFiles": null, - "Type": "post", - "Description": "This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024", - "PreviewImage": "", - "Tags": ["acm", "hsp", "go", "tech", "talk", "aiep"], - "Authors": ["Adhesh", "Aditya", "Nathan", "Anirudh"] - } - }, - "posts/week-1.html": { - "CompleteURL": "posts/week-1.html", - "Frontmatter": { - "Title": "Week-1 Progress", - "Date": "2024-03-18", - "Draft": false, - "JSFiles": null, - "Type": "post", - "Description": "", - "PreviewImage": "", - "Tags": ["progress"], - "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] - } - }, - "posts/week-2.html": { - "CompleteURL": "posts/week-2.html", - "Frontmatter": { - "Title": "Week-2 Progress", - "Date": "2024-03-25", - "Draft": false, - "JSFiles": null, - "Type": "post", - "Description": "", - "PreviewImage": "", - "Tags": ["progress"], - "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] - } - }, - "posts/week-3.html": { - "CompleteURL": "posts/week-3.html", - "Frontmatter": { - "Title": "Week-3 Progress", - "Date": "2024-04-01", - "Draft": false, - "JSFiles": null, - "Type": "post", - "Description": "", - "PreviewImage": "", - "Tags": ["progress"], - "Authors": ["Adhesh", "Aditya", "Anirudh", "Nathan"] - } - } -} +{"docs.html":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"2024-04-10","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null},"index.html":{"CompleteURL":"index.html","Frontmatter":{"Title":"Home","Date":"2024-02-24","Draft":false,"JSFiles":null,"Type":"","Description":"homepage for our ssg","PreviewImage":"/static/plane.jpg","Tags":null,"Authors":null},"Tags":null},"posts/bench.html":{"CompleteURL":"posts/bench.html","Frontmatter":{"Title":"benchmark","Date":"2024-01-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["test-post"],"Authors":null},"Tags":["test-post"]},"posts/building_anna.html":{"CompleteURL":"posts/building_anna.html","Frontmatter":{"Title":"Building anna","Date":"2024-04-04","Draft":false,"JSFiles":null,"Type":"post","Description":"This page contains a post about anna, a static site generator written in Go. This team project was built as part of AIEP 2024","PreviewImage":"","Tags":["acm","hsp","go","tech","talk","aiep"],"Authors":["Adhesh","Aditya","Nathan","Anirudh"]},"Tags":["acm","hsp","go","tech","talk","aiep"]},"posts/week-1.html":{"CompleteURL":"posts/week-1.html","Frontmatter":{"Title":"Week-1 Progress","Date":"2024-03-18","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"posts/week-2.html":{"CompleteURL":"posts/week-2.html","Frontmatter":{"Title":"Week-2 Progress","Date":"2024-03-25","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]},"posts/week-3.html":{"CompleteURL":"posts/week-3.html","Frontmatter":{"Title":"Week-3 Progress","Date":"2024-04-01","Draft":false,"JSFiles":null,"Type":"post","Description":"","PreviewImage":"","Tags":["progress"],"Authors":["Adhesh","Aditya","Anirudh","Nathan"]},"Tags":["progress"]}} \ No newline at end of file diff --git a/test/engine/json_index_test/want_index.json b/test/engine/json_index_test/want_index.json index a6f6b45..317502d 100644 --- a/test/engine/json_index_test/want_index.json +++ b/test/engine/json_index_test/want_index.json @@ -1 +1 @@ -{"docs.md":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null}}} +{"docs.md":{"CompleteURL":"docs.html","Frontmatter":{"Title":"Anna Documentation","Date":"","Draft":false,"JSFiles":null,"Type":"","Description":"","PreviewImage":"","Tags":null,"Authors":null},"Tags":null}} \ No newline at end of file diff --git a/test/engine/render_engine_generated/posts_template.layout b/test/engine/render_engine_generated/posts_template.html similarity index 100% rename from test/engine/render_engine_generated/posts_template.layout rename to test/engine/render_engine_generated/posts_template.html diff --git a/test/engine/render_page/template_input.layout b/test/engine/render_page/template_input.html similarity index 100% rename from test/engine/render_page/template_input.layout rename to test/engine/render_page/template_input.html diff --git a/test/engine/render_tags/tags_subpage_template.layout b/test/engine/render_tags/tags_subpage_template.html similarity index 100% rename from test/engine/render_tags/tags_subpage_template.layout rename to test/engine/render_tags/tags_subpage_template.html diff --git a/test/engine/render_tags/tags_template.layout b/test/engine/render_tags/tags_template.html similarity index 100% rename from test/engine/render_tags/tags_template.layout rename to test/engine/render_tags/tags_template.html diff --git a/test/engine/render_user_defined/template_input.layout b/test/engine/render_user_defined/template_input.html similarity index 100% rename from test/engine/render_user_defined/template_input.layout rename to test/engine/render_user_defined/template_input.html From 24d5303d0600a8dc7ee66dc7e6ffefe27b9e6287 Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 21:09:24 +0530 Subject: [PATCH 5/6] docs: update documentation --- site/content/docs.md | 45 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/site/content/docs.md b/site/content/docs.md index deb6c82..2c8c024 100644 --- a/site/content/docs.md +++ b/site/content/docs.md @@ -77,18 +77,37 @@ The ssg currently requires the following directory structure - The `posts.html` file defines the layout of a page displaying all the posts of the site - The layout files can be composed of smaller html files which are stored in the `partials/` folder -#### Layout +## Building layouts -The layout files can access the following rendered data from the markdown files: +Each layout file(except `posts.html` and `tags.html`) can access any data from the entire ssg -- `{{.CompleteURL}}` : Returns the complete url of the given page -- `{{.FilenameWithoutExtension}}` : Returns the name of the current file -- `{{.Date}}` : Returns the last modified date of the current file -- `{{.Frontmatter.[Tagname]}}` : Returns the value of the frontmatter tag - - Example: `{{.Frontmatter.Title}}` : Returns the value of the title tag -- `{{.Body}}` : Returns the markdown body rendered to HTML -- `{{.Layout.[Tagname]}}`: Returns the particular configuration detail of the page - - Example: `{{.Layout.Navbar}}` : Returns a string slice with the names of all the navbar elements +The URL for the current page can be accessed using `{{.PageURL}}` + +To access the data for a particular page, use Go templating syntax: + +```html +{{$PageData := index .DeepDataMerge.Templates .PageURL}} +{{$PageData.CompleteURL}} +``` + +All of the following page data fields can be accessed in the above manner: + +- `{{$PageData.CompleteURL}}` : Returns the complete url of the given page +- `{{$PageData.Date}}` : Returns the last modified date of the current file +- `{{$PageData.Frontmatter.[Tagname]}}` : Returns the value of the frontmatter tag + - Example: `{{$PageData.Frontmatter.Title}}` : Returns the value of the title tag +- `{{$PageData.Body}}` : Returns the markdown body rendered to HTML +- `{{$PageData.Layout.[Tagname]}}`: Returns the particular configuration detail of the page + - Example: `{{$PageData.Layout.Navbar}}` : Returns a string slice with the names of all the navbar elements + +In addition to page data, the following fields can be accessed: + +- `{{.DeepDataMerge.Tags}}` - A map that stores the template of the tag sub-pages for a particular tag url +- `{{.DeepDataMerge.TagsMap}}` - A map that stores a slice of templates of all posts for a particular tag url +- `{{.DeepDataMerge.LayoutConfig}}` - Stores the layout parsed from `config.yml` +- `{{.DeepDataMerge.Posts}}` - Stores a slice of templates of all posts +- `{{.DeepDataMerge.JSONIndex}}` - Stores the JSON index generated for a particular site +(primarily used for search and graphing of tags) ## Notes @@ -110,10 +129,12 @@ The layout files can access the following rendered data from the markdown files: - `title` : The title of the current page - `date`: The date of the current page - `draft`: When set to 'true', the current page is not rendered unless the '-d' flag is used +- `scripts`: Stores the page-level scripts to be added - `type`: Sets the type of the page. Use type 'post' for posts - `description`: Stores the description of the current post previewed in posts.html - `previewimage`: Stores the preview image of the current page - `tags`: Stores the tags of the particular page +- `authors`: Stores (multiple) author/s of a particular page (**The above tags are Frontmatter tags**) @@ -143,12 +164,15 @@ siteTitle: anna siteScripts: author: Anna ``` + --- + ## Run locally ```sh go run github.com/acmpesuecc/anna@v1.0.0-alpha ``` + > If you don't have a site dir with the pre-requisite layout template; anna proceeds to fetch the default site dir from our GitHub repository ## Contributing to Anna @@ -161,6 +185,7 @@ If you have git installed, clone our repository and build against the latest com git clone github.com/acmpesuecc/anna; cd anna go build ``` + ```text Usage: anna [flags] From 8da851bf14d9c6efce44706b53880e142d77ebd8 Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 21:47:39 +0530 Subject: [PATCH 6/6] feat: access deep data merge in all layouts Co-authored-by: Aditya Hegde --- pkg/engine/anna_engine.go | 18 +++++------ pkg/engine/engine_test.go | 12 +++---- pkg/engine/user_engine.go | 9 +++--- pkg/parser/parser.go | 2 -- pkg/parser/parser_test.go | 2 +- site/content/docs.md | 4 ++- site/layout/page.html | 8 ++--- site/layout/partials/head.html | 32 +++++++++++-------- site/layout/partials/header.html | 20 +++++++++--- site/layout/posts.html | 5 +-- site/layout/tag-subpage.html | 6 ++-- site/layout/tags.html | 9 +++--- .../posts_template.html | 2 +- test/engine/render_tags/tags_template.html | 2 +- 14 files changed, 73 insertions(+), 58 deletions(-) diff --git a/pkg/engine/anna_engine.go b/pkg/engine/anna_engine.go index 2101d37..f28ee80 100644 --- a/pkg/engine/anna_engine.go +++ b/pkg/engine/anna_engine.go @@ -17,10 +17,10 @@ import ( ) type TagRootTemplateData struct { - DeepDataMerge DeepDataMerge - PagePath template.URL - TagTemplateData parser.TemplateData - TagNames []string + DeepDataMerge DeepDataMerge + PageURL template.URL + TemplateData parser.TemplateData + TagNames []string } func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { @@ -46,15 +46,14 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { } tagRootTemplataData := parser.TemplateData{ - Layout: e.DeepDataMerge.LayoutConfig, Frontmatter: parser.Frontmatter{Title: "Tags"}, } tagTemplateData := TagRootTemplateData{ - DeepDataMerge: e.DeepDataMerge, - PagePath: "tags.html", - TagTemplateData: tagRootTemplataData, - TagNames: tagNames, + DeepDataMerge: e.DeepDataMerge, + PageURL: "tags.html", + TemplateData: tagRootTemplataData, + TagNames: tagNames, } // Rendering the page displaying all tags @@ -80,7 +79,6 @@ func (e *Engine) RenderTags(fileOutPath string, templ *template.Template) { tagString, _ = strings.CutSuffix(tagString, ".html") e.DeepDataMerge.Tags[tag] = parser.TemplateData{ - Layout: e.DeepDataMerge.LayoutConfig, Frontmatter: parser.Frontmatter{ Title: tagString, }, diff --git a/pkg/engine/engine_test.go b/pkg/engine/engine_test.go index 682abfd..a17e4cd 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -36,12 +36,12 @@ func TestRenderPage(t *testing.T) { Tags: []string{"blog", "thoughts"}, }, Body: template.HTML("

Hello World

"), - Layout: parser.LayoutConfig{ - Navbar: []string{"index", "posts"}, - BaseURL: "https://example.org", - SiteTitle: "Anna", - Author: "anna", - }, + // Layout: parser.LayoutConfig{ + // Navbar: []string{"index", "posts"}, + // BaseURL: "https://example.org", + // SiteTitle: "Anna", + // Author: "anna", + // }, } templ, err := template.ParseFiles(TestDirPath + "render_page/template_input.html") diff --git a/pkg/engine/user_engine.go b/pkg/engine/user_engine.go index 4b19b57..7254108 100644 --- a/pkg/engine/user_engine.go +++ b/pkg/engine/user_engine.go @@ -12,8 +12,9 @@ import ( ) type postsTemplateData struct { - Posts []parser.TemplateData - parser.TemplateData + DeepDataMerge DeepDataMerge + PageURL template.URL + TemplateData parser.TemplateData } func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, template *template.Template) { @@ -21,11 +22,11 @@ func (e *Engine) RenderEngineGeneratedFiles(fileOutPath string, template *templa var postsBuffer bytes.Buffer postsData := postsTemplateData{ - Posts: e.DeepDataMerge.Posts, TemplateData: parser.TemplateData{ Frontmatter: parser.Frontmatter{Title: "Posts"}, - Layout: e.DeepDataMerge.LayoutConfig, }, + DeepDataMerge: e.DeepDataMerge, + PageURL: "posts.html", } // e.DeepDataMerge.Templates["posts.html"] = parser.TemplateData{ // Frontmatter: parser.Frontmatter{Title: "Posts"}, diff --git a/pkg/parser/parser.go b/pkg/parser/parser.go index 2bfd766..aa66f3e 100644 --- a/pkg/parser/parser.go +++ b/pkg/parser/parser.go @@ -44,7 +44,6 @@ type TemplateData struct { Date int64 Frontmatter Frontmatter Body template.HTML - Layout LayoutConfig LiveReload bool } @@ -132,7 +131,6 @@ func (p *Parser) AddFileAndRender(baseDirPath string, dirEntryPath string, front Date: date, Frontmatter: frontmatter, Body: template.HTML(body), - Layout: p.LayoutConfig, LiveReload: p.LiveReload, } diff --git a/pkg/parser/parser_test.go b/pkg/parser/parser_test.go index 8c6d7b9..15705fe 100644 --- a/pkg/parser/parser_test.go +++ b/pkg/parser/parser_test.go @@ -52,7 +52,7 @@ func TestAddFileandRender(t *testing.T) { Date: want_parser.DateParse(sample_frontmatter.Date).Unix(), Frontmatter: sample_frontmatter, Body: template.HTML(sample_body), - Layout: want_layout, + // Layout: want_layout, } want_parser.LayoutConfig = want_layout diff --git a/site/content/docs.md b/site/content/docs.md index 2c8c024..66ca0d7 100644 --- a/site/content/docs.md +++ b/site/content/docs.md @@ -90,6 +90,8 @@ To access the data for a particular page, use Go templating syntax: {{$PageData.CompleteURL}} ``` +To access the page data for `posts.html`, `tags.html` and partials, set {{$PageData := .TemplateData}} + All of the following page data fields can be accessed in the above manner: - `{{$PageData.CompleteURL}}` : Returns the complete url of the given page @@ -182,7 +184,7 @@ Detailed documentation for our SSG can be found: [here](https://anna-docs.netlif If you have git installed, clone our repository and build against the latest commit ```sh -git clone github.com/acmpesuecc/anna; cd anna +git clone github.com/acmpesuecc/anna; cd anna go build ``` diff --git a/site/layout/page.html b/site/layout/page.html index fd4ebac..32daec0 100644 --- a/site/layout/page.html +++ b/site/layout/page.html @@ -1,10 +1,10 @@ {{ define "page"}} {{$PageData := index .DeepDataMerge.Templates .PageURL}} -{{ template "head" $PageData}} +{{ template "head" .}} - {{template "header" $PageData}} + {{template "header" .}}
{{ if eq $PageData.Frontmatter.Type "post" }} @@ -36,9 +36,9 @@

{{ $PageData.Frontmatter.Title }}

{{$PageData.Body}}
- {{template "footer" $PageData}} + {{template "footer" .}} -{{ end}} \ No newline at end of file +{{ end}} diff --git a/site/layout/partials/head.html b/site/layout/partials/head.html index 7371d04..df7ce9f 100644 --- a/site/layout/partials/head.html +++ b/site/layout/partials/head.html @@ -1,46 +1,50 @@ -{{define "head"}} +{{ define "head" }} + +{{ $PageData := index .DeepDataMerge.Templates .PageURL }} +{{if eq $PageData nil }} + {{ $PageData = .TemplateData }} +{{end}} + - {{.Frontmatter.Title}} + {{$PageData.Frontmatter.Title}} + - + - {{ if .LiveReload }} + + {{ if $PageData.LiveReload }} {{ end }} - {{range .Frontmatter.JSFiles}} + {{range $PageData.Frontmatter.JSFiles}} - {{end}} {{range .Layout.SiteScripts}} + {{end}} {{range .DeepDataMerge.LayoutConfig.SiteScripts}} {{end}} - - - + + + - + - {{template "footer" $PageData}} + {{template "footer" .}} + diff --git a/test/engine/render_engine_generated/posts_template.html b/test/engine/render_engine_generated/posts_template.html index 12b2fa0..f66eb58 100644 --- a/test/engine/render_engine_generated/posts_template.html +++ b/test/engine/render_engine_generated/posts_template.html @@ -3,7 +3,7 @@