Baking Static Sites with Python and Jinja
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!doctype html> | |
<html lang="en"> | |
<head> | |
<meta charset="utf-8"> | |
<title>{{ title }}</title> | |
<link rel="stylesheet" href="static/style.css"> | |
</head> | |
<body> | |
<div class="container"> | |
{% for feed in feeds %} | |
<div class="feed"> | |
<h3>{{ feed.channel.title }}</h3> | |
<ul> | |
{% for entry in feed.entries[0:4] %} | |
<li><a href="{{ entry.link }}">{{ entry.title }}</a></li> | |
{% endfor %} | |
</ul> | |
</div> | |
{% endfor %} | |
</div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os, shutil | |
import feedparser | |
from jinja2 import Template, Environment, FileSystemLoader | |
URLS = ( | |
'http://feeds.arstechnica.com/arstechnica/index/', | |
'https://www.reddit.com/r/programming/.rss', | |
'https://www.theatlantic.com/feed/all/', | |
'https://css-tricks.com/feed/', | |
'https://www.theverge.com/rss/index.xml', | |
'https://lobste.rs/rss' | |
) | |
class SiteGenerator(object): | |
def __init__(self): | |
self.feeds = [] | |
self.env = Environment(loader=FileSystemLoader('template')) | |
self.fetch_feeds() | |
self.empty_public() | |
self.copy_static() | |
self.render_page() | |
def fetch_feeds(self): | |
""" Request and parse all of the feeds, saving them in self.feeds """ | |
for url in URLS: | |
print(f"Fetching {url}") | |
self.feeds.append(feedparser.parse(url)) | |
def empty_public(self): | |
""" Ensure the public directory is empty before generating. """ | |
try: | |
shutil.rmtree('./public') | |
os.mkdir('./public') | |
except: | |
print("Error cleaning up old files.") | |
def copy_static(self): | |
""" Copy static assets to the public directory """ | |
try: | |
shutil.copytree('template/static', 'public/static') | |
except: | |
print("Error copying static files.") | |
def render_page(self): | |
print("Rendering page to static file.") | |
template = self.env.get_template('_layout.html') | |
with open('public/index.html', 'w+') as file: | |
html = template.render( | |
title = "Spiffy Feeds", | |
feeds = self.feeds | |
) | |
file.write(html) | |
if __name__ == "__main__": | |
SiteGenerator() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
body { | |
background-color: #DBDBDB; | |
font-family: sans-serif; | |
} | |
.container { | |
display: flex; | |
flex-flow: row wrap; | |
justify-content: space-around; | |
width: 70%; | |
margin: 5em auto; | |
} | |
.feed { | |
width: 300px; | |
background-color: #FFFFFF; | |
border: 1px solid #989898; | |
border-top: 10px solid #E75131; | |
margin: 1em; | |
} | |
.feed h3 { | |
border-bottom: 1px solid #989898; | |
margin: 0; | |
padding: 1em; | |
font-size: 1.3em; | |
} | |
.feed ul { | |
padding: 0 1em; | |
list-style: none; | |
} | |
.feed li { | |
margin: 1em 0; | |
border-bottom: 1px dashed #989898; | |
padding-bottom: 1em; | |
} | |
.feed li a { | |
color: #333333; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment