Reading rss feed and generating static html with golang
Mike Hyden
Posted on December 20, 2022
Prerequisite
In order to follow this tutorial you will need to have golang installed on your machine
Project
1. Finding rss feed
We're gonna use this rss feed from this cool developers tshirt shop.
They have rss of their newest t-shirt releases.
You can find it here
2. Creating a new project
1.) In your $GOPATH
create a new project
mkdir rss_feed
2.) navigate to directory and init mod
cd rss_feed && go mod init
3.) install rss reader dependency
go get github.com/mmcdole/gofeed
3. Reading the rss feed
Reading the rss feed is super simple with mmcdole's library
our full main:
package main
import (
"log"
"github.com/mmcdole/gofeed"
)
var FeedUrl = "https://www.devshirt.club/developer-shirt/rss.xml"
func main() {
fp := gofeed.NewParser()
fp.UserAgent = "MyCustomAgent 1.0"
feed, _ := fp.ParseURL(FeedUrl)
log.Printf("read the feed %#v", feed)
}
4. Creating html template
Here we are gonna use golangs built in template, what it will expect is for us to pass a slice of articles, and in return it will generate us a simple html page.
type Article struct {
Title string
Description string
ImageTitle string
ImageUrl string
Link string
}
var siteTemplate string = `
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1> Example of dynamic rss feed parsing </h1>
{{ range $key, $item := . }}
<article>
<h2>{{ $item.Title }}</h2>
<img src="{{$item.ImageUrl}}" style="max-width: 400px;" />
<p>
{{$item.Description}}
<br />
<a href="{{$item.Link}}"/> Read more </a>
</p>
</article>
{{ end }}
</div>
</body>
</html>
`
5. Tying it all together
We are gonna load our feed, based on that iterate and create our slice of articles and simply output to console our generated html
package main
import (
"log"
"os"
"text/template"
"github.com/mmcdole/gofeed"
)
var FeedUrl = "https://www.devshirt.club/developer-shirt/rss.xml"
type Article struct {
Title string
Description string
ImageTitle string
ImageUrl string
Link string
}
var siteTemplate string = `
<html>
<head>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<!-- Optional theme -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/css/bootstrap-theme.min.css" integrity="sha384-rHyoN1iRsVXV4nD0JutlnGaslCJuC7uwjduW9SVrLvRYooPp2bWYgmgJQIXwl/Sp" crossorigin="anonymous">
<!-- Latest compiled and minified JavaScript -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@3.3.7/dist/js/bootstrap.min.js" integrity="sha384-Tc5IQib027qvyjSMfHjOMaLkfuWVxZxUPnCJA7l2mCWNIpG9mGCD8wGNIcPD7Txa" crossorigin="anonymous"></script>
</head>
<body>
<div class="container">
<h1> Example of dynamic rss feed parsing </h1>
{{ range $key, $item := . }}
<article>
<h2>{{ $item.Title }}</h2>
<img src="{{$item.ImageUrl}}" style="max-width: 400px;" />
<p>
{{$item.Description}}
<br />
<a href="{{$item.Link}}"/> Read more </a>
</p>
</article>
{{ end }}
</div>
</body>
</html>
`
func main() {
fp := gofeed.NewParser()
fp.UserAgent = "MyCustomAgent 1.0"
feed, err := fp.ParseURL(FeedUrl)
if err != nil {
log.Fatal(err)
}
var articles []Article
for _, item := range feed.Items {
article := Article{
Title: item.Title,
Description: item.Description,
Link: item.Link,
ImageUrl: item.Extensions["media"]["content"][0].Attrs["url"],
}
articles = append(articles, article)
}
tmpl, err := template.New("site").Parse(siteTemplate)
if err != nil {
log.Fatal(err)
}
err = tmpl.Execute(os.Stdout, articles)
if err != nil {
log.Fatal(err)
}
}
Posted on December 20, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.