Skip to content

Commit

Permalink
feat: complete deep data merge and update tests
Browse files Browse the repository at this point in the history
Co-authored-by: Aditya Hegde <[email protected]>
  • Loading branch information
anirudhsudhir and bwaklog committed Apr 11, 2024
1 parent 96f6666 commit 97dd0b9
Show file tree
Hide file tree
Showing 31 changed files with 724 additions and 260 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
site/rendered/
anna
!anna/
*.exe
Expand All @@ -7,3 +6,8 @@ anna
ssg/
*.txt
dist/

#Test directories
**/rendered/
test/**/static/
test/**/got_sitemap.xml
6 changes: 3 additions & 3 deletions cmd/anna/anna.go
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
80 changes: 52 additions & 28 deletions pkg/engine/anna_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand All @@ -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)
}

Expand All @@ -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,
}
}

Expand Down Expand Up @@ -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<url>\n")
buffer.WriteString("\t\t<loc>" + url + "</loc>\n")
buffer.WriteString("\t\t<lastmod>" + templateData.Frontmatter.Date + "</lastmod>\n")
Expand Down Expand Up @@ -165,8 +189,8 @@ func (e *Engine) GenerateFeed() {
if !templateData.Frontmatter.Draft {
buffer.WriteString("<entry>\n")
buffer.WriteString(" <title>" + templateData.Frontmatter.Title + "</title>\n")
buffer.WriteString(" <link href=\"" + e.DeepDataMerge.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html\"/>\n")
buffer.WriteString(" <id>" + e.DeepDataMerge.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html</id>\n")
buffer.WriteString(" <link href=\"" + e.DeepDataMerge.LayoutConfig.BaseURL + string(templateData.CompleteURL) + "/>\n")
buffer.WriteString(" <id>" + e.DeepDataMerge.LayoutConfig.BaseURL + string(templateData.CompleteURL) + "</id>\n")
buffer.WriteString(" <updated>" + time.Unix(templateData.Date, 0).Format(time.RFC3339) + "</updated>\n")
buffer.WriteString(" <content type=\"html\"><![CDATA[" + string(templateData.Body) + "]]></content>\n")
buffer.WriteString(" </entry>\n")
Expand Down
28 changes: 9 additions & 19 deletions pkg/engine/anna_engine_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand All @@ -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{
Expand Down Expand Up @@ -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) {
Expand All @@ -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",
},
Expand All @@ -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) {
Expand All @@ -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",
},
Expand Down Expand Up @@ -223,7 +216,4 @@ func TestGenerateSitemap(t *testing.T) {
}
})

if err := os.RemoveAll(TestDirPath + "sitemap/got_sitemap.xml"); err != nil {
t.Errorf("%v", err)
}
}
33 changes: 21 additions & 12 deletions pkg/engine/engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
}

/*
Expand All @@ -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
Expand All @@ -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)
}
Expand Down
19 changes: 7 additions & 12 deletions pkg/engine/engine_integration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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("<h1>Index Page</h1>"),
CompleteURL: "index.html",
Body: template.HTML("<h1>Index Page</h1>"),
CompleteURL: "index.html",
}

engine.DeepDataMerge.Templates["posts/hello.md"] = parser.TemplateData{
FilenameWithoutExtension: "hello",
Body: template.HTML("<h1>Hello World</h1>"),
CompleteURL: "posts/hello.html",
engine.DeepDataMerge.Templates["posts/hello.html"] = parser.TemplateData{
Body: template.HTML("<h1>Hello World</h1>"),
CompleteURL: "posts/hello.html",
}

if err := os.MkdirAll(TestDirPath+"render_user_defined/rendered", 0750); err != nil {
Expand Down Expand Up @@ -73,7 +71,4 @@ func TestRenderUserDefinedPages(t *testing.T) {
}
})

if err := os.RemoveAll(TestDirPath + "render_user_defined/rendered"); err != nil {
t.Errorf("%v", err)
}
}
Loading

0 comments on commit 97dd0b9

Please sign in to comment.