Writing Software To Organise My Website Since I Cannot Be Stuffed To Do It Myself
Now I am going to make a confession, I am definitely not the best when it comes to organisation. For an example, my computer desk looks something like the picture below, but with more coffee mugs.
Unlike in the physical realm, I can write software that will manage all the logistics for future me. For this website I wrote three controller modules:
-
fileparser.py
: The lowest level of control for reading and writing files.
-
markdownparser.py
: Parses my articles that I write in markdown into a sexy Jinja template.
-
pagecontrol.py
: Responsible for access control to pages and sorting articles into categories and release date.
The most interesting aspect from a design point of view is how I parse markdown documents to juicy Jinja templates.
Markdown To Beautiful Web Pages
I used the
markdown
Python library to parse my articles that I write using markdown notation to HTML. However, this parsing capability by itself can only generate very basic HTML. That is when
BeautifulSoup
comes in to make it extremely easy to modify attributes.
To demonstrate how easy it is to use both markdown and BeautifulSoup to automatically style pretty HTML documents from markdown, let us say that we want to parse the following markdown document.
somestoof.md
# Hi There
How are ya going.
This will be parse to the following HTML.
somestoof.html
<h1>Hi There</h1>
<p>How are ya going.</p>
This can be done with the following Python code.
import markdown
with open("somestoof.md", "r") as f:
md_raw = f.read()
with open("somestoof.html", "w") as f:
f.write(markdown.markdown(md_raw, extensions=["fenced_code", "codehilite"]))
The
extensions
arguments are just for properly parsing code snippets into HTML which is not shown in this example.
Now let's say we have made a cool styling class called 'sick_header' for
<h1>
tags, we can parse the text of the HTML document to BeautifulSoup to find all of the appropriate tags and add the attributes.
from bs4 import BeautifulSoup
import markdown
def modify_tag_attributes(tag_name, attrs, soup):
"""
Automatically modifies the attributes for a given type of HTML tag.
Parameters:
tag_name: str
the name of the type of HTML tag to modify
attrs: dict
a dictionary mapping the new attribute key value pairs.
soup: bs4.BeautifulSoup
the soup that we are cooking ;)
"""
# Loops through all of the tags with the same tag name given, eg. 'h1'
for tag in soup.find_all(tag_name):
for attr_name, attr_value in attrs.items():
tag[attr_name] = attr_value
with open("somestoof.md", "r") as f:
md_raw = f.read()
html_raw = markdown.markdown(md_raw, extensions=["fenced_code", "codehilite"])
soup = BeautifulSoup(html_raw, "html.parser")
modify_tag_attributes("h1", {"class" : "sick_header"}, soup)
with open("somestoof.html", "w") as f:
f.write(soup.prettify())
Now my
markdownparser
module is a bit more complex since it parses the markdown to a Jinja template and sorts the parsed HTML to the blocks used in my base template. However, this part of the markdown parsing has been left as an exercise for the reader.
Putting It All Together
Putting together my controllers, parsing files and Flask code I now have a super easy method for writing new articles and let my code do everything else for me. Within my repository I have a folder called
markdown_entries
, where I can write all of my articles in markdown and on each startup of the website it will check if I have made any updates and if so parses the article to a Jinja template. The folder structure for creating this blog post is shown below.
markdown_entries/
└── blog
└── creating_site
├── content.md
├── images
│ ├── facepunch.jpg
│ ├── ilovevincent.png
│ ├── messydesk.jpeg
│ └── solid_state.png
└── prop.yaml
prop.yaml
is just a YAML configuration file that I use to specify article passwords, page names, description, categories, etc.