Building a Blog: Generating Static Files
This post is part 2 of the "Building a Blog" series:
- Building a Blog: Overview
- Building a Blog: Generating Static Files
- Building a Blog: Authentation
- Building a Blog: Deploy
Before anyting, the core task is generating blog posts with your prefered input format, like markdown, reST, AsciiDoc, etc. Personally I prefer wrting using markdown format. Because python is my major programming language, I write reST too, mainly to write documenation using sphinx. Also, I need the generating tool to be customizable, so I can extend it some specific needs, like generating special post etc.
Pelican
At first I considered sphinx, as I'm already familiar with it, used it quite often, and supports math and many output format like latex. But the problem is also obvious: it's built for writing documenations and I find no good looking templage. And I realized that I do not really need latex output for a blog.
Then it comes to hexo, withing many suprisingly good templates.
The downside is it's written in node.js, which I'm not familiar nor
interested. I do not like the engine language, but the home page
and templates are elegant. So I gave it a try.
I spent a day to write two plugins, one for marking
specific content as confidential, another for filtering posts on some
criteria. It turns out that wrting plugins for it is not pleasant,
especially I'm not a fan of the language. Considering the possibility
that I need to extent it futher, I think it's probably not a good choice.
Finally I choosed pelican as the static page generator. pelican
is
a popular python package for generating static pages, supporting
markdown, reST, AsciiDoc out of the box, and is flexible to add
new readers and generators etc. to extend it. It's using a language
that I'm familiar with, it's easy to exent, but the downside is obviouse
too: the home page looks, well, not beautiful at least. pelican uses
python-markdown
to parse markdown files, it is still actively developped,
extensible, but the documenation is
a nightmare. It's literally difficult to read, and even
more difficult to find he information I want.
At last I have to read the soursource code. Also I did not
find an attractive template from the gallary.
But luckily, I found a beautiful template maupassant from hexo templates gallary that have been kindly ported to pelican by Rongqing Ye. It's originally developped by cho for Typecho.
pelican
Extionsions
I have some kind of specific requirement of generating posts:
- mark a post as confidential content
- filter posts by some criteria so I can generate a sub-blog
- write reveal.js slides.
Like hexo
, pelican's plugins is implemented with signals
.
Simply put, the generating process is splited to many steps,
at each step pelican will emit specific signals, so you can
register your function to do some processing. For example,
there's a signals when pelican initialize, so you can get the
configurations; there's a signal when readers are initialized,
when you can register your reader for special input files.
For details please find the documentations on
how to create plugins
Mark Confidential Post
I wrote a special function registered to article_generator_context
, to collect confidential centents
marked by a frontmatter metadata confidential
. based on the value, this function may cleanup the summary to hide any information except the title from the index page, or change
the status to draft
, so the post will not be listed on any
index page, or completely ignore the post, by setting the status
to an invalid value that is not understood by pelican. But I
will receive an error message about this. Before exit, I write
the urls of all confidential posts, for later layer use.
Filter Posts
The filter is similarly implemented: register a function that changes the status to some invalid value if it should not be included. So by specifying some topics in the frontmatter, I can generate a sub-blog that only contains post on the topic. This is helpful if I want a sub blog for relatively formal situations.
Write reveal.js
Slides
reveal.js
is a framework for easily creating beautiful presentations using HTML. It'll be cool and handy to
host slides too.
There's a fairly simple way to do so: just define a new
template page, and specify it in the frontmatter. But things
becomes a litte complicated when it comes to reveal.js
:
it uses <section>
tag to indicate slides, but there's
not such a thing in markdown. If this is not really a problem,
as you can extend the parser, you have to be careful when
you write html tags inside markdown, in case some markdown
rules applied to html content, especially when you loaded many
extensions.
To make things clear, I finally decided not to use markdown
parsers in pelican, instead, use reveal.js
markdown support,
or write raw htmls directly. To do so, I added a new reader
for special extensions .mds
and .htmls
. The frontmatter
is processed just like a normal markdown file, but the content
is not parsed. They are inserted directly to the corresponding
predefined templates.
After a while, I wanted to add something else. Note that in the reveal.js official demo you canchange the style by clicking links. I'd like to support this too. After some expirements, I used a special mark to indicated a special slide being inserted. All I need is do some string find and replace after reading a file.
But when it comes to pdf export, things became complicated. While I can insert a setting slide now, practically it does not belong to the content and I did not want to include it when exporting to pdf files. Generating two versions? Not ideal. I need some html way solution.
First I marked these settings slide sections to a
special no-print
class, then use css to
hide it when print:
@media print
{
.no-print, .no-print *
{
display: none !important;
}
}
Then I found that the content were hidden but left blank pages. As already I have marked these slides, I can directly remove these slides with javascript, connected to reveal.js ready event. Now these settings slides will not be exported!