How to export the Markdown I have written?

I tried to export my posts to a .bar file, but from what I can see it contains only the rendered HTML, not the original Markdown.

How can I export that?

If you want the Markdown files, you can choose the “Export theme and Markdown” option under Posts → Export. I would keep the .bar file too, because it contains all your uploaded photos.

1 Like

Thanks @manton. This is very good advice.

I had this question too. I recently tried to download my site and found the photos missing, but then when I downloaded using .bar, that unzipped into a json file (which seemed to be formatting), and a index.html, which was all the posts squished together with no formatting and no photos. The photos were in folders, but not connected to the content at all. But exporting to markdown gave me no photos at all.

What I want is to be able to download my content the way a Hugo site would normally appear - with Content/Blog/Entries/folderswithphotos, etc. I want the site to be comprehensible by a human looking at the files, and something I could tinker with and put right up in a self-hosted Hugo installation if I chose to do that. Is this possible?

There’s not currently an export download that is exactly that, but if you download both the .bar and the Markdown file, you will have everything. You’ll need to unzip the .bar and move the uploads folder into the Markdown folder. Then it should be identical to what Micro.blog runs through Hugo.

Maybe we should have an option to download the Markdown + images to save a step.

Downloading both together would be great! After years of trying to back up WordPress blogs that just become buggy messes of code I can’t read (and that never import properly or have the original photos), my goal is to be able to back-up my site into files that are organized and make sense. I really love Hugo for this.

I often think about about the digital stuff I’ll leave behind for the kids, and how a blog is something my kids and even grandkids might want to look at someday (or me! when I’m old! :)). With the Hugo structure, even if the site wasn’t loaded online anywhere, you could go through the markdown files and read it that way and still fully comprehend it.

With the .bar and markdown exports, I wasn’t sure how to re-create the original files, like where to put the photos in the markdown files so that they would match up/link unto the entries.

1 Like

FWIW. I wrote a Python script that takes the content of the bar-file and convert it to the format that blot.im uses (very similar to Hugo), and among other things move a post and it’s images to a separate folder. You can find it here Jan Erik Moström - Micro.blog to blot script

1 Like

Hi Jan, that link seems to go to a 404 page for me?

You can click the three dots next to your blog name and select export. One option will have the markdown and all your theme files.

Hmmm, it looks like did a restart of the blog. I should have that entry on another computer. I will look and see if I can find during the week and upload it again.

Now I remember what happened, I did an import of bar-file from another micro.blog and everything became a big mess. So, I started from scratch. But here is the code

# This script assumes it's launched from inside the micro.blog export folder

import frontmatter
import os
import re
import shutil
from dateutil import parser

basedir = '/Users/jem/Desktop/TestOutput'
imgpat = re.compile('<img.*src="(.*?)".*?/>')
domainpat = re.compile('https:.*/uploads/')
blothead = 'title: {}\ndate: {}\n\n'

# I really dislike doing this but ...
imgdata = {'destdir':'',}

def copyimage(src,dest):
	shutil.copy(os.path.join('uploads',src), os.path.join(imgdata['destdir'],dest))
	
def imgproc(m):
	orgpath = m.group(1)
	
	# Remove domain info
	p = domainpat.sub('',orgpath)
	n = '_'+os.path.basename(p)
	copyimage(p,n)
	return '![]('+n+')'

def formatblotpost(post):
	# Update content and copy image files
	modifiedcontent = imgpat.sub(imgproc,post.content)
	if post.metadata['title'] == '':
		post.metadata['title'] = post.metadata['datetitle']
	return blothead.format(post.metadata['title'],post.metadata['date']) + modifiedcontent
		
def create_destdir(newbase,curfilepath,poststamp):
	(odir,oname) = os.path.split(curfilepath)
	newdir = os.path.join(newbase,odir)
	# Check if the dest dir exists, this should be the year & month folder
	if not os.path.isdir(newdir):
		os.makedirs(newdir)
	postdir = os.path.join(newdir,poststamp)
	# This should not be possible but ...
	if os.path.isdir(postdir):
		raise Exception('Post dir already exists')
	else:
		os.mkdir(postdir)
	return postdir

def handlepost( destdir, source ):
	print(source)
	
	try:
		postcontent = frontmatter.load(source)
		meta = postcontent.metadata
		pdate = parser.parse(meta['date'])
		pdir = create_destdir(destdir,source,pdate.strftime('%Y%m%d_%H%M%S'))
		postcontent['datetitle']= pdate.strftime('%Y-%m-%d %H:%M:%S')
		# Deep sigh
		imgdata['destdir'] = pdir

		# Create actual post
		of = open(os.path.join(pdir,'index.md'),'w')
		of.write(formatblotpost(postcontent))
		of.close()
	except FileNotFoundError as arg:
		print(arg)

for root, dirs, files in os.walk('.'):
	if not 'uploads' in root:
		for f in files:
			if not '.DS_Store' in f:
				handlepost(basedir,os.path.join(root,f))