Creating Kirby posts from articles in Ashes

Nobody will read this article, but it means a lot to me because it definitely improves my life and smooths the creation of posts. Deeper you go into automatization, more user-specific it becomes, that's what I believe at least. This article shows how to create blog posts for Kirby CMS using data extracted from articles using Ashes.

Kirby is the CMS I use for this blog. Each article is a plain text file within an ordered folder. Just check the image:

This blog has 2 kinds of posts, long articles, which are named blogarticle.txt to pull a specific template, and commentary articles with links to external posts, which are named quotearticle.txt, also to grab a specific template. This article will cover the creation of a quotearticle, which contains an additional custom field for the url to be linked in the reader.

As I covered before, you can pull information out of Ashes, my Fever client of choice, send it to Pythonista or Drafts and do some magic. Our tool of choice, this time, is definitely Pythonista.

First we gonna add an action to Ashes called Create Quote Article:


This action was designed to call a Pythonista script named QuoteArticle, so keep that in mind.

As you read an article of interest, you select a quote you'd like to publish in your blog post and call this action. It will run the QuoteArticle file in Pythonista and now things get tricky.

# -*- coding: utf-8 -*-

from ftplib import FTP
import unicodedata
import datetime
from os import remove
from console import clear
import webbrowser

#Here we'll organize the data brought from Ashes into properly named variables.
#Afterwards, we'll create an article structured for Kirby.
quote = sys.argv[1]
title = sys.argv[2]
link = sys.argv[3]

article = 'Title: ' + title + '\n----\nDate: ' +'%Y-%m-%d') + '\n----\nLink: ' + link + '\n----\nText: >' + quote

#If you want to add a comment to the post, this will prompt you to add one.
print article
comment = raw_input('Comment: ')

#This clause checks if you included a comment and adds it to the article.
if len(comment) > 0:
    article = article + '\n\n' + comment
    print article
    print article

#connecting to the FTP now (:
ftp = FTP('link to your ftp')
ftp.login('ftp login','ftp password')

#This function is tricky.
#It will convert accented characters and such from an unicode.
#By the end it will remove some unicode characters that we don't want in our url later.
def remove_accents(input_str):
    nkfd_form = unicodedata.normalize('NFKD', input_str)
    almost = u"".join([c for c in nkfd_form if not unicodedata.combining(c)])
    return almost.translate(dict.fromkeys(map(ord, u"$_.+!*'(),’")))

#This will execute our aforementioned function.
#It also converts spaces into hyphens
urlpath = remove_accents('-'.join(title.split()).decode('utf-8'))

#I created a variable for the path/to/folder because we'll use it often.
path = 'path/to/folder/'

#Every article in Kirby is a plain text file within a folder.
#The folder structure works something like this:
#This means that we must find out what is the next number to create a folder.
#The len() goes for, notice how I reduce other folders and the main directory.
folderName = str(len(ftp.nlst(path))-4) + '-' + urlpath

#Here we create the folder within our FTP.
ftp.mkd(path + folderName)

#Now it is time to create our txt file locally and replace its contents for our article.
#This will send our article to our ftp
ftp.storlines('STOR ' + path + folderName + '/quotearticle.txt',open('quotearticle.txt','r'))
#This will remove your local file, so you can keep your iOS tidy.
print 'Your article is up!''' + urlpath)

This wall of code probably looks like a mess, but that's because I commented through the whole thing, so if you decide to tweak the code, you never get lost. The best way to describe what this script does is to show it in a list:

  1. Import a bunch of modules we gonna use later;
  2. Create variables from the data pulled from Ashes and edit them into the content of our article. If you have no idea on how the structure of a Kirby post looks like, check it down here:
  3. Then Pythonista will bring the console to ask if you want to include a comment to the post. Afterwards, it checks if you did and change your article accordingly.
  4. We'll connect to your FTP. Remember to set your ftp url, login and password in the fields.
  5. You saw how Kirby requires the creation of folders to place our articles in, so before creating a plain text file, we must fix our folder name based on the title of the article we sent from Ashes. The function will convert the title to unicode and strip it from characters we don't want in our urls. It'll also replace spaces for hyphens.
  6. We find out the number to prepend to our folder using len() into the contents of the directory less the invisible files, in my case, 4. It is always at least 2 (the txt file and the directory, as it counts).
  7. Then we finally create the folder and are ready for our plain text file. We can't create straight on the ftp, so we must create a local file first. We do it quickly and place the content for the article into it. The name of the file is quotearticle.txt, so tweak it for your needs.
  8. We upload our local quotearticle.txt into our freshly created folder, then we remove our local copy, just to keep everything clean, print a cool message and open your post using Pythonista's browser so you can check out the results. Remember to change the url to your blog.

There must be a way to make this code shorter and more effective, I hold on the excuse to be checking Python for less than a week. If you're having trouble adapting this script to your specific case, send a message at and I'll find a way to help you out.