Bidirectional IPython-Nikola workflow to write your blog post
The idea of this blog post is to show you how you can achieve an efficient bidirectional workflow to write your blog posts using great tools/features derived from IPython and Nikola.
Probably, this would be interesting not only for the people using IPython and Nikola to write their blog post, but also to other people because this would be a simple but nice example of how you can integrate this two applications to better suit your needs.
OK, first of all, let's go to the folder containing my blog:
damian@damian-S400CA:~$ cd /media/datos/Desarrollos/damian_blog
damian@damian-S400CA:/media/datos/Desarrollos/damian_blog$
Then I activate my virtualenv specifically filled to build my blog:
damian@damian-S400CA:/media/datos/Desarrollos/damian_blog$ workon blog
(blog)damian@damian-S400CA:/media/datos/Desarrollos/damian_blog$
Now, we are ready to the next step, calling the nikola console
:
(blog)damian@damian-S400CA:/media/datos/Desarrollos/damian_blog$ nikola console
Scanning posts......done!
Python 2.7.4 (default, Apr 19 2013, 18:28:01)
Type "copyright", "credits" or "license" for more information.
IPython 1.1.0 -- An enhanced Interactive Python.
? -> Introduction and overview of IPython's features.
%quickref -> Quick reference.
help -> Python's own help system.
object? -> Details about 'object', use 'object??' for extra details.
Nikola v6.1.1 -- IPython Console (conf = configuration, SITE = site engine)
Yes... Nikola offers a feature called nikola console
which immediately opens an IPython console (if you have installed IPython, of course) where you can do a lot of things, as I will show you later, but also have direct access to Nikola internals through the conf
(configuration) and SITE
(site engine) objects. We can explore this objects using the tab completion from the IPython machinery:
In [1]: conf.<TAB>
conf.BLOG_AUTHOR conf.LICENSE
conf.BLOG_DESCRIPTION conf.MATHJAX_CONFIG
conf.BLOG_EMAIL conf.NAVIGATION_LINKS
conf.BLOG_TITLE conf.PAGES
conf.BODY_END conf.POSTS
conf.COMMENT_SYSTEM_ID conf.py
conf.COMPILERS conf.pyc
conf.CONTENT_FOOTER conf.SITE_URL
conf.CREATE_MONTHLY_ARCHIVE conf.SOCIAL_BUTTONS_CODE
conf.DEFAULT_LANG conf.THEME
conf.DEPLOY_COMMANDS conf.time
conf.GLOBAL_CONTEXT conf.TRANSLATIONS
conf.INDEX_TEASERS conf.unicode_literals
conf.IPYNB_CONFIG
In [1]: SITE.<TAB>
SITE.abs_link SITE.MESSAGES
SITE.clean_task_paths SITE.pages
SITE.commands SITE.path
SITE.compilers SITE.plugin_manager
SITE.config SITE.post_per_file
SITE.configured SITE.posts_per_category
SITE.current_lang SITE.posts_per_month
SITE.default_lang SITE.posts_per_tag
SITE.EXTRA_PLUGINS SITE.posts_per_year
SITE.file_exists SITE.rel_link
SITE.generic_page_renderer SITE.render_template
SITE.generic_post_list_renderer SITE.scan_posts
SITE.gen_tasks SITE.strict
SITE.get_compiler SITE.template_system
SITE.GLOBAL_CONTEXT SITE.THEMES
SITE.global_data SITE.timeline
SITE.inverse_compilers SITE.translations
SITE.link
But, we will probably go back to these objects in another blog post... now, we go again to the Nikola IPython console because we want to create a new post. The easiest way to do it is just calling the proper Nikola command using the !
to pass it from the Nikola IPython console to the shell.
In [1]: !nikola new_post -f ipynb
But we can do it better ;-)
We can pass arguments to the nikola new_post
command such as the title
, tags
, format
(we have already pass the format with -f ipynb
), etc. So, let me create some variables for these arguments inside my Nikola IPython console session:
In [1]: title = "Bidirectional IPython-Nikola workflow to write your blog post"
In [2]: tags_list = ['python', 'IPython', 'nikola', 'blog', 'extension', 'gh-pages', 'git', 'workflow']
In [3]: tags = ', '.join(tags_list)
In [4]: tags
Out[4]: u'python, IPython, nikola, blog, extension, gh-pages, git, workflow'
Here I have the string title
containing the title for the current blog post and a list called tags_list
containing the corresponding tags. Later I call the .join
method because I will need to pass a string with the tags sepatarated by commas to the nikola new_post
command.
But, wait a minute... I have Python variables containing the title and the tags for my blog post. How can pass this variables to the shell to use them as arguments of the nikola new_post
command???
OK, to solve this problem we will use an exciting feature from IPython, just see the following line:
In [5]: !nikola new_post -f ipynb -t "{title}" --tags="{tags}"
which will create the desired ipynb
and the corresponding .meta
file containing the title and tags.
Creating New Post
-----------------
Title: Bidirectional IPython-Nikola workflow to write your blog post
Scanning posts......done!
Your post's metadata is at: posts/bidirectional-ipython-nikola-workflow-to-write-your-blog-post.meta
[2013-10-15T19:21:28Z] NOTICE: new_post: Your post's text is at: posts/bidirectional-ipython-nikola-workflow-to-write-your-blog-post.ipynb
Que me contusi! (or... do you see the bidirectional nature of this interaction? Nice, don't you think?)
Yes, inside IPython, we can use the braces to pass Python variables to the shell... ;-)
Do you see the possibilities we have with this little feature?
Now, I cd into the post folder of my site and open the IPython notebook with my custom extensions.
In [6]: cd posts/
/media/datos/Desarrollos/damian_blog/posts
In [7]: !ipython notebook --profile=myext
In the IPython Dashboard, I will open the new ipynb
called bidirectional-ipython-nikola-workflow-to-write-your-blog-post.ipynb
and write the content (I am writing right now).
Then, when I am done with the blog post, I need to deploy my new content to somewhere to make available to the public...
And this is very easy...
First, Nikola have a nikola deploy
command which you can customize with your conf.py file. You can see it here my configuration:
!sed -n 197,208p conf.py
The instructions are very easy to understand, if you need more details just read this post I wrote some weeks ago.
I am essentially pushing the content to master, creating a split and deploy it later to gh-pages.
OK, but because I am lazy ;-), some weeks ago I wrote an IPython javascript extension which let me execute this nikola deploy
command from a button in the IPython notebook toolbar. Essentially something like this (don't worry, I will release the extension soon):
function nikolaDeploy(path, clean) {
IPython.notebook.kernel.execute('cd ' + path);
if (clean=="True") {
IPython.notebook.kernel.execute('!nikola clean');
}else{
//do nothing
}
IPython.notebook.kernel.execute('!nikola build');
IPython.notebook.kernel.execute('!nikola deploy');
messager();
}
As you can see, I call nikola clean
to clean my site, the I built it with nikola build
, and deploy it with my customized nikola deploy
... and all these actions with just a click!
And now you have the complete workflow! A very simple one, because you can make a lot of modifications to improve it. However, this workflow show you how you can integrate two exciting projects, communicate one with the other and viceversa, and get beautiful results.
Hope you enjoy it!
Damián.
Did you like the content? Great!
Or visit my support page for more information.
Btw, don't forget this blog post is an ipynb file itself! So, you can download it from the "Source" link at the top of the post if you want to play with it ;-)
Comments powered by Disqus