|
|
|
|
@ -120,6 +120,7 @@ type BlogItemInfo struct {
@@ -120,6 +120,7 @@ type BlogItemInfo struct {
|
|
|
|
|
Summary string |
|
|
|
|
Content template.HTML |
|
|
|
|
Author string |
|
|
|
|
Image string |
|
|
|
|
CreatedAt int64 |
|
|
|
|
Time string // Formatted time
|
|
|
|
|
TimeISO string // ISO time
|
|
|
|
|
@ -132,6 +133,7 @@ type ArticleItemInfo struct {
@@ -132,6 +133,7 @@ type ArticleItemInfo struct {
|
|
|
|
|
Summary string |
|
|
|
|
Content template.HTML |
|
|
|
|
Author string |
|
|
|
|
Image string |
|
|
|
|
CreatedAt int64 |
|
|
|
|
Time string // Formatted time
|
|
|
|
|
TimeISO string // ISO time
|
|
|
|
|
@ -299,7 +301,7 @@ func (g *HTMLGenerator) ProcessMarkdown(markdownContent string) (string, error)
@@ -299,7 +301,7 @@ func (g *HTMLGenerator) ProcessMarkdown(markdownContent string) (string, error)
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GenerateLandingPage generates the static landing page
|
|
|
|
|
func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems []FeedItemInfo) (string, error) { |
|
|
|
|
func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems []FeedItemInfo, newestBlogItem *BlogItemInfo, newestArticleItem *ArticleItemInfo) (string, error) { |
|
|
|
|
// Collect pubkeys from feed items
|
|
|
|
|
pubkeys := make([]string, 0, len(feedItems)) |
|
|
|
|
for _, item := range feedItems { |
|
|
|
|
@ -308,7 +310,15 @@ func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems
@@ -308,7 +310,15 @@ func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems
|
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Fetch profiles for feed authors
|
|
|
|
|
// Add blog and article author pubkeys if available
|
|
|
|
|
if newestBlogItem != nil && newestBlogItem.Author != "" { |
|
|
|
|
pubkeys = append(pubkeys, newestBlogItem.Author) |
|
|
|
|
} |
|
|
|
|
if newestArticleItem != nil && newestArticleItem.Author != "" { |
|
|
|
|
pubkeys = append(pubkeys, newestArticleItem.Author) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Fetch profiles for feed authors, blog author, and article author
|
|
|
|
|
ctx := context.Background() |
|
|
|
|
profiles := g.fetchProfilesBatch(ctx, pubkeys) |
|
|
|
|
|
|
|
|
|
@ -326,7 +336,39 @@ func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems
@@ -326,7 +336,39 @@ func (g *HTMLGenerator) GenerateLandingPage(wikiPages []WikiPageInfo, feedItems
|
|
|
|
|
Profiles: profiles, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return g.renderTemplate("landing.html", data) |
|
|
|
|
// Add newest blog and article items to template data
|
|
|
|
|
type LandingPageData struct { |
|
|
|
|
PageData |
|
|
|
|
NewestBlogItem *BlogItemInfo |
|
|
|
|
NewestArticleItem *ArticleItemInfo |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
landingData := LandingPageData{ |
|
|
|
|
PageData: data, |
|
|
|
|
NewestBlogItem: newestBlogItem, |
|
|
|
|
NewestArticleItem: newestArticleItem, |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// Use renderTemplate but with custom data - need to include base.html for DOCTYPE
|
|
|
|
|
renderTmpl := template.New("landing-render").Funcs(getTemplateFuncs()) |
|
|
|
|
|
|
|
|
|
files := []string{ |
|
|
|
|
filepath.Join(g.templateDir, "components.html"), |
|
|
|
|
filepath.Join(g.templateDir, "base.html"), |
|
|
|
|
filepath.Join(g.templateDir, "landing.html"), |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
_, err := renderTmpl.ParseFiles(files...) |
|
|
|
|
if err != nil { |
|
|
|
|
return "", fmt.Errorf("failed to parse landing templates: %w", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
var buf bytes.Buffer |
|
|
|
|
if err := renderTmpl.ExecuteTemplate(&buf, "base.html", landingData); err != nil { |
|
|
|
|
return "", fmt.Errorf("failed to render landing template: %w", err) |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return buf.String(), nil |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
// GenerateWikiPage generates a wiki article page
|
|
|
|
|
|