From 281515ca89637586d4755b3de1cb34dfba150f8a Mon Sep 17 00:00:00 2001
From: Alex Suraci <asuraci@pivotal.io>
Date: Wed, 15 Jul 2020 15:28:03 -0400
Subject: [PATCH] ugly wip: add blog feed to main page

there's no good place to put it :(

Signed-off-by: Alex Suraci <asuraci@pivotal.io>
---
 css/booklit.css          | 23 ++++++++++++++++++++
 go.mod                   |  1 +
 go.sum                   | 12 ++++++++++
 go/docs/plugin.go        | 47 +++++++++++++++++++++++++++++++++++++++-
 html/blog-feed-item.tmpl |  9 ++++++++
 html/blog-feed.tmpl      |  9 ++++++++
 html/header.tmpl         |  1 +
 html/inline-header.tmpl  |  1 -
 less/index.less          | 31 ++++++++++++++++++++++++++
 lit/index.lit            |  4 ++++
 10 files changed, 136 insertions(+), 2 deletions(-)
 create mode 100644 html/blog-feed-item.tmpl
 create mode 100644 html/blog-feed.tmpl
 create mode 100644 html/header.tmpl
 delete mode 100644 html/inline-header.tmpl

diff --git a/css/booklit.css b/css/booklit.css
index d9fcd322..6308db90 100644
--- a/css/booklit.css
+++ b/css/booklit.css
@@ -900,6 +900,29 @@ body.index .page-content h2:first-child {
 .side-by-side .pipeline-svg {
   padding: 48px;
 }
+#section_index h1 {
+  border: 0;
+  padding: 0;
+}
+.blog-feed {
+  padding: 70px;
+  margin: -70px;
+  margin-bottom: 0px;
+}
+.blog-feed .blog-posts {
+  margin-bottom: 0;
+}
+.blog-feed .blog-feed-item h2 {
+  margin-bottom: 0 !important;
+}
+.blog-feed .blog-feed-item .post-meta {
+  color: #7a7373;
+  font-size: 14px;
+}
+.blog-feed .blog-feed-item .post-excerpt {
+  margin-top: 0.5em;
+  margin-bottom: 0;
+}
 @media (max-width: 1100px) {
   .side-by-side {
     grid-template-columns: 100%;
diff --git a/go.mod b/go.mod
index efd7c61e..1659f419 100644
--- a/go.mod
+++ b/go.mod
@@ -4,6 +4,7 @@ require (
 	github.com/blang/semver v3.5.1+incompatible
 	github.com/google/go-github v17.0.0+incompatible
 	github.com/google/go-querystring v1.0.0 // indirect
+	github.com/mmcdole/gofeed v1.0.0
 	github.com/prometheus/client_model v0.2.0
 	github.com/prometheus/common v0.9.1
 	github.com/vito/booklit v0.11.1-0.20200528143027-05f9902b5ed9
diff --git a/go.sum b/go.sum
index 459cdae5..943f958e 100644
--- a/go.sum
+++ b/go.sum
@@ -1,4 +1,6 @@
 cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
+github.com/PuerkitoBio/goquery v1.5.0 h1:uGvmFXOA73IKluu/F84Xd1tt/z07GYm8X49XKHP7EJk=
+github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg=
 github.com/agext/levenshtein v1.2.3 h1:YB2fHEn0UJagG8T1rrWknE3ZQzWM06O8AMAatNn7lmo=
 github.com/agext/levenshtein v1.2.3/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
 github.com/alecthomas/assert v0.0.0-20170929043011-405dbfeb8e38 h1:smF2tmSOzy2Mm+0dGI2AIUHY+w0BUc+4tn40djz7+6U=
@@ -16,10 +18,13 @@ github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuy
 github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc=
 github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
 github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0=
+github.com/andybalholm/cascadia v1.0.0 h1:hOCXnnZ5A+3eVDX8pvgl4kofXv2ELss0bKcqRySc45o=
+github.com/andybalholm/cascadia v1.0.0/go.mod h1:GsXiBklL0woXo1j/WYWtSYYC4ouU9PqHO0sqidkEA4Y=
 github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24TaqPxmxbtue+5NUziq4I4S80YR8gNf3Q=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/blang/semver v3.5.1+incompatible h1:cQNTCjp13qL8KC3Nbxr/y2Bqb63oX6wdnnjpJbkM4JQ=
 github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/codegangsta/cli v1.20.0/go.mod h1:/qJNoX69yVSKu5o4jLyXAENLRyk1uhi7zkbQ3slBdOA=
 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964 h1:y5HC9v93H5EPKqaS1UYVg1uYah5Xf51mBfIoWehClUQ=
 github.com/danwakefield/fnmatch v0.0.0-20160403171240-cbb64ac3d964/go.mod h1:Xd9hchkHSWYkEqJwUGisez3G1QY8Ryz0sdWrLPMGjLk=
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
@@ -60,6 +65,10 @@ github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hd
 github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
+github.com/mmcdole/gofeed v1.0.0 h1:PHqwr8fsEm8xarj9s53XeEAFYhRM3E9Ib7Ie766/LTE=
+github.com/mmcdole/gofeed v1.0.0/go.mod h1:tkVcyzS3qVMlQrQxJoEH1hkTiuo9a8emDzkMi7TZBu0=
+github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf h1:sWGE2v+hO0Nd4yFU/S/mDBM5plIU8v/Qhfz41hkDIAI=
+github.com/mmcdole/goxpp v0.0.0-20181012175147-0068e33feabf/go.mod h1:pasqhqstspkosTneA62Nc+2p9SOBBYAPbnmRRWPQ0V8=
 github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063 h1:V7s6vhIrNeOqocziAmRoVJh6gnPPx83ovlpT7Hf5shI=
 github.com/mna/pigeon v1.0.1-0.20200224192238-18953b277063/go.mod h1:rkFeDZ0gc+YbnrXPw0q2RlI0QRuKBBPu67fgYIyGRNg=
 github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
@@ -111,8 +120,10 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
 golang.org/x/mod v0.2.0 h1:KU7oHjnv3XNWfa5COkzUifxZmxp1TyI7ImMXqFxLwvQ=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
+golang.org/x/net v0.0.0-20180218175443-cbe0f9307d01/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
+golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190613194153-d28f0bde5980 h1:dfGZHvZk057jK2MCeWus/TowKpJ8y4AmooUzdBSR9GU=
@@ -139,6 +150,7 @@ golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7w
 golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20200413165638-669c56c373c4 h1:opSr2sbRXk5X5/givKrrKj9HXxFpW2sdCiP8MJSKLQY=
 golang.org/x/sys v0.0.0-20200413165638-669c56c373c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
+golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/tools v0.0.0-20190830223141-573d9926052a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
diff --git a/go/docs/plugin.go b/go/docs/plugin.go
index a6a02305..3d634d37 100644
--- a/go/docs/plugin.go
+++ b/go/docs/plugin.go
@@ -14,6 +14,7 @@ import (
 
 	"github.com/blang/semver"
 	"github.com/google/go-github/github"
+	"github.com/mmcdole/gofeed"
 	dto "github.com/prometheus/client_model/go"
 	"github.com/prometheus/common/expfmt"
 	"golang.org/x/oauth2"
@@ -74,11 +75,25 @@ func (p Plugin) Codeblock(language string, code booklit.Content) booklit.Content
 	}
 }
 
+func (p Plugin) Header(depth, content booklit.Content) booklit.Content {
+	return booklit.Styled{
+		Style:   "header",
+		Content: content,
+		Block:   true,
+		Partials: booklit.Partials{
+			"Depth": depth,
+		},
+	}
+}
+
 func (p Plugin) InlineHeader(content booklit.Content) booklit.Content {
 	return booklit.Styled{
-		Style:   "inline-header",
+		Style:   "header",
 		Content: content,
 		Block:   true,
+		Partials: booklit.Partials{
+			"Depth": booklit.String("2"),
+		},
 	}
 }
 
@@ -98,6 +113,36 @@ func (p Plugin) SplashIntro(intro, downloads booklit.Content) {
 	)
 }
 
+func (p Plugin) BlogFeed() (booklit.Content, error) {
+	feed, err := gofeed.NewParser().ParseURL("https://blog.concourse-ci.org/rss/")
+	if err != nil {
+		return nil, fmt.Errorf("parse blog feed: %w", err)
+	}
+
+	items := booklit.Sequence{}
+	for _, item := range feed.Items {
+		items = append(items, booklit.Styled{
+			Style: "blog-feed-item",
+			Block: true,
+			Content: booklit.Link{
+				Content: booklit.String(item.Title),
+				Target:  item.Link,
+			},
+			Partials: booklit.Partials{
+				"Author":      booklit.String(item.Author.Name),
+				"PublishedAt": booklit.String(item.PublishedParsed.Format("January 6, 2006")),
+				"Description": booklit.String(item.Description),
+			},
+		})
+	}
+
+	return booklit.Styled{
+		Style:   "blog-feed",
+		Block:   true,
+		Content: items,
+	}, nil
+}
+
 func (p Plugin) QuickStart(content booklit.Content) booklit.Content {
 	return booklit.Styled{
 		Style:   "quick-start",
diff --git a/html/blog-feed-item.tmpl b/html/blog-feed-item.tmpl
new file mode 100644
index 00000000..8699f6c6
--- /dev/null
+++ b/html/blog-feed-item.tmpl
@@ -0,0 +1,9 @@
+<div class="blog-feed-item">
+  <h2>{{.Content | render}}</h2>
+  <div class="post-meta">
+    <span class="post-date">{{.Partial "PublishedAt" | render}}</span>
+    by
+    <span class="post-author">{{.Partial "Author" | render}}</span>
+  </div>
+  <p class="post-excerpt">{{.Partial "Description" | render}}</p>
+</div>
diff --git a/html/blog-feed.tmpl b/html/blog-feed.tmpl
new file mode 100644
index 00000000..cc72319f
--- /dev/null
+++ b/html/blog-feed.tmpl
@@ -0,0 +1,9 @@
+<div class="blog-feed">
+  <h1>Latest news</h1>
+
+  <div class="blog-posts side-by-side">
+    {{range $item := slice .Content 0 2}}
+    {{. | render}}
+    {{end}}
+  </div>
+</div>
diff --git a/html/header.tmpl b/html/header.tmpl
new file mode 100644
index 00000000..4c4d93bf
--- /dev/null
+++ b/html/header.tmpl
@@ -0,0 +1 @@
+<h{{.Partial "Depth" | render}}>{{.Content | render}}</h{{.Partial "Depth" | render}}>
diff --git a/html/inline-header.tmpl b/html/inline-header.tmpl
deleted file mode 100644
index 6eb1eee4..00000000
--- a/html/inline-header.tmpl
+++ /dev/null
@@ -1 +0,0 @@
-<h2>{{.Content | render}}</h2>
diff --git a/less/index.less b/less/index.less
index ffe38827..ad6a19fa 100644
--- a/less/index.less
+++ b/less/index.less
@@ -283,6 +283,37 @@ body.index .page-content h2 {
   }
 }
 
+#section_index h1 {
+  border: 0;
+  padding: 0;
+}
+
+.blog-feed {
+  padding: 70px;
+  margin: -70px;
+  margin-bottom: 0px;
+
+  .blog-posts {
+    margin-bottom: 0;
+  }
+
+  .blog-feed-item {
+    h2 {
+      margin-bottom: 0 !important;
+    }
+
+    .post-meta {
+      color: @grey-secondary;
+      font-size: 14px;
+    }
+
+    .post-excerpt {
+      margin-top: 0.5em;
+      margin-bottom: 0;
+    }
+  }
+}
+
 @media(max-width: @page-width) {
   .side-by-side {
     grid-template-columns: 100%;
diff --git a/lit/index.lit b/lit/index.lit
index cefca8d1..4a53d0bd 100644
--- a/lit/index.lit
+++ b/lit/index.lit
@@ -16,6 +16,10 @@
   \download-links
 }
 
+\blog-feed
+
+\header{1}{Features}
+
 \side-by-side{
   \inline-header{Configure as code}
 
