I have created a simple scraper that takes the top 10 news from a website and returns a JSON with the title and the score. I want to pass the title and the score as HTML template so I can generate a webpage. I'm not familiar with the templating Go language and I don't know how to pass the values for each of the links. Here is the HTML code that I should use and my implementation for now:
<!DOCTYPE html>
<html>
<head><linkrel="stylesheet" href="https://unpkg.com/mvp.css"
/>
</head>
<body>
<h1>{{.PageTitle}}</h1>
<ul>
{{range .Links}}
<li>{{.Title}}: {{.Score}}</li>
{{end}}
</ul>
</body>
</html>
My code:
package main
import (
"encoding/json"
"html/template"
"log"
"net/http"
"strconv"
)
type TopStories struct {
Title string `json:"title"`
Score int `json:"score"`
}
type TopStoriesPayload struct {
TopStories []TopStories
}
type NewsScraper struct {
url string
Data []TopStories
}
type templateData struct {
PageTitle string
Data []TopStories
}
func NewNewsScraper(url string) *NewsScraper {
return &NewsScraper{url: url}
}
func Top10Stories() []string {
req, err := http.NewRequest("GET", "https://hacker-news.firebaseio.com/v0/topstories.json", nil)
if err != nil {
log.Fatal(err)
}
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
var IDs []int
json.NewDecoder(resp.Body).Decode(&IDs)
IDs = IDs[:10]
var IDsString []string
for _, id := range IDs {
IDsString = append(IDsString, strconv.Itoa(id))
}
return IDsString
}
func (n *NewsScraper) GetTopStories() {
req, err := http.NewRequest("GET", n.url, nil)
if err != nil {
log.Fatal(err)
}
for _, id := range Top10Stories() {
req.URL.Path = "/v0/item/" id ".json"
resp, err := http.DefaultClient.Do(req)
if err != nil {
log.Fatal(err)
}
var topStory TopStories
json.NewDecoder(resp.Body).Decode(&topStory)
n.Data = append(n.Data, topStory)
}
}
//create html template handler for top stories
func HTMLHandler(w http.ResponseWriter, r *http.Request) {
scraper := NewNewsScraper("https://hacker-news.firebaseio.com")
scraper.GetTopStories()
tmpl:= template.Must(template.ParseFiles("template.html"))
data := templateData{
PageTitle: "Top Stories",
Data :[]TopStories{
//what should I put here?
},
}
tmpl.Execute(w, data)
}
func main() {
mux := http.NewServeMux()
mux.HandleFunc("/top", HTMLHandler)
http.ListenAndServe(":8080", mux)
}
CodePudding user response:
I see three issues with your code:
a) The template.html file should have space between link & rel
<linkrel="stylesheet" href="https://unpkg.com/mvp.css"/>
to
<link rel="stylesheet" href="https://unpkg.com/mvp.css"/>
b) The template.html file should contain .Data
instead of .Links
.
c) The go code should be replaced from the below
Data :[]TopStories{
//what should I put here?
},
to
Data : scraper.Data,