Home Blog

Creating My Own Blogging Platform

edit: I have since replaced this python/markdown system: Blogging with Emacs and Org

Today I've started working on creating a new blogging platform for my website. Previously I had my blog setup with Wordpress, but I found that I wasn't using it much, and that it provided much more than I needed.

As a minimalist, I like the idea of a barebones style platform that I can create all the features for. It should be easy to install and maintain, which means using as little packages as possible. Currently the features that I am aiming for are the following:

For this post I will focus on the first two items.

Publishing a markdown file has two steps:

Both of these are straightforward. First I need a way convert markdown to html. Python should be able to handle this: pip install markdown

Perfect!

Then I will need to open the markdown file, read it into a string, pass it into markdown(), and finally write it into a .html file. The only information the program will need for me is the post number, which can come from a command line argument.

After this the script will have to insert a new table row (<tr>) element into blog.html

<tr><td><a href="posts/4.html">Creating My Own Blogging Platform </a></td><td>Thu 07/19/18</td></tr>

This needs three things: the link, the date of the post, and the title. The link will always be 'posts/<post-number>.html', so that's easy. The title can be found by looking at the first line of the .md file, and the date will be on the second line.

The outputted html needs to include a few more things. First a `<link>` tag so that all the posts can share the same style sheet:

html = '<LINK REL=StyleSheet HREF="style.css" TYPE="text/css">\n' + html

And finally a fixed header so that readers can navigate back to the index page. For this I'll create a partial file and have the script read it and paste it into the output.

header.html

<div class="header">
    <form action="../blog.html">
      <input type="submit" value="blog" />
    </form>
</div>

create-post.py

 #!/usr/bin/python3
from markdown import markdown
from sys      import argv
 """
adds a new <tr> element to blog.html
new row will be the first to keep reverse chronoligical order
"""
def add_entry_to_list(post_num) :
  post_num = str(post_num)
  md     = open(post_num+'.md')
  header = md.readline()[3:-1] #slice omits the beginning hashes and trailing \n
  date   = md.readline()[5:-1]
  md.close()
  html = open('../blog.html')
  lines = html.readlines()
  html.close()
  new_element = '<tr><td><a href="posts/'+post_num+'.html">'+header+'</a></td><td>'+date+'</td></tr>\n'
  i = len(lines) - 1
  while i > 0 :
    if lines[i].strip() == new_element.strip() :
      print('list item already exists')
      return
    if lines[i].strip() == '<tbody>' :
      lines.insert(i+1,' '+4+new_element) #indent new tag properly and add to file
      print('new list item created')
      html = open('../blog.html','wt')
      html.writelines(lines)
      html.close()
      return
    i -= 1
"""
reads from the markdown file (post_num).md and writes (post_num).html
"""
def add_entry(post_num) :
  try :
    md = open(post_num+'.md')
  except :
    print(post_num+'.md'+' does not exist!')
    return
  h = open('header.html')
  header = h.read()
  h.close()
  html = markdown(md.read())
  html = '<LINK REL=StyleSheet HREF="style.css" TYPE="text/css">\n' + html
  html = header + html
  md.close()
  post = open(post_num+'.html','wt')
  post.write(html)
  post.close()
  print('post updated')
  add_entry_to_list(post_num)
 if __name__ == '__main__' :
  post_num = argv[1]
  add_entry(post_num)

Next up is adding some CSS. I'm all for minimalism, but plain markdown is pretty bland. Padding, a bigger font size, and a light background will made it easier on the eyes. The post title should be in the middle and images should be kept from taking the entire page up.

html {
  padding: 7%;
  background: darkgrey;
}
 body {
  background: lightgrey;
  padding:10px;
  outline: solid darkslateblue 2px;
}
 h2 {
  margin: auto;
  text-align: center;
}
 img {
  display: block;
  width: auto;
  height: auto;
  max-width: 50%;
  margin: 20px auto;
  border-radius:8px;
}
 p {
  font-size: 18px;
}

For the code snippets I'll make a thin outline and give them a lighter background so that it stands out.

pre {
  outline: solid black 1px;
  background: whitesmoke;
  padding: 5px;
}


The header should be fixed so users don't need to scroll all the way up to go back. A darker background will work well.

.header {
  position:fixed;
  top:0px;
  left:0px;
  width:100%;
  background:#5f5f5f;
  color: #CCC;
  padding: 10px 20px 10px 20px;
  font-size:25px;
}

Finally the button itself needs colors, and should highlight on mouse over.

.header form {
  display: inline;
}
 input {
  background:#5f5f5f;
  color:white;
  border: solid #5f5f5 2px;
  transition-duration: 0.4s;
  border-radius: 4px;
  font-size:20px;
}
 input:hover {
  background:grey;
  color:white;
  border: solid #5f5f5 2px;
  transition-duration: 0.4s;
  border-radius: 4px;
  font-size:20px;
}

A great part of markdown is that you can add any html tag whenever you need it. So my blog will be able to support whatever interactive elements I feel like making. Pretty cool!

<button id="before-after"> Before/After </button>
<script>
document.getElementById('before-after').addEventListener('click',function() {
  document.styleSheets[0].disabled = !document.styleSheets[0].disabled;
  document.styleSheets[1].disabled = !document.styleSheets[1].disabled;
});
</script>

The style looks okay for now, but I will most likely keep tinkering with it.

EDIT: I have made significant changes since then. Here's the result of the above style Updated source code can be found here

  generated with    29.0.50 9.5.2 on 05/12/22