From b71d24a0f0de5cd211eaf9852e55722952bc86ff Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Tue, 9 Apr 2024 00:06:08 +0530 Subject: [PATCH 01/11] 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 60010583bcb2a72f830d366f31f3fe3182b8fd72 Mon Sep 17 00:00:00 2001 From: Nathan Paul Date: Wed, 10 Apr 2024 14:51:18 +0530 Subject: [PATCH 02/11] meta/gh: add bench.yml --- .github/workflows/bench.yml | 47 ++++++++++++++++++++++++++++ test/bench.sh | 62 +++++++++++++++++-------------------- 2 files changed, 75 insertions(+), 34 deletions(-) create mode 100644 .github/workflows/bench.yml diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml new file mode 100644 index 0000000..f351eec --- /dev/null +++ b/.github/workflows/bench.yml @@ -0,0 +1,47 @@ +name: benchmark + +on: + push: + branches: + - 'prof-bench.sh' + workflow_dispatch: + +jobs: + benchmark: + runs-on: ubuntu-latest + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: Install Hyperfine + run: | + sudo apt-get update + sudo apt-get install -y hyperfine + + - name: Install Go + uses: actions/setup-go@v2 + with: + go-version-file: "go.mod" + + - name: Install Rust + uses: actions-rs/toolchain@v1.0.6 + with: + profile: minimal + toolchain: stable + + - name: Install Dependencies + run: | + sudo apt-get install -y curl git + curl https://sh.rustup.rs -sSf | sh -s -- -y + export PATH="$HOME/.cargo/bin:$PATH" + rustup default stable + rustup update + rustc --version + cargo --version + go version + + - name: Run Benchmark + run: | + chmod +x test/bench.sh + ./test/bench.sh diff --git a/test/bench.sh b/test/bench.sh index d957f16..baaf2b8 100755 --- a/test/bench.sh +++ b/test/bench.sh @@ -1,24 +1,15 @@ #!/bin/bash -set -e -clear - # parameters files=1000 warm=10 # cleanup cleanup() { - echo "Cleaning up" + echo "cleaning up" rm -rf /tmp/bench } trap cleanup EXIT -# echo "bash: cleanup" -cd /tmp || exit -rm -rf bench -mkdir bench -cd bench - # check if hyperfine is installed if ! command -v hyperfine &>/dev/null; then echo "hyperfine is not installed. Please install hyperfine to continue." @@ -26,40 +17,43 @@ if ! command -v hyperfine &>/dev/null; then fi # cloning candidates -echo "Cloning SSGs" -git clone https://github.com/acmpesuecc/anna -git clone https://github.com/anirudhRowjee/saaru -sleep 1; clear +echo "clone SSGs" +git clone https://github.com/acmpesuecc/anna /tmp/bench/anna +git clone https://github.com/anirudhRowjee/saaru /tmp/bench/saaru +sleep 1 -# benchmark file -cp anna/site/content/posts/bench.md test.md +# copy benchmark file +cp /tmp/bench/anna/site/content/posts/bench.md /tmp/bench/test.md -# checkout at v1 and commit -cd anna && git checkout v1.0.0-alpha; cd .. -cd saaru && git checkout c17930724fcaad67e1cfa3cc969667d043c1b826; cd .. -sleep 1; clear +# checkout specific versions +cd /tmp/bench/anna && git checkout v1.0.0-alpha && cd .. +cd saaru && git checkout c17930724fcaad67e1cfa3cc969667d043c1b826 && cd .. +sleep 1 # build SSGs -cd anna; go build; cd .. -cd saaru; cargo build --release; mv ./target/release/saaru .; cd .. -sleep 1; clear +echo "build SSGs" +cd /tmp/bench/anna && go build && cd .. +cd saaru && cargo build --release && mv ./target/release/saaru . && cd .. +echo "finished building" -# clean content dirs (no md files other than test.md) +# clean content/* dirs echo "Cleaning content directories" -rm -rf anna/site/content/posts/* -rm -rf saaru/docs/src/* +rm -rf /tmp/bench/anna/site/content/posts/* +rm -rf /tmp/bench/saaru/docs/src/* # create multiple copies of the test file echo "Spawning $files different markdown files..." for ((i = 0; i < files; i++)); do - cp test.md "anna/site/content/posts/test_$i.md" - cp test.md "saaru/docs/src/test_$i.md" + cp /tmp/bench/test.md "/tmp/bench/anna/site/content/posts/test_$i.md" + cp /tmp/bench/test.md "/tmp/bench/saaru/docs/src/test_$i.md" done -sleep 1; clear +sleep 1 -# run the benchmark -echo "Running benchmark with $files md files and $warm warmup runs" -cd anna; hyperfine -p 'sync' -w $warm "./anna"; cd .. -cd saaru; hyperfine -p 'sync' -w $warm "./saaru --base-path ./docs"; cd .. +# cooldown +echo "cooldown for 30s" +sleep 30 -echo "Benchmarking finished." +# run hyperfine +echo "running benchmark: $files md files and $warm warmup runs" +cd /tmp/bench/anna && hyperfine -p 'sync' -w $warm "./anna" && cd .. +cd saaru && hyperfine -p 'sync' -w $warm "./saaru --base-path ./docs" && cd .. From 87e9a95808432a5a6cbadf803f3dce5ad72b831f Mon Sep 17 00:00:00 2001 From: Nathan Paul Date: Wed, 10 Apr 2024 15:19:12 +0530 Subject: [PATCH 03/11] meta/gh: update actions --- .github/workflows/bench.yml | 8 +++----- .github/workflows/build.yml | 19 ++++--------------- .github/workflows/tests.yml | 31 +++++++++++++------------------ 3 files changed, 20 insertions(+), 38 deletions(-) diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f351eec..f35b366 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -1,10 +1,8 @@ -name: benchmark +# Benchmark anna v/s other SSGs +name: Benchmark on: - push: - branches: - - 'prof-bench.sh' - workflow_dispatch: + workflow_dispatch: jobs: benchmark: diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8ddfcfd..32dd1c7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,9 +1,7 @@ # Sample workflow for building and deploying an anna site to GitHub pages -name: Build +name: Build and Deploy on: - push: - branches: [main] workflow_dispatch: # Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages @@ -25,6 +23,7 @@ defaults: jobs: build: runs-on: ubuntu-latest + needs: test-and-coverage environment: name: github-pages url: ${{steps.deployment.outputs.page_url}} @@ -37,19 +36,8 @@ jobs: with: go-version-file: "go.mod" - - name: test anna - run: go test ./... - - - name: build anna - run: go build - - - name: Insert commit hash in footer - run: | - sed -i "s/COMMIT_HASH/${{ github.sha }}/g" site/layout/partials/footer.layout - - name: build site with anna - run: | - ./anna + run: go run . - name: upload /rendered uses: actions/upload-artifact@master @@ -64,6 +52,7 @@ jobs: environment: name: github-pages url: ${{steps.deployment.outputs.page_url}} + steps: - name: download /rendered uses: actions/download-artifact@master diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 1e768f9..acc1ce8 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -1,32 +1,27 @@ -# Sample workflow for building and deploying an anna site to GitHub pages -name: Tests - -on: [push, pull_request] - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false +name: Go Test and Coverage +on: + push: + pull_request: + workflow_dispatch: + defaults: run: shell: bash jobs: - check: + test-and-coverage: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 + - name: Setup Go uses: actions/setup-go@v4 with: go-version-file: "go.mod" - - run: go test ./... + - name: Run Tests + run: go test ./... + + - name: Generate Test Coverage + run: go test -cover ./... From 75201286aaa619083f7a36b81ccf4ccfeb7f5fe1 Mon Sep 17 00:00:00 2001 From: Nathan Paul Date: Wed, 10 Apr 2024 17:37:02 +0530 Subject: [PATCH 04/11] meta/gh: automate goreleaser ref: #76 use go-releaser + gh-actions to build binaries for 3 target platforms --- .github/workflows/bench.yml | 2 +- .github/workflows/release.yml | 30 ++++++++++++++++++++++++++++++ go.mod | 4 ++-- go.sum | 4 ++-- 4 files changed, 35 insertions(+), 5 deletions(-) create mode 100644 .github/workflows/release.yml diff --git a/.github/workflows/bench.yml b/.github/workflows/bench.yml index f35b366..2ea4699 100644 --- a/.github/workflows/bench.yml +++ b/.github/workflows/bench.yml @@ -18,7 +18,7 @@ jobs: sudo apt-get install -y hyperfine - name: Install Go - uses: actions/setup-go@v2 + uses: actions/setup-go@v4 with: go-version-file: "go.mod" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 0000000..59873a7 --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,30 @@ +name: Release + +on: + push: + tags: + - '*' + +permissions: + contents: write + +jobs: + goreleaser: + runs-on: ubuntu-latest + steps: + - name: checkout code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: setup go + uses: actions/setup-go@v4 + + - name: run goreleaser + uses: goreleaser/goreleaser-action@v5 + with: + distribution: goreleaser + version: latest + args: release --clean + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/go.mod b/go.mod index 221ae52..ea939a8 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/acmpesuecc/anna -go 1.22.0 +go 1.22.2 require ( github.com/PuerkitoBio/goquery v1.9.1 @@ -20,7 +20,7 @@ require ( github.com/mattn/go-isatty v0.0.20 // indirect github.com/mattn/go-runewidth v0.0.15 // indirect github.com/rivo/uniseg v0.4.7 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect + github.com/rogpeppe/go-internal v1.12.0 // indirect github.com/spf13/pflag v1.0.5 // indirect golang.org/x/net v0.24.0 // indirect golang.org/x/sys v0.19.0 // indirect diff --git a/go.sum b/go.sum index 8a3d170..6aceecd 100644 --- a/go.sum +++ b/go.sum @@ -31,8 +31,8 @@ github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJ github.com/rivo/uniseg v0.4.7 h1:WUdvkW8uEhrYfLC4ZzdpI2ztxP1I582+49Oc5Mq64VQ= github.com/rivo/uniseg v0.4.7/go.mod h1:FN3SvrM+Zdj16jyLfmOkMNblXMcoc8DfTHruCPUcx88= github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= +github.com/rogpeppe/go-internal v1.12.0 h1:exVL4IDcn6na9z1rAb56Vxr+CgyK3nn3O+epU5NdKM8= +github.com/rogpeppe/go-internal v1.12.0/go.mod h1:E+RYuTGaKKdloAfM02xzb0FW3Paa99yedzYV+kq4uf4= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/spf13/cobra v1.8.0 h1:7aJaZx1B85qltLMc546zn58BxxfZdR/W22ej9CFoEf0= github.com/spf13/cobra v1.8.0/go.mod h1:WXLWApfZ71AjXPya3WOlMsY9yMs7YeiHhFVlvLyhcho= From 7fac3345e9ddea1fbe9256978760218bfe079811 Mon Sep 17 00:00:00 2001 From: Nathan Paul Date: Thu, 11 Apr 2024 00:42:40 +0530 Subject: [PATCH 05/11] feat: style atom feeds closes: #95 misc: update docs, prompt user before sitedir bootstrap --- README.md | 25 +++++------ pkg/engine/anna_engine.go | 7 +-- pkg/helpers/helper.go | 7 +++ site/content/docs.md | 42 ++++++++--------- site/content/posts/bench.md | 2 +- site/layout/partials/head.layout | 2 +- site/static/index.json | 2 +- site/static/styles/feed.xsl | 77 ++++++++++++++++++++++++++++++++ 8 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 site/static/styles/feed.xsl diff --git a/README.md b/README.md index c8d119b..4844220 100644 --- a/README.md +++ b/README.md @@ -17,31 +17,28 @@ A static site generator in go Inspired by [Hugo](https://gohugo.io) and [Saaru](https://github.com/anirudhRowjee/saaru), this static site generator aims to take performance to the next level with parallel rendering, live reload and so much more, all in Go. -> Pronounced: `/ɐnːɐ/` which means rice in Kannada 🍚 +Pronounced: `/ɐnːɐ/` which means rice 🍚 in Kannada -This project is a part of the ACM PESU-ECC's yearly [AIEP](https://acmpesuecc.github.io/aiep) program, and is maintained by [Adhesh Athrey](https://github.com/DedLad), [Nathan Paul](https://github.com/polarhive), [Anirudh Sudhir](https://github.com/anirudhsudhir), and [Aditya Hegde](https://github.com/bwaklog) +> This project is a part of the ACM PESU-ECC's yearly [AIEP](https://acmpesuecc.github.io/aiep) program, and is maintained by [Adhesh Athrey](https://github.com/DedLad), [Nathan Paul](https://github.com/polarhive), [Anirudh Sudhir](https://github.com/anirudhsudhir), and [Aditya Hegde](https://github.com/bwaklog) --- - -## Install +## Get Started ```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 -Alternatively, clone our repository to build the latest version of anna: - -```sh -git clone github.com/acmpesuecc/anna --depth=1; cd anna -go run . -``` - -### Detailed documentation of our SSG can be found [here](https://anna-docs.netlify.app/) +## Contributing to Anna ---- +Detailed documentation for our SSG can be found: [here](https://anna-docs.netlify.app/) -## Flags +If you have git installed, clone our repository and build against the latest commit +```sh +git clone github.com/acmpesuecc/anna; cd anna +go build +``` ```text Usage: anna [flags] diff --git a/pkg/engine/anna_engine.go b/pkg/engine/anna_engine.go index daf6e31..ba4f47e 100644 --- a/pkg/engine/anna_engine.go +++ b/pkg/engine/anna_engine.go @@ -154,6 +154,7 @@ func (e *Engine) GenerateSitemap(outFilePath string) { func (e *Engine) GenerateFeed() { var buffer bytes.Buffer buffer.WriteString("\n") + buffer.WriteString("\n") buffer.WriteString("\n") buffer.WriteString(" " + e.LayoutConfig.SiteTitle + "\n") buffer.WriteString(" \n") @@ -162,10 +163,10 @@ func (e *Engine) GenerateFeed() { // iterate over parsed markdown files that are non-draft posts for _, templateData := range e.Templates { if !templateData.Frontmatter.Draft { - buffer.WriteString(" \n") + buffer.WriteString("\n") buffer.WriteString(" " + templateData.Frontmatter.Title + "\n") buffer.WriteString(" \n") - buffer.WriteString(" " + e.LayoutConfig.BaseURL + "/" + templateData.FilenameWithoutExtension + ".html\n") + buffer.WriteString(" " + e.LayoutConfig.BaseURL + "/posts/" + templateData.FilenameWithoutExtension + ".html\n") buffer.WriteString(" " + time.Unix(templateData.Date, 0).Format(time.RFC3339) + "\n") buffer.WriteString(" \n") buffer.WriteString(" \n") @@ -173,7 +174,7 @@ func (e *Engine) GenerateFeed() { } buffer.WriteString("\n") - outputFile, err := os.Create(helpers.SiteDataPath + "rendered/feed.atom") + outputFile, err := os.Create(helpers.SiteDataPath + "rendered/feed.xml") if err != nil { e.ErrorLogger.Fatal(err) } diff --git a/pkg/helpers/helper.go b/pkg/helpers/helper.go index 7ee8a20..889a73e 100644 --- a/pkg/helpers/helper.go +++ b/pkg/helpers/helper.go @@ -72,6 +72,13 @@ func (h *Helper) CreateRenderedDir(fileOutPath string) { } func (h *Helper) Bootstrap() { + fmt.Println("Are you sure you want to proceed with the bootstrap process? (y/n)") + var confirm string + fmt.Scanln(&confirm) + if confirm != "y" { + fmt.Println("Bootstrap process cancelled.") + return + } log.Println("Downloading base theme") url := "https://github.com/acmpesuecc/anna/archive/refs/heads/main.zip" output, err := os.Create("anna-repo.zip") diff --git a/site/content/docs.md b/site/content/docs.md index be01e9c..deb6c82 100644 --- a/site/content/docs.md +++ b/site/content/docs.md @@ -1,4 +1,5 @@ --- +date: 2024-04-10 title: Anna Documentation --- @@ -20,12 +21,12 @@ Pronounced: `/ɐnːɐ/` which means rice in Kannada 🍚 This Project is a part of the ACM PESU-ECC's yearly [AIEP](https://acmpesuecc.github.io/aiep) program, and is maintained by [Adhesh Athrey](https://github.com/DedLad), [Nathan Paul](https://github.com/polarhive), [Anirudh Sudhir](https://github.com/anirudhsudhir), and [Aditya Hegde](https://github.com/bwaklog) +--- ## Directory structure The ssg currently requires the following directory structure ```text - /anna β”œβ”€β”€ /cmd β”œβ”€β”€ /pkg @@ -134,8 +135,7 @@ navbar: - posts baseURL: http://localhost:8000/ -# Replace this with the actual canonical-url of your site. - +# Replace this with the actual canonical-url of your site # baseURL tells search-engines (SEO), web-crawlers (robots.txt) so people can discover your site on the internet. # It's also embeded in your sitemap / atom feed and can be used to change metadata about your site. @@ -143,33 +143,35 @@ siteTitle: anna siteScripts: author: Anna ``` - -## Install - -Once you have a directory structure, install `anna` using: +--- +## Run locally ```sh -go install github.com/acmpesuecc/anna@latest +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 -Or if you have git installed, clone our repository: +## Contributing to Anna -```sh -git clone github.com/acmpesuecc/anna --depth=1 -cd anna -go run . -``` +Detailed documentation for our SSG can be found: [here](https://anna-docs.netlify.app/) -## Flags +If you have git installed, clone our repository and build against the latest commit +```sh +git clone github.com/acmpesuecc/anna; cd anna +go build +``` ```text Usage: anna [flags] Flags: - -a, --addr stringwhich sip address to serve rendered content to (default "8000") - -d, --draft renders draft posts - -h, --help help for ssg - -s, --serve serve the rendered content - -v, --validate-html validate semantic HTML + -a, --addr string ip address to serve rendered content to (default "8000") + -d, --draft renders draft posts + -h, --help help for anna + -l, --layout validates html layouts + -p, --prof enable profiling + -s, --serve serve the rendered content + -v, --version prints current version number + -w, --webconsole wizard to setup anna ``` diff --git a/site/content/posts/bench.md b/site/content/posts/bench.md index c4c8bac..8811ef1 100644 --- a/site/content/posts/bench.md +++ b/site/content/posts/bench.md @@ -2,7 +2,7 @@ title: benchmark template: post.jinja author: John Doe -date: 2024-02-23 +date: 2024-01-01 categories: - Technology - Programming diff --git a/site/layout/partials/head.layout b/site/layout/partials/head.layout index 99b68b0..2a41124 100644 --- a/site/layout/partials/head.layout +++ b/site/layout/partials/head.layout @@ -11,7 +11,7 @@ - + {{range .Frontmatter.JSFiles}} diff --git a/site/static/index.json b/site/static/index.json index 0236c6a..33cad2e 100644 --- a/site/static/index.json +++ b/site/static/index.json @@ -1 +1 @@ -{"bench.md":{"CompleteURL":"posts/bench.html","FilenameWithoutExtension":"bench","Frontmatter":{"Title":"benchmark","Date":"2024-02-23","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":"","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 +{"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 diff --git a/site/static/styles/feed.xsl b/site/static/styles/feed.xsl new file mode 100644 index 0000000..7b47381 --- /dev/null +++ b/site/static/styles/feed.xsl @@ -0,0 +1,77 @@ + + + + + + + + Web Feed β€’ <xsl:value-of select="atom:feed/atom:title"/> + + + +
+
+

This is a web feed, also known as an RSS feed. Subscribe by copying the URL from the address bar into your newsreader app.

+
+
+
+ +
+
+

Recent Items

+ +
+ + +
+ + +

's Web Feed Preview

+

This RSS feed provides the latest posts from 's blog. + + + + + + Visit Website → + + +

+ +

What is an RSS feed?

+

An RSS feed is a data format that contains the latest content from a website, blog, or podcast. You can use feeds to subscribe to websites and get the latest content in one place.

+
    +
  • Feeds put you in control. Unlike social media apps, there is no algorithm deciding what you see or read. You always get the latest content from the creators you care about.
  • +
  • Feed are private by design. No one owns web feeds, so no one is harvesting your personal information and profiting by selling it to advertisers.
  • +
  • Feeds are spam-proof. Had enough? Easy, just unsubscribe from the feed.
  • +
+

All you need to do to get started is to add the URL (web address) for this feed to a special app called a newsreader. Visit About Feeds to get started with newsreaders and subscribing. It’s free.

+
+ + +
+

+ + + + + + +

+

+ +

+ + Published: + +
+
+ +
\ No newline at end of file From 79cb97680db9f225efed034282ddc2438f6fcf9f Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 13:01:57 +0530 Subject: [PATCH 06/11] test: delete generated test data after testing --- .gitignore | 1 - pkg/engine/anna_engine_test.go | 34 ++++++++++++---- pkg/engine/engine_integration_test.go | 11 +++++ pkg/engine/engine_test.go | 10 ++++- pkg/engine/user_engine_test.go | 8 ++++ .../render_page/rendered/posts/got.html | 18 --------- .../want_index.json | 0 .../engine/merged_data_test/static/index.json | 1 - .../rendered/posts.html | 40 ------------------- .../render_page/rendered/posts/got.html | 18 --------- test/engine/render_tags/rendered/tags.html | 13 ------ .../render_tags/rendered/tags/blogs.html | 13 ------ .../render_tags/rendered/tags/tech.html | 13 ------ .../render_user_defined/rendered/index.html | 10 ----- .../rendered/posts/hello.html | 10 ----- test/engine/sitemap/got_sitemap.xml | 15 ------- test/engine/want_sitemap.xml | 15 ------- 17 files changed, 54 insertions(+), 176 deletions(-) delete mode 100644 test/engine/engine/render_page/rendered/posts/got.html rename test/engine/{merged_data_test => json_index_test}/want_index.json (100%) delete mode 100644 test/engine/merged_data_test/static/index.json delete mode 100644 test/engine/render_engine_generated/rendered/posts.html delete mode 100644 test/engine/render_page/rendered/posts/got.html delete mode 100644 test/engine/render_tags/rendered/tags.html delete mode 100644 test/engine/render_tags/rendered/tags/blogs.html delete mode 100644 test/engine/render_tags/rendered/tags/tech.html delete mode 100644 test/engine/render_user_defined/rendered/index.html delete mode 100644 test/engine/render_user_defined/rendered/posts/hello.html delete mode 100644 test/engine/sitemap/got_sitemap.xml delete mode 100644 test/engine/want_sitemap.xml diff --git a/.gitignore b/.gitignore index 211b43d..f1febea 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ -!rendered/ site/rendered/ anna !anna/ diff --git a/pkg/engine/anna_engine_test.go b/pkg/engine/anna_engine_test.go index 985ccd0..38ada32 100644 --- a/pkg/engine/anna_engine_test.go +++ b/pkg/engine/anna_engine_test.go @@ -61,6 +61,9 @@ func TestRenderTags(t *testing.T) { if err != nil { t.Errorf("%v", err) } + if err := os.MkdirAll(TestDirPath+"render_tags/rendered", 0750); err != nil { + t.Errorf("%v", err) + } e.RenderTags(fileOutPath, templ) t.Run("render tag.html", func(t *testing.T) { @@ -105,14 +108,21 @@ func TestRenderTags(t *testing.T) { } if !slices.Equal(got_tech_file, want_tech_file) { - t.Errorf("The expected and generated tech.html tag-subpage can be found in test/engine/render_tags/rendered/tags/") + t.Errorf("The expected and generated tech.html tag-subpage can be found in test/engine/render_tags/rendered/tags/") } }) -} + if err := os.RemoveAll(TestDirPath + "render_tags/rendered"); err != nil { + t.Errorf("%v", err) + } +} func TestGenerateMergedJson(t *testing.T) { - t.Run("test json creation from e.Templates", func(t *testing.T) { + if err := os.MkdirAll(TestDirPath+"json_index_test/static", 0750); err != nil { + t.Errorf("%v", err) + } + + 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), @@ -127,14 +137,14 @@ func TestGenerateMergedJson(t *testing.T) { }, } - e.GenerateJSONIndex(TestDirPath + "merged_data_test") + e.GenerateJSONIndex(TestDirPath + "json_index_test") - got_json, err := os.ReadFile(TestDirPath + "/merged_data_test/static/index.json") + got_json, err := os.ReadFile(TestDirPath + "/json_index_test/static/index.json") if err != nil { t.Errorf("%v", err) } - want_json, err := os.ReadFile(TestDirPath + "/merged_data_test/want_index.json") + want_json, err := os.ReadFile(TestDirPath + "/json_index_test/want_index.json") if err != nil { t.Errorf("%v", err) } @@ -143,9 +153,13 @@ func TestGenerateMergedJson(t *testing.T) { want_json = bytes.TrimSpace(want_json) if !slices.Equal(got_json, want_json) { - t.Errorf("The expected and generated json can be found in test/layout/") + t.Errorf("The expected and generated json can be found in test/engine/json_index_test") } }) + + if err := os.RemoveAll(TestDirPath + "json_index_test/static"); err != nil { + t.Errorf("%v", err) + } } func TestGenerateSitemap(t *testing.T) { @@ -205,7 +219,11 @@ func TestGenerateSitemap(t *testing.T) { }) if strings.Compare(got_sitemap_string, want_sitemap_string) == 0 { - t.Errorf("The expected and generated sitemap can be found in test/layout/sitemap/") + t.Errorf("The expected and generated sitemap can be found in test/engine/sitemap/") } }) + + if err := os.RemoveAll(TestDirPath + "sitemap/got_sitemap.xml"); err != nil { + t.Errorf("%v", err) + } } diff --git a/pkg/engine/engine_integration_test.go b/pkg/engine/engine_integration_test.go index 906b7fb..678f379 100644 --- a/pkg/engine/engine_integration_test.go +++ b/pkg/engine/engine_integration_test.go @@ -22,11 +22,17 @@ func TestRenderUserDefinedPages(t *testing.T) { parser.TemplateData{ FilenameWithoutExtension: "index", Body: template.HTML("

Index Page

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

Hello World

"), + CompleteURL: "posts/hello.html", + } + + if err := os.MkdirAll(TestDirPath+"render_user_defined/rendered", 0750); err != nil { + t.Errorf("%v", err) } t.Run("render a set of user defined pages", func(t *testing.T) { @@ -35,6 +41,7 @@ func TestRenderUserDefinedPages(t *testing.T) { if err != nil { t.Errorf("%v", err) } + engine.RenderUserDefinedPages(TestDirPath+"render_user_defined/", templ) want_index_file, err := os.ReadFile(TestDirPath + "render_user_defined/want_index.html") @@ -65,4 +72,8 @@ func TestRenderUserDefinedPages(t *testing.T) { t.Errorf("The expected and generated post/hello.html can be found in test/engine/render_user_defined/rendered/posts/") } }) + + 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 f39cf89..f54ba25 100644 --- a/pkg/engine/engine_test.go +++ b/pkg/engine/engine_test.go @@ -14,6 +14,10 @@ import ( const TestDirPath = "../../test/engine/" func TestRenderPage(t *testing.T) { + if err := os.MkdirAll(TestDirPath+"render_page/rendered", 0750); err != nil { + t.Errorf("%v", err) + } + 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), @@ -46,7 +50,7 @@ func TestRenderPage(t *testing.T) { t.Errorf("%v", err) } - engine.RenderPage(TestDirPath+"engine/render_page/", "posts/got.md", page, templ, "page") + engine.RenderPage(TestDirPath+"render_page/", "posts/got.md", page, templ, "page") got_file, err := os.ReadFile(TestDirPath + "render_page/rendered/posts/got.html") if err != nil { @@ -62,4 +66,8 @@ func TestRenderPage(t *testing.T) { t.Errorf("The expected and generated page.html can be found in test/engine/render_page/rendered/") } }) + + if err := os.RemoveAll(TestDirPath + "render_page/rendered"); err != nil { + t.Errorf("%v", err) + } } diff --git a/pkg/engine/user_engine_test.go b/pkg/engine/user_engine_test.go index 3c046cc..1116923 100644 --- a/pkg/engine/user_engine_test.go +++ b/pkg/engine/user_engine_test.go @@ -47,6 +47,10 @@ func TestRenderEngineGeneratedFiles(t *testing.T) { }, } + if err := os.MkdirAll(TestDirPath+"render_engine_generated/rendered", 0750); err != nil { + t.Errorf("%v", err) + } + t.Run("test rendering of post.html", func(t *testing.T) { templ, err := template.ParseFiles(TestDirPath + "render_engine_generated/posts_template.layout") if err != nil { @@ -69,4 +73,8 @@ 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/test/engine/engine/render_page/rendered/posts/got.html b/test/engine/engine/render_page/rendered/posts/got.html deleted file mode 100644 index 6cfcd99..0000000 --- a/test/engine/engine/render_page/rendered/posts/got.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - -
- -
-blog -
- - - -
-

Hello World

- - diff --git a/test/engine/merged_data_test/want_index.json b/test/engine/json_index_test/want_index.json similarity index 100% rename from test/engine/merged_data_test/want_index.json rename to test/engine/json_index_test/want_index.json diff --git a/test/engine/merged_data_test/static/index.json b/test/engine/merged_data_test/static/index.json deleted file mode 100644 index b9e300f..0000000 --- a/test/engine/merged_data_test/static/index.json +++ /dev/null @@ -1 +0,0 @@ -{"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}} \ No newline at end of file diff --git a/test/engine/render_engine_generated/rendered/posts.html b/test/engine/render_engine_generated/rendered/posts.html deleted file mode 100644 index 9a5b556..0000000 --- a/test/engine/render_engine_generated/rendered/posts.html +++ /dev/null @@ -1,40 +0,0 @@ - - - - - - diff --git a/test/engine/render_page/rendered/posts/got.html b/test/engine/render_page/rendered/posts/got.html deleted file mode 100644 index 6cfcd99..0000000 --- a/test/engine/render_page/rendered/posts/got.html +++ /dev/null @@ -1,18 +0,0 @@ - - - - -
- -
-blog -
- - - -
-

Hello World

- - diff --git a/test/engine/render_tags/rendered/tags.html b/test/engine/render_tags/rendered/tags.html deleted file mode 100644 index 1c73adc..0000000 --- a/test/engine/render_tags/rendered/tags.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- -blogs - -tech - -
-
- - diff --git a/test/engine/render_tags/rendered/tags/blogs.html b/test/engine/render_tags/rendered/tags/blogs.html deleted file mode 100644 index 3d48ac2..0000000 --- a/test/engine/render_tags/rendered/tags/blogs.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- -file1 - -file2 - -
-
- - diff --git a/test/engine/render_tags/rendered/tags/tech.html b/test/engine/render_tags/rendered/tags/tech.html deleted file mode 100644 index 88497f7..0000000 --- a/test/engine/render_tags/rendered/tags/tech.html +++ /dev/null @@ -1,13 +0,0 @@ - - -
-
- -file2 - -file3 - -
-
- - diff --git a/test/engine/render_user_defined/rendered/index.html b/test/engine/render_user_defined/rendered/index.html deleted file mode 100644 index c3dcf98..0000000 --- a/test/engine/render_user_defined/rendered/index.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
- -
-

Index Page

- - diff --git a/test/engine/render_user_defined/rendered/posts/hello.html b/test/engine/render_user_defined/rendered/posts/hello.html deleted file mode 100644 index d4fc935..0000000 --- a/test/engine/render_user_defined/rendered/posts/hello.html +++ /dev/null @@ -1,10 +0,0 @@ - - - - -
- -
-

Hello World

- - diff --git a/test/engine/sitemap/got_sitemap.xml b/test/engine/sitemap/got_sitemap.xml deleted file mode 100644 index dc94b5b..0000000 --- a/test/engine/sitemap/got_sitemap.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - example.org/index.html - 2024-02-23 - - - example.org/research.html - 2024-02-23 - - - example.org/about.html - 2024-02-23 - - diff --git a/test/engine/want_sitemap.xml b/test/engine/want_sitemap.xml deleted file mode 100644 index 5578525..0000000 --- a/test/engine/want_sitemap.xml +++ /dev/null @@ -1,15 +0,0 @@ - - - - example.org/about.html - 2024-02-23 - - - example.org/index.html - 2024-02-23 - - - example.org/research.html - 2024-02-23 - - From 96f6666aee3da0e7a4fba75befa4e4c48d94f45c Mon Sep 17 00:00:00 2001 From: Anirudh Sudhir Date: Thu, 11 Apr 2024 14:25:34 +0530 Subject: [PATCH 07/11] 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 08/11] 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 09/11] 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 10/11] 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 11/11] 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 @@