Skip to content

Commit

Permalink
Implement lazy loading with HTMX
Browse files Browse the repository at this point in the history
  • Loading branch information
mikkelsvartveit committed Sep 14, 2024
1 parent 22cb0fc commit 7f5a7f8
Show file tree
Hide file tree
Showing 6 changed files with 91 additions and 29 deletions.
2 changes: 1 addition & 1 deletion src/fetch_articles.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func fetchData() {
}

// Only fetch the first N items
rss.Channel.Items = rss.Channel.Items[:20]
rss.Channel.Items = rss.Channel.Items[:30]

for _, item := range rss.Channel.Items {
processArticle(item)
Expand Down
46 changes: 44 additions & 2 deletions src/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package main
import (
"fmt"
"net/http"
"strconv"
"text/template"
"time"

Expand All @@ -11,6 +12,11 @@ import (
"github.com/joho/godotenv"
)

type PageData struct {
NextPage int
Articles []Article
}

func main() {
// Load the .env file
godotenv.Load()
Expand All @@ -30,11 +36,47 @@ func main() {
// Run Goroutine to fetch data periodically
go runPeriodically(time.Minute*5, fetchData)

// Serve index.html
// Load HTML template
indexTmpl := template.Must(template.ParseFiles("templates/index.html"))

// Serve front page
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
articles := listArticles(1, 10)
err := indexTmpl.Execute(w, articles)
page := 1

pageData := PageData{
NextPage: page + 1,
Articles: articles,
}

err := indexTmpl.Execute(w, pageData)
if err != nil {
fmt.Println("Error executing template:", err)
}
})

// Serve articles fragment for htmx lazy loading
r.Get("/articles/{page}", func(w http.ResponseWriter, r *http.Request) {
page, err := strconv.Atoi(chi.URLParam(r, "page"))
if err != nil {
fmt.Println("Error parsing page number:", err)
w.WriteHeader(http.StatusBadRequest)
return
}

articles := listArticles(page, 10)

if len(articles) == 0 {
w.WriteHeader(http.StatusOK)
return
}

pageData := PageData{
NextPage: page + 1,
Articles: articles,
}

err = indexTmpl.ExecuteTemplate(w, "articles", pageData)
if err != nil {
fmt.Println("Error executing template:", err)
}
Expand Down
1 change: 1 addition & 0 deletions static/htmx.min.js

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions static/loading.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 1 addition & 1 deletion static/output.css

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

68 changes: 43 additions & 25 deletions templates/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
<title>Filtrert.no – den trivelige nyhetssiden</title>
<link rel="stylesheet" href="/output.css" />
<meta name="viewport" content="width=device-width, initial-scale=1" />

<script src="/htmx.min.js"></script>
</head>

<body>
Expand All @@ -12,31 +14,47 @@ <h1 class="text-3xl">
</h1>

<div>
{{ range . }}
<div>
<div class="my-8 h-px bg-gray-200"></div>

<a href="{{ .ArticleUrl }}" class="flex flex-col gap-4 sm:flex-row">
<img
class="aspect-video rounded sm:h-36"
src="{{ .ImageUrl }}"
alt="{{ .Title }}"
onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'100\' height=\'100\'%3E%3Crect width=\'100\' height=\'100\' fill=\'%23f3f4f6\'/%3E%3C/svg%3E';"
/>
<div class="flex-1">
<p class="text-xs font-medium text-gray-600">
{{ .Time.Format "Monday, 15:04" }}
</p>
<h3 class="mb-2 mt-1 text-xl">
{{ .Title }}
</h3>

<p class="line-clamp-3 text-sm">
{{ .Description }}
</p>
</div>
</a>
</div>
{{ block "articles" . }}
{{ range .Articles }}
<div>
<div class="my-8 h-px bg-gray-200"></div>

<a
href="{{ .ArticleUrl }}"
class="flex flex-col gap-4 sm:flex-row"
>
<img
class="aspect-video rounded sm:h-36"
src="{{ .ImageUrl }}"
alt="{{ .Title }}"
onerror="this.onerror=null; this.src='data:image/svg+xml,%3Csvg xmlns=\'http://www.w3.org/2000/svg\' width=\'100\' height=\'100\'%3E%3Crect width=\'100\' height=\'100\' fill=\'%23f3f4f6\'/%3E%3C/svg%3E';"
/>

<div class="flex-1">
<p class="text-xs font-medium text-gray-600">
{{ .Time.Format "Monday, 15:04" }}
</p>
<h3 class="mb-2 mt-1 text-xl">
{{ .Title }}
</h3>

<p class="line-clamp-3 text-sm">
{{ .Description }}
</p>
</div>
</a>
</div>
{{ end }}


<img
hx-get="/articles/{{ .NextPage }}"
hx-trigger="revealed"
hx-swap="outerHTML"
src="/loading.svg"
alt="Loading..."
class="mx-auto mt-8 h-10"
/>
{{ end }}
</div>
</main>
Expand Down

0 comments on commit 7f5a7f8

Please sign in to comment.