Reading rss feed and generating static html with golang
Tags: go, programming, tutorial
Published: 2022-12-20 18:16:16

## 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](https://www.devshirt.club/) shop.

They have rss of their newest t-shirt releases. 
You can find it [here](https://www.devshirt.club/developer-shirt/rss.xml)

### 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)
	}
}

```