From Django Zinnia Blog to Jekyll Static Sites
django django-zinnia jekyllI’ve been neglecting my homepage for a while, and as a dynamic site written in Django, it is harder to manage and I just don’t want to spend the same amount of effort anymore to run a page I don’t frequently update.
To remedy this, I decided to throw everything into static files and build the static files when I do deploys of new content instead of dynamically rendering the pages on each request.
The hardest part about this migration was my old blog posts that were not written in markdown and were located in a database that my Django server was attached to. To remedy this I wrote a script to convert Zinnia blog entries into markdown files in Jekyll’s format.
If you would like to migrate your own blog to Jekyll, you can use the Django
management command to dump the data into a JSON file and point the script I
wrote at it. To get the data out of your DB, from your Django host run,
python manage.py dumpdata zinnia --indent=2 > blog_data.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
#!/usr/bin/env python3
# convert_zinnia.py - script for parsing zinnia db blob into jekyll posts
import json
import os
import html2text
# open database of zinna posts created from django's dumpdb command
blog_dump_file = 'blog_data.json'
blog_file = open(blog_dump_file)
blog_json = json.loads(blog_file.read())
# go over each item in the dump and create files for zinnia's entries
for item in blog_json:
if item['model'] == u'zinnia.entry':
fields = item['fields']
title = fields['title']
creation_date = fields['creation_date']
status = fields['status']
slug = fields['slug']
content = fields['content']
date, time = creation_date.split(' ')
year, month, day = date.split('-')
# convert posts from HTML format into markdown for Jekyll
md_content = html2text.html2text(content)
if status == 0:
status_name = 'draft'
if status == 1:
status_name = 'unpublished'
if status == 2:
status_name = 'published'
if status == 3:
status_name = 'other3'
if status in [0,1]:
filename = '%s' % (slug)
os.makedirs('_drafts', exist_ok=True)
new_file = open('_drafts/%s.markdown' % filename, 'w')
if status in [2]:
filename = '%s-%s-%s-%s' % (year,month,day,slug)
os.makedirs('_posts', exist_ok=True)
new_file = open('_posts/%s.markdown' % filename, 'w')
# create the file for the post and save it to either _posts or _drafts
header = '''---
layout: post
title: "%s"
categories: blog
---
%s
''' % (title, md_content,)
new_file.write(header)
new_file.close()
This script creates _posts
and a _drafts
directory which you then can copy
over to your Jekyll installation. Before publishing your content from Django
into Jekyll, be sure to inspect the script output and rendering to make sure
you are getting the expected out. I had to hand tune the output files but it
was definitely easier than the first couple of entries that I copied over by
hand.
One last thing to remember and take care of is making sure your old URLs match your new URLS. The Jekyll file name scheme determines the URLs and the blog category in each post header puts it in the right path.