Pelican Signals
Pelican的插件系统是使用blinker的signal
实现的。Pelican所有可以用的signals可以在signals.py找到。本文的目的是记录这些signals是在Pelican运行中什么时候发出的。
(1) Pelican有一个叫做Pelican
的类,含有程序的主体框架。当Pelican
的一个实例pelican
初始化完成之后(基本设置,加载插件),发出第一个signal。
signals.initialized.send(pelican)
(2) pelican
开始加载生成器Generator
(generators.py)。加载过程中将实例化每个Generator
,每个实例generator
初始化过程中会获得一个Reader
(readers.py)实例reader
,因此会发出
signals.readers_init.send(reader)
初始化结束之后都会发出
signals.generator_init.send(generator)
以上signal是由基类提供,每个Generator
子类在发出以上signal之后还会发出自己的signal,其中最重要的两个子类是ArticlesGenertor
和PagesGenerator
。
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) 接下来要将生成器得到的内容通过Writer
(writers.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
换成我们自己的程序,这样就可以按照自己的意愿生成想要的主页。