Pelican的插件系统是使用blinkersignal实现的。Pelican所有可以用的signals可以在signals.py找到。本文的目的是记录这些signals是在Pelican运行中什么时候发出的。

(1) Pelican有一个叫做Pelican的类,含有程序的主体框架。当Pelican的一个实例pelican初始化完成之后(基本设置,加载插件),发出第一个signal。

signals.initialized.send(pelican)

(2) pelican开始加载生成器Generatorgenerators.py)。加载过程中将实例化每个Generator,每个实例generator初始化过程中会获得一个Readerreaders.py)实例reader,因此会发出

signals.readers_init.send(reader)

初始化结束之后都会发出

signals.generator_init.send(generator)

以上signal是由基类提供,每个Generator子类在发出以上signal之后还会发出自己的signal,其中最重要的两个子类是ArticlesGenertorPagesGenerator

ArticlesGenerator发出

signals.article_generator_init.send(generator)

PagesGenerator发出

signals.page_generator_init.send(generator)

除了内置的生成器外,pelican在这个时候也会发出

signals.get_generators.send(pelican)

来获得有可能来自于插件的生成器。


(3) 生成器加载完成之后开始生成所有文章与页面。ArticlesGenerator在生成完所有文章之后首先发出

signals.article_generator_pretaxonomy.send(generator)

然后处理tag和category等,最后发出

signals.article_generator_finalized.send(generator)

PagesGenerator只在完成生成页面时发出

signals.page_generator_finalized.send(generator)

(4) pelican发出

signals.all_generators_finalized.send(generators)

其中generators是包含所有生成器实例的列表。


(5) 接下来要将生成器得到的内容通过Writerwriters.py)根据主题中的模板渲染成html文件。pelican通过

signals.get_writer.send(pelican)

获得一个Writer实例writer。接着每个生成器中的内容依次通过writer渲染成html文件。我只说明两种生成器的过程。

对于ArticlesGenerator,如果设置生成rss等订阅源时,首先会依次发出如下两个signals

signals.feed_generated.send(context, feed=feed)
signals.feed_written.send(complete_path, context=context, feed=feed)

在生成每篇文章的html的过程中依次发出如下signals

# before writing
signals.article_generator_write_article.send(generator, content=article)
# after written
signals.content_written.send(path, context=localcontext)

完成所有跟文章相关的html文件之后,结束时发出

signals.article_writer_finalized.send(generator, writer=writer)

对于PagesGenerator,过程简单了些:每次完成一个页面的渲染发出

signals.content_written.send(path, context=localcontext)

完成所有页面的渲染后,结束时发出

signals.page_writer_finalized.send(generator, writer=writer)

(6) 最后pelican发出

signals.finalized.send(pelican)

表示程序将要结束。


上述过程包含了大部分signals,但不是全部(例如还有其他生成器产生的signals)。在实际应用中,很多时候我们只需要用到过程中(2)和(3)产生的signals。例如如果我们希望控制主页出现的文章,我们只需要用到(2)中的

signals.article_generator_init.send(generator)

这是因为主页是用generator.generate_direct_templates来生成的,所以要控制主页上出现的文章,我们只需在生成器初始化的时候,将generator.generate_direct_templates换成我们自己的程序,这样就可以按照自己的意愿生成想要的主页。