Commit edfcf822 authored by Marien Fressinaud's avatar Marien Fressinaud

Generate an Atom feed automatically

parent e0e669e1
...@@ -73,6 +73,8 @@ $ tree ...@@ -73,6 +73,8 @@ $ tree
├── articles ├── articles
│   └── my-article.md │   └── my-article.md
├── site ├── site
│   ├── feeds
│   │   └── all.atom.xml
│   ├── index.html │   ├── index.html
│   ├── my-article.html │   ├── my-article.html
├── theme ├── theme
...@@ -85,6 +87,9 @@ $ echo site/my-article.html ...@@ -85,6 +87,9 @@ $ echo site/my-article.html
Please note that `./articles` folder only accepts Markdown files (i.e. Please note that `./articles` folder only accepts Markdown files (i.e.
extension is `.md`). extension is `.md`).
As you can see, it also generates automatically [an Atom feed](https://en.wikipedia.org/wiki/Atom_(Web_standard))
under `./site/feeds/all.atom.xml`.
You can define meta variables in the Markdown file which will be accessible You can define meta variables in the Markdown file which will be accessible
then in the template. Variables are uppercased and prepended by `ARTICLE_`. For then in the template. Variables are uppercased and prepended by `ARTICLE_`. For
example, for the following Markdown file: example, for the following Markdown file:
...@@ -158,6 +163,8 @@ $ tree ...@@ -158,6 +163,8 @@ $ tree
├── articles ├── articles
│   └── my-article.md │   └── my-article.md
├── site ├── site
│   ├── feeds
│   │   └── all.atom.xml
│   ├── index.html │   ├── index.html
│   ├── my-article.html │   ├── my-article.html
│   └── style.css │   └── style.css
......
...@@ -12,6 +12,8 @@ import uuid ...@@ -12,6 +12,8 @@ import uuid
import markdown import markdown
import pytz import pytz
import xml.etree.ElementTree as ET
import boopsy import boopsy
...@@ -184,12 +186,68 @@ def main(): ...@@ -184,12 +186,68 @@ def main():
article = Article(slug, article_file.read(), configuration=configuration) article = Article(slug, article_file.read(), configuration=configuration)
articles.append(article) articles.append(article)
# If there is no articles, stop there
if len(articles) == 0:
return
# And write them in the ./site folder # And write them in the ./site folder
for article in articles: for article in articles:
output_filepath = os.path.join(output_path, f"{article.slug()}.html") output_filepath = os.path.join(output_path, f"{article.slug()}.html")
with open(output_filepath, "w") as output_file: with open(output_filepath, "w") as output_file:
output_file.write(article.render()) output_file.write(article.render())
# Finish by writing the news feed
feed_dirpath = os.path.join(output_path, "feeds")
os.mkdir(feed_dirpath)
# Just create some variables so it's easier to manipulate after
site_url = configuration["SITE_URL"]
site_uuid = configuration["SITE_UUID"]
site_title = configuration["SITE_TITLE"]
site_timezone = configuration["SITE_TIMEZONE"]
timezone = pytz.timezone(site_timezone)
current_datetime = datetime.datetime.now(tz=timezone)
# Start to build the XML feed with the root information
feed = ET.Element("feed", xmlns="http://www.w3.org/2005/Atom")
ET.SubElement(feed, "title").text = site_title
ET.SubElement(
feed,
"link",
href=f"{site_url}feeds/all.atom.xml",
rel="self",
type="application/atom+xml",
)
ET.SubElement(feed, "link", href=site_url, rel="alternate", type="text/html")
ET.SubElement(feed, "id").text = f"urn:uuid:{site_uuid}"
ET.SubElement(feed, "updated").text = current_datetime.isoformat(timespec="seconds")
for article in articles:
# and complete it for each article
entry = ET.SubElement(feed, "entry")
ET.SubElement(entry, "title").text = article.title()
ET.SubElement(entry, "id").text = f"urn:uuid:{article.uuid()}"
article_author = article.author()
if article_author:
author = ET.SubElement(entry, "author")
ET.SubElement(author, "name").text = article_author
ET.SubElement(
entry, "link", href=article.url(), rel="alternate", type="text/html"
)
ET.SubElement(entry, "published").text = article.date().isoformat(
timespec="seconds"
)
article_update = article.update()
if article_update:
ET.SubElement(entry, "updated").text = article_update.isoformat(
timespec="seconds"
)
ET.SubElement(entry, "content", type="html").text = article.content()
# And write it on the filesystem
feed_filepath = os.path.join(feed_dirpath, "all.atom.xml")
ET.ElementTree(feed).write(feed_filepath, encoding="unicode", xml_declaration=True)
if __name__ == "__main__": if __name__ == "__main__":
try: try:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment